@unlimiting/qsc 0.1.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/dist/chunker/ast.d.ts +7 -0
- package/dist/chunker/ast.d.ts.map +1 -0
- package/dist/chunker/ast.js +302 -0
- package/dist/chunker/ast.js.map +1 -0
- package/dist/chunker/index.d.ts +15 -0
- package/dist/chunker/index.d.ts.map +1 -0
- package/dist/chunker/index.js +26 -0
- package/dist/chunker/index.js.map +1 -0
- package/dist/chunker/languages/dart.d.ts +3 -0
- package/dist/chunker/languages/dart.d.ts.map +1 -0
- package/dist/chunker/languages/dart.js +22 -0
- package/dist/chunker/languages/dart.js.map +1 -0
- package/dist/chunker/languages/go.d.ts +3 -0
- package/dist/chunker/languages/go.d.ts.map +1 -0
- package/dist/chunker/languages/go.js +20 -0
- package/dist/chunker/languages/go.js.map +1 -0
- package/dist/chunker/languages/index.d.ts +12 -0
- package/dist/chunker/languages/index.d.ts.map +1 -0
- package/dist/chunker/languages/index.js +35 -0
- package/dist/chunker/languages/index.js.map +1 -0
- package/dist/chunker/languages/kotlin.d.ts +3 -0
- package/dist/chunker/languages/kotlin.d.ts.map +1 -0
- package/dist/chunker/languages/kotlin.js +23 -0
- package/dist/chunker/languages/kotlin.js.map +1 -0
- package/dist/chunker/languages/python.d.ts +3 -0
- package/dist/chunker/languages/python.d.ts.map +1 -0
- package/dist/chunker/languages/python.js +21 -0
- package/dist/chunker/languages/python.js.map +1 -0
- package/dist/chunker/languages/swift.d.ts +3 -0
- package/dist/chunker/languages/swift.d.ts.map +1 -0
- package/dist/chunker/languages/swift.js +24 -0
- package/dist/chunker/languages/swift.js.map +1 -0
- package/dist/chunker/languages/typescript.d.ts +4 -0
- package/dist/chunker/languages/typescript.d.ts.map +1 -0
- package/dist/chunker/languages/typescript.js +34 -0
- package/dist/chunker/languages/typescript.js.map +1 -0
- package/dist/chunker/token.d.ts +6 -0
- package/dist/chunker/token.d.ts.map +1 -0
- package/dist/chunker/token.js +107 -0
- package/dist/chunker/token.js.map +1 -0
- package/dist/collection.d.ts +22 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +154 -0
- package/dist/collection.js.map +1 -0
- package/dist/config/index.d.ts +95 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +103 -0
- package/dist/config/index.js.map +1 -0
- package/dist/embedder/index.d.ts +14 -0
- package/dist/embedder/index.d.ts.map +1 -0
- package/dist/embedder/index.js +18 -0
- package/dist/embedder/index.js.map +1 -0
- package/dist/embedder/local.d.ts +11 -0
- package/dist/embedder/local.d.ts.map +1 -0
- package/dist/embedder/local.js +60 -0
- package/dist/embedder/local.js.map +1 -0
- package/dist/embedder/openai.d.ts +10 -0
- package/dist/embedder/openai.d.ts.map +1 -0
- package/dist/embedder/openai.js +69 -0
- package/dist/embedder/openai.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +824 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/index.d.ts +17 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +18 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/local.d.ts +10 -0
- package/dist/llm/local.d.ts.map +1 -0
- package/dist/llm/local.js +76 -0
- package/dist/llm/local.js.map +1 -0
- package/dist/llm/openai.d.ts +10 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +76 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/mcp.d.ts +3 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +393 -0
- package/dist/mcp.js.map +1 -0
- package/dist/scanner/git.d.ts +26 -0
- package/dist/scanner/git.d.ts.map +1 -0
- package/dist/scanner/git.js +134 -0
- package/dist/scanner/git.js.map +1 -0
- package/dist/scanner/index.d.ts +17 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +174 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/search/bm25.d.ts +17 -0
- package/dist/search/bm25.d.ts.map +1 -0
- package/dist/search/bm25.js +27 -0
- package/dist/search/bm25.js.map +1 -0
- package/dist/search/expander.d.ts +12 -0
- package/dist/search/expander.d.ts.map +1 -0
- package/dist/search/expander.js +60 -0
- package/dist/search/expander.js.map +1 -0
- package/dist/search/fusion.d.ts +32 -0
- package/dist/search/fusion.d.ts.map +1 -0
- package/dist/search/fusion.js +80 -0
- package/dist/search/fusion.js.map +1 -0
- package/dist/search/index.d.ts +61 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +137 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/reranker.d.ts +18 -0
- package/dist/search/reranker.d.ts.map +1 -0
- package/dist/search/reranker.js +56 -0
- package/dist/search/reranker.js.map +1 -0
- package/dist/search/vector.d.ts +23 -0
- package/dist/search/vector.d.ts.map +1 -0
- package/dist/search/vector.js +47 -0
- package/dist/search/vector.js.map +1 -0
- package/dist/store.d.ts +119 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +500 -0
- package/dist/store.js.map +1 -0
- package/package.json +48 -0
package/dist/store.js
ADDED
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import * as sqliteVec from "sqlite-vec";
|
|
3
|
+
// --- Embedding text formatting ---
|
|
4
|
+
/**
|
|
5
|
+
* Format a chunk with contextual metadata for embedding.
|
|
6
|
+
* The resulting string includes file path, language, chunk type, and name
|
|
7
|
+
* as a prefix before the actual code content, so that the embedding model
|
|
8
|
+
* captures contextual information alongside the raw code.
|
|
9
|
+
*
|
|
10
|
+
* Format: "file: <path> | language: <lang> | type: <type> | name: <name> | code: <content>"
|
|
11
|
+
*/
|
|
12
|
+
export function formatChunkForEmbedding(chunk) {
|
|
13
|
+
const parts = [];
|
|
14
|
+
if (chunk.file_path)
|
|
15
|
+
parts.push(`file: ${chunk.file_path}`);
|
|
16
|
+
if (chunk.language)
|
|
17
|
+
parts.push(`language: ${chunk.language}`);
|
|
18
|
+
if (chunk.chunk_type)
|
|
19
|
+
parts.push(`type: ${chunk.chunk_type}`);
|
|
20
|
+
if (chunk.name)
|
|
21
|
+
parts.push(`name: ${chunk.name}`);
|
|
22
|
+
parts.push(`code: ${chunk.content}`);
|
|
23
|
+
return parts.join(" | ");
|
|
24
|
+
}
|
|
25
|
+
// --- Schema SQL ---
|
|
26
|
+
const SCHEMA_SQL = `
|
|
27
|
+
CREATE TABLE IF NOT EXISTS repositories (
|
|
28
|
+
id TEXT PRIMARY KEY,
|
|
29
|
+
path TEXT NOT NULL,
|
|
30
|
+
last_commit TEXT,
|
|
31
|
+
indexed_at TEXT,
|
|
32
|
+
config TEXT
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
CREATE TABLE IF NOT EXISTS files (
|
|
36
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
37
|
+
repo_id TEXT NOT NULL REFERENCES repositories(id),
|
|
38
|
+
path TEXT NOT NULL,
|
|
39
|
+
hash TEXT NOT NULL,
|
|
40
|
+
language TEXT,
|
|
41
|
+
active INTEGER DEFAULT 1,
|
|
42
|
+
indexed_at TEXT,
|
|
43
|
+
UNIQUE(repo_id, path)
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
CREATE INDEX IF NOT EXISTS idx_files_repo_id ON files(repo_id);
|
|
47
|
+
CREATE INDEX IF NOT EXISTS idx_files_hash ON files(hash);
|
|
48
|
+
CREATE INDEX IF NOT EXISTS idx_files_active ON files(active);
|
|
49
|
+
|
|
50
|
+
CREATE TABLE IF NOT EXISTS chunks (
|
|
51
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
52
|
+
file_id INTEGER NOT NULL REFERENCES files(id),
|
|
53
|
+
hash TEXT NOT NULL,
|
|
54
|
+
seq INTEGER NOT NULL,
|
|
55
|
+
start_line INTEGER,
|
|
56
|
+
end_line INTEGER,
|
|
57
|
+
chunk_type TEXT,
|
|
58
|
+
name TEXT,
|
|
59
|
+
content TEXT NOT NULL,
|
|
60
|
+
metadata TEXT,
|
|
61
|
+
UNIQUE(file_id, seq)
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_chunks_file_id ON chunks(file_id);
|
|
65
|
+
CREATE INDEX IF NOT EXISTS idx_chunks_hash ON chunks(hash);
|
|
66
|
+
|
|
67
|
+
CREATE TABLE IF NOT EXISTS chunk_vectors (
|
|
68
|
+
chunk_id INTEGER PRIMARY KEY REFERENCES chunks(id),
|
|
69
|
+
model TEXT NOT NULL,
|
|
70
|
+
embedded_at TEXT
|
|
71
|
+
);
|
|
72
|
+
`;
|
|
73
|
+
const FTS_SQL = `
|
|
74
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS chunks_fts USING fts5(
|
|
75
|
+
content,
|
|
76
|
+
name,
|
|
77
|
+
content=chunks,
|
|
78
|
+
content_rowid=id
|
|
79
|
+
);
|
|
80
|
+
`;
|
|
81
|
+
const FTS_TRIGGERS_SQL = `
|
|
82
|
+
CREATE TRIGGER IF NOT EXISTS chunks_ai AFTER INSERT ON chunks BEGIN
|
|
83
|
+
INSERT INTO chunks_fts(rowid, content, name) VALUES (new.id, new.content, new.name);
|
|
84
|
+
END;
|
|
85
|
+
|
|
86
|
+
CREATE TRIGGER IF NOT EXISTS chunks_ad AFTER DELETE ON chunks BEGIN
|
|
87
|
+
INSERT INTO chunks_fts(chunks_fts, rowid, content, name) VALUES('delete', old.id, old.content, old.name);
|
|
88
|
+
END;
|
|
89
|
+
|
|
90
|
+
CREATE TRIGGER IF NOT EXISTS chunks_au AFTER UPDATE ON chunks BEGIN
|
|
91
|
+
INSERT INTO chunks_fts(chunks_fts, rowid, content, name) VALUES('delete', old.id, old.content, old.name);
|
|
92
|
+
INSERT INTO chunks_fts(rowid, content, name) VALUES (new.id, new.content, new.name);
|
|
93
|
+
END;
|
|
94
|
+
`;
|
|
95
|
+
function vectorTableSQL(dimensions) {
|
|
96
|
+
return `CREATE VIRTUAL TABLE IF NOT EXISTS vectors_vec USING vec0(
|
|
97
|
+
chunk_id INTEGER PRIMARY KEY,
|
|
98
|
+
embedding float[${dimensions}] distance_metric=cosine
|
|
99
|
+
);`;
|
|
100
|
+
}
|
|
101
|
+
function prepareStatements(db) {
|
|
102
|
+
return {
|
|
103
|
+
upsertRepo: db.prepare(`
|
|
104
|
+
INSERT INTO repositories (id, path, last_commit, indexed_at, config)
|
|
105
|
+
VALUES (@id, @path, @last_commit, @indexed_at, @config)
|
|
106
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
107
|
+
path = excluded.path,
|
|
108
|
+
last_commit = excluded.last_commit,
|
|
109
|
+
indexed_at = excluded.indexed_at,
|
|
110
|
+
config = excluded.config
|
|
111
|
+
`),
|
|
112
|
+
upsertFile: db.prepare(`
|
|
113
|
+
INSERT INTO files (repo_id, path, hash, language, active, indexed_at)
|
|
114
|
+
VALUES (@repo_id, @path, @hash, @language, @active, @indexed_at)
|
|
115
|
+
ON CONFLICT(repo_id, path) DO UPDATE SET
|
|
116
|
+
hash = excluded.hash,
|
|
117
|
+
language = excluded.language,
|
|
118
|
+
active = excluded.active,
|
|
119
|
+
indexed_at = excluded.indexed_at
|
|
120
|
+
`),
|
|
121
|
+
getFileByRepoAndPath: db.prepare(`
|
|
122
|
+
SELECT * FROM files WHERE repo_id = ? AND path = ?
|
|
123
|
+
`),
|
|
124
|
+
insertChunk: db.prepare(`
|
|
125
|
+
INSERT INTO chunks (file_id, hash, seq, start_line, end_line, chunk_type, name, content, metadata)
|
|
126
|
+
VALUES (@file_id, @hash, @seq, @start_line, @end_line, @chunk_type, @name, @content, @metadata)
|
|
127
|
+
`),
|
|
128
|
+
deleteChunksByFileId: db.prepare(`
|
|
129
|
+
DELETE FROM chunks WHERE file_id = ?
|
|
130
|
+
`),
|
|
131
|
+
getChunkHashesByFileId: db.prepare(`
|
|
132
|
+
SELECT id, hash, seq FROM chunks WHERE file_id = ? ORDER BY seq ASC
|
|
133
|
+
`),
|
|
134
|
+
deleteChunkById: db.prepare(`
|
|
135
|
+
DELETE FROM chunks WHERE id = ?
|
|
136
|
+
`),
|
|
137
|
+
deleteVectorByChunkId: db.prepare(`
|
|
138
|
+
DELETE FROM vectors_vec WHERE chunk_id = ?
|
|
139
|
+
`),
|
|
140
|
+
deleteChunkVectorByChunkId: db.prepare(`
|
|
141
|
+
DELETE FROM chunk_vectors WHERE chunk_id = ?
|
|
142
|
+
`),
|
|
143
|
+
updateChunkSeq: db.prepare(`
|
|
144
|
+
UPDATE chunks SET seq = ? WHERE id = ?
|
|
145
|
+
`),
|
|
146
|
+
getUnembeddedChunks: db.prepare(`
|
|
147
|
+
SELECT
|
|
148
|
+
c.id AS chunk_id,
|
|
149
|
+
c.content,
|
|
150
|
+
c.name,
|
|
151
|
+
c.chunk_type,
|
|
152
|
+
f.path AS file_path,
|
|
153
|
+
f.language,
|
|
154
|
+
f.repo_id
|
|
155
|
+
FROM chunks c
|
|
156
|
+
JOIN files f ON c.file_id = f.id
|
|
157
|
+
WHERE f.active = 1
|
|
158
|
+
AND c.id NOT IN (SELECT chunk_id FROM chunk_vectors)
|
|
159
|
+
LIMIT ?
|
|
160
|
+
`),
|
|
161
|
+
insertVector: db.prepare(`
|
|
162
|
+
INSERT INTO vectors_vec (chunk_id, embedding)
|
|
163
|
+
VALUES (?, ?)
|
|
164
|
+
`),
|
|
165
|
+
insertChunkVector: db.prepare(`
|
|
166
|
+
INSERT OR REPLACE INTO chunk_vectors (chunk_id, model, embedded_at)
|
|
167
|
+
VALUES (?, ?, ?)
|
|
168
|
+
`),
|
|
169
|
+
searchBM25: db.prepare(`
|
|
170
|
+
SELECT
|
|
171
|
+
c.id AS chunk_id,
|
|
172
|
+
c.file_id,
|
|
173
|
+
c.content,
|
|
174
|
+
c.name,
|
|
175
|
+
c.chunk_type,
|
|
176
|
+
c.start_line,
|
|
177
|
+
c.end_line,
|
|
178
|
+
f.path AS file_path,
|
|
179
|
+
f.repo_id,
|
|
180
|
+
fts.rank
|
|
181
|
+
FROM chunks_fts fts
|
|
182
|
+
JOIN chunks c ON c.id = fts.rowid
|
|
183
|
+
JOIN files f ON c.file_id = f.id
|
|
184
|
+
WHERE chunks_fts MATCH ?
|
|
185
|
+
AND f.active = 1
|
|
186
|
+
ORDER BY fts.rank
|
|
187
|
+
LIMIT ?
|
|
188
|
+
`),
|
|
189
|
+
searchVector: db.prepare(`
|
|
190
|
+
SELECT
|
|
191
|
+
v.chunk_id,
|
|
192
|
+
v.distance
|
|
193
|
+
FROM vectors_vec v
|
|
194
|
+
WHERE v.embedding MATCH ?
|
|
195
|
+
AND k = ?
|
|
196
|
+
`),
|
|
197
|
+
searchVectorDetail: db.prepare(`
|
|
198
|
+
SELECT
|
|
199
|
+
c.id AS chunk_id,
|
|
200
|
+
c.file_id,
|
|
201
|
+
c.content,
|
|
202
|
+
c.name,
|
|
203
|
+
c.chunk_type,
|
|
204
|
+
c.start_line,
|
|
205
|
+
c.end_line,
|
|
206
|
+
f.path AS file_path,
|
|
207
|
+
f.repo_id
|
|
208
|
+
FROM chunks c
|
|
209
|
+
JOIN files f ON c.file_id = f.id
|
|
210
|
+
WHERE c.id = ?
|
|
211
|
+
AND f.active = 1
|
|
212
|
+
`),
|
|
213
|
+
deactivateFile: db.prepare(`
|
|
214
|
+
UPDATE files SET active = 0 WHERE repo_id = ? AND path = ?
|
|
215
|
+
`),
|
|
216
|
+
deleteOrphanChunks: db.prepare(`
|
|
217
|
+
DELETE FROM chunks WHERE file_id IN (
|
|
218
|
+
SELECT id FROM files WHERE active = 0
|
|
219
|
+
)
|
|
220
|
+
`),
|
|
221
|
+
deleteOrphanVectors: db.prepare(`
|
|
222
|
+
DELETE FROM vectors_vec WHERE chunk_id NOT IN (
|
|
223
|
+
SELECT id FROM chunks
|
|
224
|
+
)
|
|
225
|
+
`),
|
|
226
|
+
deleteOrphanChunkVectors: db.prepare(`
|
|
227
|
+
DELETE FROM chunk_vectors WHERE chunk_id NOT IN (
|
|
228
|
+
SELECT id FROM chunks
|
|
229
|
+
)
|
|
230
|
+
`),
|
|
231
|
+
countRepos: db.prepare(`SELECT COUNT(*) AS count FROM repositories`),
|
|
232
|
+
countFiles: db.prepare(`SELECT COUNT(*) AS count FROM files`),
|
|
233
|
+
countActiveFiles: db.prepare(`SELECT COUNT(*) AS count FROM files WHERE active = 1`),
|
|
234
|
+
countChunks: db.prepare(`SELECT COUNT(*) AS count FROM chunks`),
|
|
235
|
+
countEmbeddedChunks: db.prepare(`SELECT COUNT(*) AS count FROM chunk_vectors`),
|
|
236
|
+
getRepository: db.prepare(`
|
|
237
|
+
SELECT * FROM repositories WHERE id = ?
|
|
238
|
+
`),
|
|
239
|
+
getActiveFiles: db.prepare(`
|
|
240
|
+
SELECT * FROM files WHERE repo_id = ? AND active = 1
|
|
241
|
+
`),
|
|
242
|
+
getFileByPath: db.prepare(`
|
|
243
|
+
SELECT * FROM files WHERE repo_id = ? AND path = ?
|
|
244
|
+
`),
|
|
245
|
+
getChunksByFileId: db.prepare(`
|
|
246
|
+
SELECT * FROM chunks WHERE file_id = ? ORDER BY seq ASC
|
|
247
|
+
`),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
// --- Factory ---
|
|
251
|
+
export function createStore(dbPath) {
|
|
252
|
+
const db = new Database(dbPath);
|
|
253
|
+
let stmts = null;
|
|
254
|
+
return {
|
|
255
|
+
initDb(dimensions) {
|
|
256
|
+
// Load sqlite-vec extension
|
|
257
|
+
sqliteVec.load(db);
|
|
258
|
+
// Pragmas
|
|
259
|
+
db.pragma("journal_mode = WAL");
|
|
260
|
+
db.pragma("foreign_keys = ON");
|
|
261
|
+
// Create core tables
|
|
262
|
+
db.exec(SCHEMA_SQL);
|
|
263
|
+
// Create FTS5 virtual table
|
|
264
|
+
db.exec(FTS_SQL);
|
|
265
|
+
// Create FTS5 triggers
|
|
266
|
+
db.exec(FTS_TRIGGERS_SQL);
|
|
267
|
+
// Create sqlite-vec virtual table
|
|
268
|
+
db.exec(vectorTableSQL(dimensions));
|
|
269
|
+
// Prepare statements
|
|
270
|
+
stmts = prepareStatements(db);
|
|
271
|
+
},
|
|
272
|
+
upsertRepository(repo) {
|
|
273
|
+
stmts.upsertRepo.run({
|
|
274
|
+
id: repo.id,
|
|
275
|
+
path: repo.path,
|
|
276
|
+
last_commit: repo.last_commit ?? null,
|
|
277
|
+
indexed_at: repo.indexed_at ?? new Date().toISOString(),
|
|
278
|
+
config: repo.config ?? null,
|
|
279
|
+
});
|
|
280
|
+
},
|
|
281
|
+
upsertFile(file) {
|
|
282
|
+
const existing = stmts.getFileByRepoAndPath.get(file.repo_id, file.path);
|
|
283
|
+
if (existing && existing.hash === file.hash && existing.active === 1) {
|
|
284
|
+
return { id: existing.id, changed: false };
|
|
285
|
+
}
|
|
286
|
+
const result = stmts.upsertFile.run({
|
|
287
|
+
repo_id: file.repo_id,
|
|
288
|
+
path: file.path,
|
|
289
|
+
hash: file.hash,
|
|
290
|
+
language: file.language ?? null,
|
|
291
|
+
active: file.active ?? 1,
|
|
292
|
+
indexed_at: file.indexed_at ?? new Date().toISOString(),
|
|
293
|
+
});
|
|
294
|
+
const id = existing
|
|
295
|
+
? existing.id
|
|
296
|
+
: Number(result.lastInsertRowid);
|
|
297
|
+
return { id, changed: true };
|
|
298
|
+
},
|
|
299
|
+
insertChunks(fileId, chunks) {
|
|
300
|
+
const ids = [];
|
|
301
|
+
const txn = db.transaction(() => {
|
|
302
|
+
// Get existing chunks for this file
|
|
303
|
+
const existingChunks = stmts.getChunkHashesByFileId.all(fileId);
|
|
304
|
+
// Build a map of existing hash -> chunk info (use first occurrence per hash)
|
|
305
|
+
const existingByHash = new Map();
|
|
306
|
+
for (const ec of existingChunks) {
|
|
307
|
+
if (!existingByHash.has(ec.hash)) {
|
|
308
|
+
existingByHash.set(ec.hash, { id: ec.id, seq: ec.seq, used: false });
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// Build set of new hashes for detecting removed chunks
|
|
312
|
+
const newHashCounts = new Map();
|
|
313
|
+
for (const chunk of chunks) {
|
|
314
|
+
newHashCounts.set(chunk.hash, (newHashCounts.get(chunk.hash) ?? 0) + 1);
|
|
315
|
+
}
|
|
316
|
+
// Track which existing chunk IDs are reused
|
|
317
|
+
const reusedIds = new Set();
|
|
318
|
+
// Process new chunks: match by hash, reuse or insert
|
|
319
|
+
// First pass: collect hash usage to handle duplicates
|
|
320
|
+
const hashUsage = new Map(); // hash -> times used so far
|
|
321
|
+
for (const chunk of chunks) {
|
|
322
|
+
const usedCount = hashUsage.get(chunk.hash) ?? 0;
|
|
323
|
+
hashUsage.set(chunk.hash, usedCount + 1);
|
|
324
|
+
// Find an available existing chunk with this hash
|
|
325
|
+
const existing = existingByHash.get(chunk.hash);
|
|
326
|
+
if (existing && !existing.used) {
|
|
327
|
+
// Reuse existing chunk - just update seq if needed
|
|
328
|
+
existing.used = true;
|
|
329
|
+
reusedIds.add(existing.id);
|
|
330
|
+
if (existing.seq !== chunk.seq) {
|
|
331
|
+
// Need to handle UNIQUE(file_id, seq) constraint:
|
|
332
|
+
// Temporarily set seq to a negative value, then update
|
|
333
|
+
stmts.updateChunkSeq.run(-(chunk.seq + 1), existing.id);
|
|
334
|
+
}
|
|
335
|
+
ids.push(existing.id);
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
// New chunk - will insert after cleanup
|
|
339
|
+
ids.push(-1); // placeholder
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Delete chunks that are no longer needed (not reused)
|
|
343
|
+
for (const ec of existingChunks) {
|
|
344
|
+
if (!reusedIds.has(ec.id)) {
|
|
345
|
+
stmts.deleteVectorByChunkId.run(BigInt(ec.id));
|
|
346
|
+
stmts.deleteChunkVectorByChunkId.run(ec.id);
|
|
347
|
+
stmts.deleteChunkById.run(ec.id);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// Fix temporary seq values for reused chunks
|
|
351
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
352
|
+
if (ids[i] !== -1) {
|
|
353
|
+
const existing = existingByHash.get(chunks[i].hash);
|
|
354
|
+
if (existing && existing.id === ids[i] && existing.seq !== chunks[i].seq) {
|
|
355
|
+
stmts.updateChunkSeq.run(chunks[i].seq, ids[i]);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
// Insert new chunks (those with placeholder -1)
|
|
360
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
361
|
+
if (ids[i] === -1) {
|
|
362
|
+
const chunk = chunks[i];
|
|
363
|
+
const result = stmts.insertChunk.run({
|
|
364
|
+
file_id: fileId,
|
|
365
|
+
hash: chunk.hash,
|
|
366
|
+
seq: chunk.seq,
|
|
367
|
+
start_line: chunk.start_line ?? null,
|
|
368
|
+
end_line: chunk.end_line ?? null,
|
|
369
|
+
chunk_type: chunk.chunk_type ?? null,
|
|
370
|
+
name: chunk.name ?? null,
|
|
371
|
+
content: chunk.content,
|
|
372
|
+
metadata: chunk.metadata ?? null,
|
|
373
|
+
});
|
|
374
|
+
ids[i] = Number(result.lastInsertRowid);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
txn();
|
|
379
|
+
return ids;
|
|
380
|
+
},
|
|
381
|
+
getUnembeddedChunks(limit = 100) {
|
|
382
|
+
return stmts.getUnembeddedChunks.all(limit);
|
|
383
|
+
},
|
|
384
|
+
insertEmbeddings(embeddings) {
|
|
385
|
+
const txn = db.transaction(() => {
|
|
386
|
+
const now = new Date().toISOString();
|
|
387
|
+
for (const emb of embeddings) {
|
|
388
|
+
// sqlite-vec requires BigInt for integer primary key bindings
|
|
389
|
+
stmts.insertVector.run(BigInt(emb.chunk_id), emb.embedding);
|
|
390
|
+
stmts.insertChunkVector.run(emb.chunk_id, emb.model, now);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
txn();
|
|
394
|
+
},
|
|
395
|
+
searchBM25(query, limit = 20) {
|
|
396
|
+
const ftsQuery = buildFTS5Query(query);
|
|
397
|
+
if (!ftsQuery)
|
|
398
|
+
return [];
|
|
399
|
+
return stmts.searchBM25.all(ftsQuery, limit);
|
|
400
|
+
},
|
|
401
|
+
searchVector(embedding, limit = 20) {
|
|
402
|
+
// Step 1: Get chunk_ids and distances from sqlite-vec
|
|
403
|
+
const vecResults = stmts.searchVector.all(embedding, limit);
|
|
404
|
+
if (vecResults.length === 0)
|
|
405
|
+
return [];
|
|
406
|
+
// Step 2: Fetch full chunk details for each result
|
|
407
|
+
const results = [];
|
|
408
|
+
for (const vr of vecResults) {
|
|
409
|
+
const row = stmts.searchVectorDetail.get(vr.chunk_id);
|
|
410
|
+
if (row) {
|
|
411
|
+
results.push({ ...row, distance: vr.distance });
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return results;
|
|
415
|
+
},
|
|
416
|
+
deactivateFiles(repoId, paths) {
|
|
417
|
+
const txn = db.transaction(() => {
|
|
418
|
+
for (const p of paths) {
|
|
419
|
+
stmts.deactivateFile.run(repoId, p);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
txn();
|
|
423
|
+
},
|
|
424
|
+
cleanup() {
|
|
425
|
+
let deletedChunks = 0;
|
|
426
|
+
let deletedVectors = 0;
|
|
427
|
+
const txn = db.transaction(() => {
|
|
428
|
+
// Get chunk IDs from inactive files
|
|
429
|
+
const orphanChunkIds = db
|
|
430
|
+
.prepare(`SELECT id FROM chunks WHERE file_id IN (SELECT id FROM files WHERE active = 0)`)
|
|
431
|
+
.all();
|
|
432
|
+
if (orphanChunkIds.length > 0) {
|
|
433
|
+
// Delete vectors for these chunks first (sqlite-vec requires BigInt)
|
|
434
|
+
const deleteVec = db.prepare(`DELETE FROM vectors_vec WHERE chunk_id = ?`);
|
|
435
|
+
const deleteCV = db.prepare(`DELETE FROM chunk_vectors WHERE chunk_id = ?`);
|
|
436
|
+
for (const { id } of orphanChunkIds) {
|
|
437
|
+
deleteVec.run(BigInt(id));
|
|
438
|
+
deleteCV.run(id);
|
|
439
|
+
}
|
|
440
|
+
deletedVectors = orphanChunkIds.length;
|
|
441
|
+
// Now delete the orphan chunks
|
|
442
|
+
const chunkResult = stmts.deleteOrphanChunks.run();
|
|
443
|
+
deletedChunks = chunkResult.changes;
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
txn();
|
|
447
|
+
return { deletedChunks, deletedVectors };
|
|
448
|
+
},
|
|
449
|
+
getStats() {
|
|
450
|
+
const repos = stmts.countRepos.get().count;
|
|
451
|
+
const files = stmts.countFiles.get().count;
|
|
452
|
+
const activeFiles = stmts.countActiveFiles.get().count;
|
|
453
|
+
const chunks = stmts.countChunks.get().count;
|
|
454
|
+
const embeddedChunks = stmts.countEmbeddedChunks.get().count;
|
|
455
|
+
return {
|
|
456
|
+
repositories: repos,
|
|
457
|
+
files,
|
|
458
|
+
active_files: activeFiles,
|
|
459
|
+
chunks,
|
|
460
|
+
embedded_chunks: embeddedChunks,
|
|
461
|
+
pending_chunks: chunks - embeddedChunks,
|
|
462
|
+
};
|
|
463
|
+
},
|
|
464
|
+
getRepository(repoId) {
|
|
465
|
+
return stmts.getRepository.get(repoId);
|
|
466
|
+
},
|
|
467
|
+
getActiveFiles(repoId) {
|
|
468
|
+
return stmts.getActiveFiles.all(repoId);
|
|
469
|
+
},
|
|
470
|
+
getFileByPath(repoId, path) {
|
|
471
|
+
return stmts.getFileByPath.get(repoId, path);
|
|
472
|
+
},
|
|
473
|
+
getChunksByFileId(fileId) {
|
|
474
|
+
return stmts.getChunksByFileId.all(fileId);
|
|
475
|
+
},
|
|
476
|
+
close() {
|
|
477
|
+
db.close();
|
|
478
|
+
},
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
// --- Helpers ---
|
|
482
|
+
/**
|
|
483
|
+
* Build an FTS5-compatible query from user input.
|
|
484
|
+
* Supports quoted phrases, handles special characters.
|
|
485
|
+
*/
|
|
486
|
+
function buildFTS5Query(input) {
|
|
487
|
+
const trimmed = input.trim();
|
|
488
|
+
if (!trimmed)
|
|
489
|
+
return "";
|
|
490
|
+
// If already contains FTS5 operators, pass through
|
|
491
|
+
if (/["{}\[\]]/.test(trimmed) || /\b(AND|OR|NOT|NEAR)\b/.test(trimmed)) {
|
|
492
|
+
return trimmed;
|
|
493
|
+
}
|
|
494
|
+
// Split into tokens, wrap each in quotes for safe matching
|
|
495
|
+
const tokens = trimmed.split(/\s+/).filter(Boolean);
|
|
496
|
+
if (tokens.length === 0)
|
|
497
|
+
return "";
|
|
498
|
+
return tokens.map((t) => `"${t.replace(/"/g, '""')}"`).join(" ");
|
|
499
|
+
}
|
|
500
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@unlimiting/qsc",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Query Source Code - AST-based code search with hybrid BM25+Vector+LLM reranking",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"qsc": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/",
|
|
13
|
+
"package.json",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "tsx src/index.ts",
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"start": "node dist/index.js",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=20"
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
33
|
+
"better-sqlite3": "^12.6.2",
|
|
34
|
+
"fast-glob": "^3.3.3",
|
|
35
|
+
"openai": "^6.25.0",
|
|
36
|
+
"sqlite-vec": "^0.1.7-alpha.2",
|
|
37
|
+
"tree-sitter-wasms": "^0.1.13",
|
|
38
|
+
"web-tree-sitter": "^0.22.6",
|
|
39
|
+
"yaml": "^2.8.2",
|
|
40
|
+
"zod": "^4.3.6"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
44
|
+
"@types/node": "^25.3.2",
|
|
45
|
+
"tsx": "^4.21.0",
|
|
46
|
+
"typescript": "^5.9.3"
|
|
47
|
+
}
|
|
48
|
+
}
|