@mduenas/codegraph 0.4.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/LICENSE +21 -0
- package/README.md +641 -0
- package/dist/bin/codegraph.d.ts +20 -0
- package/dist/bin/codegraph.d.ts.map +1 -0
- package/dist/bin/codegraph.js +704 -0
- package/dist/bin/codegraph.js.map +1 -0
- package/dist/config.d.ts +51 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +291 -0
- package/dist/config.js.map +1 -0
- package/dist/context/formatter.d.ts +30 -0
- package/dist/context/formatter.d.ts.map +1 -0
- package/dist/context/formatter.js +244 -0
- package/dist/context/formatter.js.map +1 -0
- package/dist/context/index.d.ts +86 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +402 -0
- package/dist/context/index.js.map +1 -0
- package/dist/db/index.d.ts +64 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +170 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrations.d.ts +44 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +105 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/queries.d.ts +148 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +669 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/directory.d.ts +45 -0
- package/dist/directory.d.ts.map +1 -0
- package/dist/directory.js +191 -0
- package/dist/directory.js.map +1 -0
- package/dist/errors.d.ts +136 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +219 -0
- package/dist/errors.js.map +1 -0
- package/dist/extraction/grammars.d.ts +36 -0
- package/dist/extraction/grammars.d.ts.map +1 -0
- package/dist/extraction/grammars.js +181 -0
- package/dist/extraction/grammars.js.map +1 -0
- package/dist/extraction/index.d.ts +91 -0
- package/dist/extraction/index.d.ts.map +1 -0
- package/dist/extraction/index.js +493 -0
- package/dist/extraction/index.js.map +1 -0
- package/dist/extraction/tree-sitter.d.ts +176 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -0
- package/dist/extraction/tree-sitter.js +1798 -0
- package/dist/extraction/tree-sitter.js.map +1 -0
- package/dist/graph/index.d.ts +8 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +13 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/queries.d.ts +106 -0
- package/dist/graph/queries.d.ts.map +1 -0
- package/dist/graph/queries.js +355 -0
- package/dist/graph/queries.js.map +1 -0
- package/dist/graph/traversal.d.ts +127 -0
- package/dist/graph/traversal.d.ts.map +1 -0
- package/dist/graph/traversal.js +465 -0
- package/dist/graph/traversal.js.map +1 -0
- package/dist/index.d.ts +496 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +818 -0
- package/dist/index.js.map +1 -0
- package/dist/installer/banner.d.ts +40 -0
- package/dist/installer/banner.d.ts.map +1 -0
- package/dist/installer/banner.js +162 -0
- package/dist/installer/banner.js.map +1 -0
- package/dist/installer/claude-md-template.d.ts +10 -0
- package/dist/installer/claude-md-template.d.ts.map +1 -0
- package/dist/installer/claude-md-template.js +46 -0
- package/dist/installer/claude-md-template.js.map +1 -0
- package/dist/installer/config-writer.d.ts +36 -0
- package/dist/installer/config-writer.d.ts.map +1 -0
- package/dist/installer/config-writer.js +282 -0
- package/dist/installer/config-writer.js.map +1 -0
- package/dist/installer/index.d.ts +13 -0
- package/dist/installer/index.d.ts.map +1 -0
- package/dist/installer/index.js +155 -0
- package/dist/installer/index.js.map +1 -0
- package/dist/installer/prompts.d.ts +18 -0
- package/dist/installer/prompts.d.ts.map +1 -0
- package/dist/installer/prompts.js +113 -0
- package/dist/installer/prompts.js.map +1 -0
- package/dist/mcp/index.d.ts +64 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +207 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tools.d.ts +93 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +442 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/transport.d.ts +89 -0
- package/dist/mcp/transport.d.ts.map +1 -0
- package/dist/mcp/transport.js +170 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/resolution/frameworks/csharp.d.ts +8 -0
- package/dist/resolution/frameworks/csharp.d.ts.map +1 -0
- package/dist/resolution/frameworks/csharp.js +274 -0
- package/dist/resolution/frameworks/csharp.js.map +1 -0
- package/dist/resolution/frameworks/express.d.ts +8 -0
- package/dist/resolution/frameworks/express.d.ts.map +1 -0
- package/dist/resolution/frameworks/express.js +208 -0
- package/dist/resolution/frameworks/express.js.map +1 -0
- package/dist/resolution/frameworks/go.d.ts +8 -0
- package/dist/resolution/frameworks/go.d.ts.map +1 -0
- package/dist/resolution/frameworks/go.js +225 -0
- package/dist/resolution/frameworks/go.js.map +1 -0
- package/dist/resolution/frameworks/index.d.ts +33 -0
- package/dist/resolution/frameworks/index.d.ts.map +1 -0
- package/dist/resolution/frameworks/index.js +113 -0
- package/dist/resolution/frameworks/index.js.map +1 -0
- package/dist/resolution/frameworks/java.d.ts +8 -0
- package/dist/resolution/frameworks/java.d.ts.map +1 -0
- package/dist/resolution/frameworks/java.js +239 -0
- package/dist/resolution/frameworks/java.js.map +1 -0
- package/dist/resolution/frameworks/laravel.d.ts +13 -0
- package/dist/resolution/frameworks/laravel.d.ts.map +1 -0
- package/dist/resolution/frameworks/laravel.js +198 -0
- package/dist/resolution/frameworks/laravel.js.map +1 -0
- package/dist/resolution/frameworks/python.d.ts +10 -0
- package/dist/resolution/frameworks/python.d.ts.map +1 -0
- package/dist/resolution/frameworks/python.js +331 -0
- package/dist/resolution/frameworks/python.js.map +1 -0
- package/dist/resolution/frameworks/react.d.ts +8 -0
- package/dist/resolution/frameworks/react.d.ts.map +1 -0
- package/dist/resolution/frameworks/react.js +294 -0
- package/dist/resolution/frameworks/react.js.map +1 -0
- package/dist/resolution/frameworks/ruby.d.ts +8 -0
- package/dist/resolution/frameworks/ruby.d.ts.map +1 -0
- package/dist/resolution/frameworks/ruby.js +262 -0
- package/dist/resolution/frameworks/ruby.js.map +1 -0
- package/dist/resolution/frameworks/rust.d.ts +8 -0
- package/dist/resolution/frameworks/rust.d.ts.map +1 -0
- package/dist/resolution/frameworks/rust.js +222 -0
- package/dist/resolution/frameworks/rust.js.map +1 -0
- package/dist/resolution/frameworks/swift.d.ts +10 -0
- package/dist/resolution/frameworks/swift.d.ts.map +1 -0
- package/dist/resolution/frameworks/swift.js +486 -0
- package/dist/resolution/frameworks/swift.js.map +1 -0
- package/dist/resolution/import-resolver.d.ts +20 -0
- package/dist/resolution/import-resolver.d.ts.map +1 -0
- package/dist/resolution/import-resolver.js +445 -0
- package/dist/resolution/import-resolver.js.map +1 -0
- package/dist/resolution/index.d.ts +72 -0
- package/dist/resolution/index.d.ts.map +1 -0
- package/dist/resolution/index.js +301 -0
- package/dist/resolution/index.js.map +1 -0
- package/dist/resolution/name-matcher.d.ts +27 -0
- package/dist/resolution/name-matcher.d.ts.map +1 -0
- package/dist/resolution/name-matcher.js +210 -0
- package/dist/resolution/name-matcher.js.map +1 -0
- package/dist/resolution/types.d.ts +108 -0
- package/dist/resolution/types.d.ts.map +1 -0
- package/dist/resolution/types.js +8 -0
- package/dist/resolution/types.js.map +1 -0
- package/dist/sync/git-hooks.d.ts +66 -0
- package/dist/sync/git-hooks.d.ts.map +1 -0
- package/dist/sync/git-hooks.js +281 -0
- package/dist/sync/git-hooks.js.map +1 -0
- package/dist/sync/index.d.ts +13 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +18 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/types.d.ts +410 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +165 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +116 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +295 -0
- package/dist/utils.js.map +1 -0
- package/dist/vectors/embedder.d.ts +140 -0
- package/dist/vectors/embedder.d.ts.map +1 -0
- package/dist/vectors/embedder.js +336 -0
- package/dist/vectors/embedder.js.map +1 -0
- package/dist/vectors/index.d.ts +9 -0
- package/dist/vectors/index.d.ts.map +1 -0
- package/dist/vectors/index.js +20 -0
- package/dist/vectors/index.js.map +1 -0
- package/dist/vectors/manager.d.ts +119 -0
- package/dist/vectors/manager.d.ts.map +1 -0
- package/dist/vectors/manager.js +274 -0
- package/dist/vectors/manager.js.map +1 -0
- package/dist/vectors/search.d.ts +134 -0
- package/dist/vectors/search.d.ts.map +1 -0
- package/dist/vectors/search.js +409 -0
- package/dist/vectors/search.js.map +1 -0
- package/package.json +67 -0
- package/scripts/postinstall.js +68 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Vector Search
|
|
4
|
+
*
|
|
5
|
+
* Provides vector similarity search using sqlite-vss extension.
|
|
6
|
+
* Falls back to brute-force cosine similarity if sqlite-vss is not available.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.VectorSearchManager = void 0;
|
|
43
|
+
exports.createVectorSearch = createVectorSearch;
|
|
44
|
+
const embedder_1 = require("./embedder");
|
|
45
|
+
/**
|
|
46
|
+
* Vector Search Manager
|
|
47
|
+
*
|
|
48
|
+
* Handles vector storage and similarity search for semantic code search.
|
|
49
|
+
*/
|
|
50
|
+
class VectorSearchManager {
|
|
51
|
+
db;
|
|
52
|
+
vssEnabled = false;
|
|
53
|
+
embeddingDimension;
|
|
54
|
+
constructor(db, dimension = embedder_1.EMBEDDING_DIMENSION) {
|
|
55
|
+
this.db = db;
|
|
56
|
+
this.embeddingDimension = dimension;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Initialize vector search
|
|
60
|
+
*
|
|
61
|
+
* Attempts to load sqlite-vss extension. Falls back to brute-force
|
|
62
|
+
* search if the extension is not available.
|
|
63
|
+
*/
|
|
64
|
+
async initialize() {
|
|
65
|
+
try {
|
|
66
|
+
// Try to load sqlite-vss extension
|
|
67
|
+
await this.loadVssExtension();
|
|
68
|
+
this.vssEnabled = true;
|
|
69
|
+
console.log('sqlite-vss extension loaded successfully');
|
|
70
|
+
// Create the VSS virtual table
|
|
71
|
+
this.createVssTable();
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
// Fall back to brute-force search
|
|
75
|
+
console.warn('sqlite-vss extension not available, falling back to brute-force search:', error instanceof Error ? error.message : String(error));
|
|
76
|
+
this.vssEnabled = false;
|
|
77
|
+
}
|
|
78
|
+
// Ensure the vectors table exists (for both VSS and fallback modes)
|
|
79
|
+
this.ensureVectorsTable();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Load the sqlite-vss extension
|
|
83
|
+
*/
|
|
84
|
+
async loadVssExtension() {
|
|
85
|
+
try {
|
|
86
|
+
// The sqlite-vss npm package provides functions to load extensions
|
|
87
|
+
const vss = await Promise.resolve().then(() => __importStar(require('sqlite-vss')));
|
|
88
|
+
// Use the load function which loads both vector0 and vss0
|
|
89
|
+
if (typeof vss.load === 'function') {
|
|
90
|
+
vss.load(this.db);
|
|
91
|
+
}
|
|
92
|
+
else if (typeof vss.default?.load === 'function') {
|
|
93
|
+
vss.default.load(this.db);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
throw new Error('sqlite-vss load function not found');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
throw new Error(`Failed to load sqlite-vss: ${error instanceof Error ? error.message : String(error)}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Create the VSS virtual table for vector search
|
|
105
|
+
*/
|
|
106
|
+
createVssTable() {
|
|
107
|
+
// Check if the table already exists
|
|
108
|
+
const tableExists = this.db
|
|
109
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='vss_vectors'")
|
|
110
|
+
.get();
|
|
111
|
+
if (!tableExists) {
|
|
112
|
+
// Create VSS virtual table
|
|
113
|
+
// vss0 is the vector search extension
|
|
114
|
+
this.db.exec(`
|
|
115
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS vss_vectors USING vss0(
|
|
116
|
+
embedding(${this.embeddingDimension})
|
|
117
|
+
);
|
|
118
|
+
`);
|
|
119
|
+
// Create mapping table to link VSS rowids to node IDs
|
|
120
|
+
this.db.exec(`
|
|
121
|
+
CREATE TABLE IF NOT EXISTS vss_map (
|
|
122
|
+
rowid INTEGER PRIMARY KEY,
|
|
123
|
+
node_id TEXT NOT NULL UNIQUE
|
|
124
|
+
);
|
|
125
|
+
`);
|
|
126
|
+
// Create index on node_id
|
|
127
|
+
this.db.exec(`
|
|
128
|
+
CREATE INDEX IF NOT EXISTS idx_vss_map_node ON vss_map(node_id);
|
|
129
|
+
`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Ensure the basic vectors table exists (for fallback mode)
|
|
134
|
+
*/
|
|
135
|
+
ensureVectorsTable() {
|
|
136
|
+
this.db.exec(`
|
|
137
|
+
CREATE TABLE IF NOT EXISTS vectors (
|
|
138
|
+
node_id TEXT PRIMARY KEY,
|
|
139
|
+
embedding BLOB NOT NULL,
|
|
140
|
+
model TEXT NOT NULL,
|
|
141
|
+
created_at INTEGER NOT NULL
|
|
142
|
+
);
|
|
143
|
+
`);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Check if VSS extension is enabled
|
|
147
|
+
*/
|
|
148
|
+
isVssEnabled() {
|
|
149
|
+
return this.vssEnabled;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Store a vector embedding for a node
|
|
153
|
+
*
|
|
154
|
+
* @param nodeId - ID of the node
|
|
155
|
+
* @param embedding - Vector embedding
|
|
156
|
+
* @param model - Model used to generate embedding
|
|
157
|
+
*/
|
|
158
|
+
storeVector(nodeId, embedding, model) {
|
|
159
|
+
const now = Date.now();
|
|
160
|
+
// Store in the vectors table (always, for persistence)
|
|
161
|
+
const blob = Buffer.from(embedding.buffer);
|
|
162
|
+
this.db
|
|
163
|
+
.prepare(`
|
|
164
|
+
INSERT OR REPLACE INTO vectors (node_id, embedding, model, created_at)
|
|
165
|
+
VALUES (?, ?, ?, ?)
|
|
166
|
+
`)
|
|
167
|
+
.run(nodeId, blob, model, now);
|
|
168
|
+
// Also store in VSS table if enabled
|
|
169
|
+
if (this.vssEnabled) {
|
|
170
|
+
this.storeInVss(nodeId, embedding);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Store vector in VSS virtual table
|
|
175
|
+
*/
|
|
176
|
+
storeInVss(nodeId, embedding) {
|
|
177
|
+
try {
|
|
178
|
+
// Check if already exists
|
|
179
|
+
const existing = this.db
|
|
180
|
+
.prepare('SELECT rowid FROM vss_map WHERE node_id = ?')
|
|
181
|
+
.get(nodeId);
|
|
182
|
+
if (existing) {
|
|
183
|
+
// Update existing vector
|
|
184
|
+
const vectorJson = JSON.stringify(Array.from(embedding));
|
|
185
|
+
this.db
|
|
186
|
+
.prepare('UPDATE vss_vectors SET embedding = ? WHERE rowid = ?')
|
|
187
|
+
.run(vectorJson, existing.rowid);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
// Insert new vector - get max rowid and increment
|
|
191
|
+
const maxRow = this.db
|
|
192
|
+
.prepare('SELECT MAX(rowid) as max FROM vss_map')
|
|
193
|
+
.get();
|
|
194
|
+
const newRowid = (maxRow?.max ?? 0) + 1;
|
|
195
|
+
const vectorJson = JSON.stringify(Array.from(embedding));
|
|
196
|
+
this.db
|
|
197
|
+
.prepare('INSERT INTO vss_vectors (rowid, embedding) VALUES (?, ?)')
|
|
198
|
+
.run(newRowid, vectorJson);
|
|
199
|
+
// Map the rowid to node_id
|
|
200
|
+
this.db
|
|
201
|
+
.prepare('INSERT INTO vss_map (rowid, node_id) VALUES (?, ?)')
|
|
202
|
+
.run(newRowid, nodeId);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
// VSS operations can fail for various reasons (dimension mismatch, etc.)
|
|
207
|
+
// Fall back to brute-force search silently
|
|
208
|
+
console.warn('VSS storage failed, using brute-force search:', error instanceof Error ? error.message : String(error));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Store multiple vectors in a batch
|
|
213
|
+
*
|
|
214
|
+
* @param entries - Array of node IDs and embeddings
|
|
215
|
+
* @param model - Model used to generate embeddings
|
|
216
|
+
*/
|
|
217
|
+
storeVectorBatch(entries, model) {
|
|
218
|
+
const now = Date.now();
|
|
219
|
+
// Use a transaction for better performance
|
|
220
|
+
this.db.transaction(() => {
|
|
221
|
+
for (const entry of entries) {
|
|
222
|
+
const blob = Buffer.from(entry.embedding.buffer);
|
|
223
|
+
this.db
|
|
224
|
+
.prepare(`
|
|
225
|
+
INSERT OR REPLACE INTO vectors (node_id, embedding, model, created_at)
|
|
226
|
+
VALUES (?, ?, ?, ?)
|
|
227
|
+
`)
|
|
228
|
+
.run(entry.nodeId, blob, model, now);
|
|
229
|
+
if (this.vssEnabled) {
|
|
230
|
+
this.storeInVss(entry.nodeId, entry.embedding);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
})();
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Get vector for a node
|
|
237
|
+
*
|
|
238
|
+
* @param nodeId - ID of the node
|
|
239
|
+
* @returns Embedding or null if not found
|
|
240
|
+
*/
|
|
241
|
+
getVector(nodeId) {
|
|
242
|
+
const row = this.db
|
|
243
|
+
.prepare('SELECT embedding FROM vectors WHERE node_id = ?')
|
|
244
|
+
.get(nodeId);
|
|
245
|
+
if (!row) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
return new Float32Array(row.embedding.buffer.slice(row.embedding.byteOffset, row.embedding.byteOffset + row.embedding.byteLength));
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Delete vector for a node
|
|
252
|
+
*
|
|
253
|
+
* @param nodeId - ID of the node
|
|
254
|
+
*/
|
|
255
|
+
deleteVector(nodeId) {
|
|
256
|
+
this.db.prepare('DELETE FROM vectors WHERE node_id = ?').run(nodeId);
|
|
257
|
+
if (this.vssEnabled) {
|
|
258
|
+
// Get the rowid before deleting
|
|
259
|
+
const mapping = this.db
|
|
260
|
+
.prepare('SELECT rowid FROM vss_map WHERE node_id = ?')
|
|
261
|
+
.get(nodeId);
|
|
262
|
+
if (mapping) {
|
|
263
|
+
this.db.prepare('DELETE FROM vss_vectors WHERE rowid = ?').run(mapping.rowid);
|
|
264
|
+
this.db.prepare('DELETE FROM vss_map WHERE node_id = ?').run(nodeId);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Search for similar vectors
|
|
270
|
+
*
|
|
271
|
+
* @param queryEmbedding - Query vector to search for
|
|
272
|
+
* @param options - Search options
|
|
273
|
+
* @returns Array of node IDs with similarity scores
|
|
274
|
+
*/
|
|
275
|
+
search(queryEmbedding, options = {}) {
|
|
276
|
+
const { limit = 10, minScore = 0 } = options;
|
|
277
|
+
if (this.vssEnabled) {
|
|
278
|
+
return this.searchWithVss(queryEmbedding, limit, minScore);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
return this.searchBruteForce(queryEmbedding, limit, minScore);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Search using sqlite-vss KNN search
|
|
286
|
+
*/
|
|
287
|
+
searchWithVss(queryEmbedding, limit, minScore) {
|
|
288
|
+
try {
|
|
289
|
+
const vectorJson = JSON.stringify(Array.from(queryEmbedding));
|
|
290
|
+
// Sanitize limit to prevent SQL injection (ensure it's a positive integer)
|
|
291
|
+
const safeLimit = Math.max(1, Math.floor(limit));
|
|
292
|
+
// Use VSS KNN search
|
|
293
|
+
// The distance is L2 (euclidean), we need to convert to similarity score
|
|
294
|
+
// Note: sqlite-vss requires LIMIT to be a literal, not a parameter
|
|
295
|
+
const rows = this.db
|
|
296
|
+
.prepare(`
|
|
297
|
+
SELECT
|
|
298
|
+
vss_map.node_id,
|
|
299
|
+
vss_vectors.distance
|
|
300
|
+
FROM vss_vectors
|
|
301
|
+
JOIN vss_map ON vss_map.rowid = vss_vectors.rowid
|
|
302
|
+
WHERE vss_search(vss_vectors.embedding, ?)
|
|
303
|
+
LIMIT ${safeLimit}
|
|
304
|
+
`)
|
|
305
|
+
.all(vectorJson);
|
|
306
|
+
// Convert L2 distance to similarity score (1 / (1 + distance))
|
|
307
|
+
return rows
|
|
308
|
+
.map((row) => ({
|
|
309
|
+
nodeId: row.node_id,
|
|
310
|
+
score: 1 / (1 + row.distance),
|
|
311
|
+
}))
|
|
312
|
+
.filter((r) => r.score >= minScore);
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
// VSS search failed, fall back to brute force
|
|
316
|
+
console.warn('VSS search failed, using brute-force:', error instanceof Error ? error.message : String(error));
|
|
317
|
+
return this.searchBruteForce(queryEmbedding, limit, minScore);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Brute-force search using cosine similarity
|
|
322
|
+
*/
|
|
323
|
+
searchBruteForce(queryEmbedding, limit, minScore) {
|
|
324
|
+
// Get all vectors
|
|
325
|
+
const rows = this.db
|
|
326
|
+
.prepare('SELECT node_id, embedding FROM vectors')
|
|
327
|
+
.all();
|
|
328
|
+
// Calculate cosine similarity for each
|
|
329
|
+
const results = [];
|
|
330
|
+
for (const row of rows) {
|
|
331
|
+
const embedding = new Float32Array(row.embedding.buffer.slice(row.embedding.byteOffset, row.embedding.byteOffset + row.embedding.byteLength));
|
|
332
|
+
const score = embedder_1.TextEmbedder.cosineSimilarity(queryEmbedding, embedding);
|
|
333
|
+
if (score >= minScore) {
|
|
334
|
+
results.push({ nodeId: row.node_id, score });
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// Sort by score descending and limit
|
|
338
|
+
results.sort((a, b) => b.score - a.score);
|
|
339
|
+
return results.slice(0, limit);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Get count of stored vectors
|
|
343
|
+
*/
|
|
344
|
+
getVectorCount() {
|
|
345
|
+
const result = this.db
|
|
346
|
+
.prepare('SELECT COUNT(*) as count FROM vectors')
|
|
347
|
+
.get();
|
|
348
|
+
return result.count;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Check if a node has a vector
|
|
352
|
+
*/
|
|
353
|
+
hasVector(nodeId) {
|
|
354
|
+
const result = this.db
|
|
355
|
+
.prepare('SELECT 1 FROM vectors WHERE node_id = ? LIMIT 1')
|
|
356
|
+
.get(nodeId);
|
|
357
|
+
return !!result;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Get all node IDs that have vectors
|
|
361
|
+
*/
|
|
362
|
+
getIndexedNodeIds() {
|
|
363
|
+
const rows = this.db
|
|
364
|
+
.prepare('SELECT node_id FROM vectors')
|
|
365
|
+
.all();
|
|
366
|
+
return rows.map((r) => r.node_id);
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Clear all vectors
|
|
370
|
+
*/
|
|
371
|
+
clear() {
|
|
372
|
+
this.db.prepare('DELETE FROM vectors').run();
|
|
373
|
+
if (this.vssEnabled) {
|
|
374
|
+
this.db.prepare('DELETE FROM vss_vectors').run();
|
|
375
|
+
this.db.prepare('DELETE FROM vss_map').run();
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Rebuild VSS index from vectors table
|
|
380
|
+
*
|
|
381
|
+
* Useful after bulk operations or if VSS index gets out of sync.
|
|
382
|
+
*/
|
|
383
|
+
rebuildVssIndex() {
|
|
384
|
+
if (!this.vssEnabled) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
// Clear VSS tables
|
|
388
|
+
this.db.prepare('DELETE FROM vss_vectors').run();
|
|
389
|
+
this.db.prepare('DELETE FROM vss_map').run();
|
|
390
|
+
// Reload from vectors table
|
|
391
|
+
const rows = this.db
|
|
392
|
+
.prepare('SELECT node_id, embedding FROM vectors')
|
|
393
|
+
.all();
|
|
394
|
+
this.db.transaction(() => {
|
|
395
|
+
for (const row of rows) {
|
|
396
|
+
const embedding = new Float32Array(row.embedding.buffer.slice(row.embedding.byteOffset, row.embedding.byteOffset + row.embedding.byteLength));
|
|
397
|
+
this.storeInVss(row.node_id, embedding);
|
|
398
|
+
}
|
|
399
|
+
})();
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
exports.VectorSearchManager = VectorSearchManager;
|
|
403
|
+
/**
|
|
404
|
+
* Create a vector search manager
|
|
405
|
+
*/
|
|
406
|
+
function createVectorSearch(db, dimension) {
|
|
407
|
+
return new VectorSearchManager(db, dimension);
|
|
408
|
+
}
|
|
409
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/vectors/search.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mduenas/codegraph",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Supercharge Claude Code with semantic code intelligence. 30% fewer tokens, 25% fewer tool calls, 100% local.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"codegraph": "./dist/bin/codegraph.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"scripts",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc && npm run copy-assets",
|
|
17
|
+
"postinstall": "node scripts/postinstall.js",
|
|
18
|
+
"copy-assets": "cp -r src/extraction/queries dist/extraction/ && cp src/db/schema.sql dist/db/",
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"cli": "npm run build && node dist/bin/codegraph.js",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"test:eval": "vitest run __tests__/evaluation/",
|
|
24
|
+
"eval": "npm run build && npx tsx __tests__/evaluation/runner.ts",
|
|
25
|
+
"clean": "rm -rf dist"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"code-intelligence",
|
|
29
|
+
"knowledge-graph",
|
|
30
|
+
"static-analysis",
|
|
31
|
+
"semantic-search"
|
|
32
|
+
],
|
|
33
|
+
"author": "",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@xenova/transformers": "^2.17.0",
|
|
37
|
+
"better-sqlite3": "^11.0.0",
|
|
38
|
+
"commander": "^14.0.2",
|
|
39
|
+
"figlet": "^1.8.0",
|
|
40
|
+
"sqlite-vss": "^0.1.2",
|
|
41
|
+
"tree-sitter": "^0.22.4",
|
|
42
|
+
"tree-sitter-c": "^0.23.4",
|
|
43
|
+
"tree-sitter-c-sharp": "^0.23.1",
|
|
44
|
+
"tree-sitter-cpp": "^0.23.4",
|
|
45
|
+
"tree-sitter-go": "^0.23.4",
|
|
46
|
+
"tree-sitter-java": "^0.23.5",
|
|
47
|
+
"tree-sitter-javascript": "^0.23.1",
|
|
48
|
+
"tree-sitter-kotlin": "^0.3.8",
|
|
49
|
+
"tree-sitter-liquid": "github:hankthetank27/tree-sitter-liquid",
|
|
50
|
+
"tree-sitter-php": "^0.23.11",
|
|
51
|
+
"tree-sitter-python": "^0.23.6",
|
|
52
|
+
"tree-sitter-ruby": "^0.23.1",
|
|
53
|
+
"tree-sitter-rust": "^0.23.2",
|
|
54
|
+
"tree-sitter-swift": "^0.7.1",
|
|
55
|
+
"tree-sitter-typescript": "^0.23.2"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
59
|
+
"@types/figlet": "^1.5.8",
|
|
60
|
+
"@types/node": "^20.19.30",
|
|
61
|
+
"typescript": "^5.0.0",
|
|
62
|
+
"vitest": "^2.0.0"
|
|
63
|
+
},
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=18.0.0"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Postinstall script - downloads the embedding model to ~/.codegraph/models
|
|
4
|
+
* This runs after `npm install` or `npx @colbymchenry/codegraph`
|
|
5
|
+
*/
|
|
6
|
+
const { existsSync, mkdirSync } = require('fs');
|
|
7
|
+
const { join } = require('path');
|
|
8
|
+
const { homedir } = require('os');
|
|
9
|
+
|
|
10
|
+
const CODEGRAPH_DIR = join(homedir(), '.codegraph');
|
|
11
|
+
const MODELS_DIR = join(CODEGRAPH_DIR, 'models');
|
|
12
|
+
const MODEL_ID = 'nomic-ai/nomic-embed-text-v1.5';
|
|
13
|
+
|
|
14
|
+
async function downloadModel() {
|
|
15
|
+
// Ensure directories exist
|
|
16
|
+
if (!existsSync(CODEGRAPH_DIR)) {
|
|
17
|
+
mkdirSync(CODEGRAPH_DIR, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
if (!existsSync(MODELS_DIR)) {
|
|
20
|
+
mkdirSync(MODELS_DIR, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Check if model is already cached
|
|
24
|
+
const modelCachePath = join(MODELS_DIR, MODEL_ID.replace('/', '/'));
|
|
25
|
+
if (existsSync(modelCachePath)) {
|
|
26
|
+
console.log('Embedding model already downloaded.');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log('Downloading embedding model (~130MB)...');
|
|
31
|
+
console.log('This is a one-time download for semantic code search.\n');
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
// Dynamic import for @xenova/transformers (ESM-only package)
|
|
35
|
+
const { pipeline, env } = await import('@xenova/transformers');
|
|
36
|
+
|
|
37
|
+
// Configure cache directory
|
|
38
|
+
env.cacheDir = MODELS_DIR;
|
|
39
|
+
|
|
40
|
+
// Download with progress
|
|
41
|
+
await pipeline('feature-extraction', MODEL_ID, {
|
|
42
|
+
progress_callback: (progress) => {
|
|
43
|
+
if (progress.status === 'progress' && progress.file && progress.progress !== undefined) {
|
|
44
|
+
const fileName = progress.file.split('/').pop();
|
|
45
|
+
const percent = Math.round(progress.progress);
|
|
46
|
+
process.stdout.write(`\rDownloading ${fileName}... ${percent}% `);
|
|
47
|
+
} else if (progress.status === 'done') {
|
|
48
|
+
process.stdout.write('\n');
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
console.log('\nEmbedding model ready!');
|
|
54
|
+
} catch (error) {
|
|
55
|
+
// Don't fail the install if model download fails
|
|
56
|
+
// User can still use codegraph without semantic search
|
|
57
|
+
console.log('\nNote: Could not download embedding model.');
|
|
58
|
+
console.log('Semantic search will download it on first use.');
|
|
59
|
+
if (process.env.DEBUG) {
|
|
60
|
+
console.error(error);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
downloadModel().catch(() => {
|
|
66
|
+
// Silent exit - don't break npm install
|
|
67
|
+
process.exit(0);
|
|
68
|
+
});
|