codeseeker 1.7.1 → 1.7.3
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 +134 -63
- package/dist/cli/commands/handlers/setup-command-handler.d.ts.map +1 -1
- package/dist/cli/commands/handlers/setup-command-handler.js +205 -185
- package/dist/cli/commands/handlers/setup-command-handler.js.map +1 -1
- package/dist/cli/commands/services/context-aware-clarification-service.js +3 -3
- package/dist/cli/services/analysis/deduplication/code-consolidation-handler.js +41 -41
- package/dist/shared/analysis-repository.js +28 -28
- package/dist/shared/documentation-rag-service.js +40 -40
- package/dist/storage/embedded/sqlite-vector-store.js +57 -57
- package/dist/storage/server/neo4j-graph-store.js +81 -81
- package/dist/storage/server/postgres-vector-store.js +65 -65
- package/package.json +4 -2
- package/scripts/postinstall.js +458 -0
|
@@ -38,17 +38,17 @@ class Neo4jGraphStore {
|
|
|
38
38
|
const session = this.driver.session({ database: this.database });
|
|
39
39
|
try {
|
|
40
40
|
// Create indexes for fast lookups
|
|
41
|
-
await session.run(`
|
|
42
|
-
CREATE INDEX node_id IF NOT EXISTS FOR (n:CodeNode) ON (n.id)
|
|
41
|
+
await session.run(`
|
|
42
|
+
CREATE INDEX node_id IF NOT EXISTS FOR (n:CodeNode) ON (n.id)
|
|
43
43
|
`);
|
|
44
|
-
await session.run(`
|
|
45
|
-
CREATE INDEX node_project IF NOT EXISTS FOR (n:CodeNode) ON (n.projectId)
|
|
44
|
+
await session.run(`
|
|
45
|
+
CREATE INDEX node_project IF NOT EXISTS FOR (n:CodeNode) ON (n.projectId)
|
|
46
46
|
`);
|
|
47
|
-
await session.run(`
|
|
48
|
-
CREATE INDEX node_type IF NOT EXISTS FOR (n:CodeNode) ON (n.type)
|
|
47
|
+
await session.run(`
|
|
48
|
+
CREATE INDEX node_type IF NOT EXISTS FOR (n:CodeNode) ON (n.type)
|
|
49
49
|
`);
|
|
50
|
-
await session.run(`
|
|
51
|
-
CREATE INDEX node_filepath IF NOT EXISTS FOR (n:CodeNode) ON (n.filePath)
|
|
50
|
+
await session.run(`
|
|
51
|
+
CREATE INDEX node_filepath IF NOT EXISTS FOR (n:CodeNode) ON (n.filePath)
|
|
52
52
|
`);
|
|
53
53
|
this.initialized = true;
|
|
54
54
|
}
|
|
@@ -60,13 +60,13 @@ class Neo4jGraphStore {
|
|
|
60
60
|
await this.initialize();
|
|
61
61
|
const session = this.driver.session({ database: this.database });
|
|
62
62
|
try {
|
|
63
|
-
await session.run(`
|
|
64
|
-
MERGE (n:CodeNode {id: $id})
|
|
65
|
-
SET n.type = $type,
|
|
66
|
-
n.name = $name,
|
|
67
|
-
n.filePath = $filePath,
|
|
68
|
-
n.projectId = $projectId,
|
|
69
|
-
n.properties = $properties
|
|
63
|
+
await session.run(`
|
|
64
|
+
MERGE (n:CodeNode {id: $id})
|
|
65
|
+
SET n.type = $type,
|
|
66
|
+
n.name = $name,
|
|
67
|
+
n.filePath = $filePath,
|
|
68
|
+
n.projectId = $projectId,
|
|
69
|
+
n.properties = $properties
|
|
70
70
|
`, {
|
|
71
71
|
id: node.id,
|
|
72
72
|
type: node.type,
|
|
@@ -86,11 +86,11 @@ class Neo4jGraphStore {
|
|
|
86
86
|
try {
|
|
87
87
|
// Use dynamic relationship type
|
|
88
88
|
const relType = edge.type.toUpperCase();
|
|
89
|
-
await session.run(`
|
|
90
|
-
MATCH (source:CodeNode {id: $sourceId})
|
|
91
|
-
MATCH (target:CodeNode {id: $targetId})
|
|
92
|
-
MERGE (source)-[r:${relType} {id: $edgeId}]->(target)
|
|
93
|
-
SET r.properties = $properties
|
|
89
|
+
await session.run(`
|
|
90
|
+
MATCH (source:CodeNode {id: $sourceId})
|
|
91
|
+
MATCH (target:CodeNode {id: $targetId})
|
|
92
|
+
MERGE (source)-[r:${relType} {id: $edgeId}]->(target)
|
|
93
|
+
SET r.properties = $properties
|
|
94
94
|
`, {
|
|
95
95
|
sourceId: edge.source,
|
|
96
96
|
targetId: edge.target,
|
|
@@ -108,13 +108,13 @@ class Neo4jGraphStore {
|
|
|
108
108
|
try {
|
|
109
109
|
await session.executeWrite(async (tx) => {
|
|
110
110
|
for (const node of nodes) {
|
|
111
|
-
await tx.run(`
|
|
112
|
-
MERGE (n:CodeNode {id: $id})
|
|
113
|
-
SET n.type = $type,
|
|
114
|
-
n.name = $name,
|
|
115
|
-
n.filePath = $filePath,
|
|
116
|
-
n.projectId = $projectId,
|
|
117
|
-
n.properties = $properties
|
|
111
|
+
await tx.run(`
|
|
112
|
+
MERGE (n:CodeNode {id: $id})
|
|
113
|
+
SET n.type = $type,
|
|
114
|
+
n.name = $name,
|
|
115
|
+
n.filePath = $filePath,
|
|
116
|
+
n.projectId = $projectId,
|
|
117
|
+
n.properties = $properties
|
|
118
118
|
`, {
|
|
119
119
|
id: node.id,
|
|
120
120
|
type: node.type,
|
|
@@ -137,11 +137,11 @@ class Neo4jGraphStore {
|
|
|
137
137
|
await session.executeWrite(async (tx) => {
|
|
138
138
|
for (const edge of edges) {
|
|
139
139
|
const relType = edge.type.toUpperCase();
|
|
140
|
-
await tx.run(`
|
|
141
|
-
MATCH (source:CodeNode {id: $sourceId})
|
|
142
|
-
MATCH (target:CodeNode {id: $targetId})
|
|
143
|
-
MERGE (source)-[r:${relType} {id: $edgeId}]->(target)
|
|
144
|
-
SET r.properties = $properties
|
|
140
|
+
await tx.run(`
|
|
141
|
+
MATCH (source:CodeNode {id: $sourceId})
|
|
142
|
+
MATCH (target:CodeNode {id: $targetId})
|
|
143
|
+
MERGE (source)-[r:${relType} {id: $edgeId}]->(target)
|
|
144
|
+
SET r.properties = $properties
|
|
145
145
|
`, {
|
|
146
146
|
sourceId: edge.source,
|
|
147
147
|
targetId: edge.target,
|
|
@@ -162,18 +162,18 @@ class Neo4jGraphStore {
|
|
|
162
162
|
let query;
|
|
163
163
|
let params;
|
|
164
164
|
if (type) {
|
|
165
|
-
query = `
|
|
166
|
-
MATCH (n:CodeNode)
|
|
167
|
-
WHERE n.projectId = $projectId AND n.type = $type
|
|
168
|
-
RETURN n
|
|
165
|
+
query = `
|
|
166
|
+
MATCH (n:CodeNode)
|
|
167
|
+
WHERE n.projectId = $projectId AND n.type = $type
|
|
168
|
+
RETURN n
|
|
169
169
|
`;
|
|
170
170
|
params = { projectId, type };
|
|
171
171
|
}
|
|
172
172
|
else {
|
|
173
|
-
query = `
|
|
174
|
-
MATCH (n:CodeNode)
|
|
175
|
-
WHERE n.projectId = $projectId
|
|
176
|
-
RETURN n
|
|
173
|
+
query = `
|
|
174
|
+
MATCH (n:CodeNode)
|
|
175
|
+
WHERE n.projectId = $projectId
|
|
176
|
+
RETURN n
|
|
177
177
|
`;
|
|
178
178
|
params = { projectId };
|
|
179
179
|
}
|
|
@@ -188,9 +188,9 @@ class Neo4jGraphStore {
|
|
|
188
188
|
await this.initialize();
|
|
189
189
|
const session = this.driver.session({ database: this.database });
|
|
190
190
|
try {
|
|
191
|
-
const result = await session.run(`
|
|
192
|
-
MATCH (n:CodeNode {id: $id})
|
|
193
|
-
RETURN n
|
|
191
|
+
const result = await session.run(`
|
|
192
|
+
MATCH (n:CodeNode {id: $id})
|
|
193
|
+
RETURN n
|
|
194
194
|
`, { id });
|
|
195
195
|
if (result.records.length === 0)
|
|
196
196
|
return null;
|
|
@@ -206,25 +206,25 @@ class Neo4jGraphStore {
|
|
|
206
206
|
try {
|
|
207
207
|
let query;
|
|
208
208
|
if (direction === 'out') {
|
|
209
|
-
query = `
|
|
210
|
-
MATCH (n:CodeNode {id: $nodeId})-[r]->(target)
|
|
211
|
-
RETURN r, n.id as sourceId, target.id as targetId, type(r) as relType
|
|
209
|
+
query = `
|
|
210
|
+
MATCH (n:CodeNode {id: $nodeId})-[r]->(target)
|
|
211
|
+
RETURN r, n.id as sourceId, target.id as targetId, type(r) as relType
|
|
212
212
|
`;
|
|
213
213
|
}
|
|
214
214
|
else if (direction === 'in') {
|
|
215
|
-
query = `
|
|
216
|
-
MATCH (source)-[r]->(n:CodeNode {id: $nodeId})
|
|
217
|
-
RETURN r, source.id as sourceId, n.id as targetId, type(r) as relType
|
|
215
|
+
query = `
|
|
216
|
+
MATCH (source)-[r]->(n:CodeNode {id: $nodeId})
|
|
217
|
+
RETURN r, source.id as sourceId, n.id as targetId, type(r) as relType
|
|
218
218
|
`;
|
|
219
219
|
}
|
|
220
220
|
else {
|
|
221
|
-
query = `
|
|
222
|
-
MATCH (n:CodeNode {id: $nodeId})-[r]-(other)
|
|
223
|
-
WITH r,
|
|
224
|
-
CASE WHEN startNode(r).id = $nodeId THEN startNode(r).id ELSE endNode(r).id END as sourceId,
|
|
225
|
-
CASE WHEN startNode(r).id = $nodeId THEN endNode(r).id ELSE startNode(r).id END as targetId,
|
|
226
|
-
type(r) as relType
|
|
227
|
-
RETURN DISTINCT r, sourceId, targetId, relType
|
|
221
|
+
query = `
|
|
222
|
+
MATCH (n:CodeNode {id: $nodeId})-[r]-(other)
|
|
223
|
+
WITH r,
|
|
224
|
+
CASE WHEN startNode(r).id = $nodeId THEN startNode(r).id ELSE endNode(r).id END as sourceId,
|
|
225
|
+
CASE WHEN startNode(r).id = $nodeId THEN endNode(r).id ELSE startNode(r).id END as targetId,
|
|
226
|
+
type(r) as relType
|
|
227
|
+
RETURN DISTINCT r, sourceId, targetId, relType
|
|
228
228
|
`;
|
|
229
229
|
}
|
|
230
230
|
const result = await session.run(query, { nodeId });
|
|
@@ -242,15 +242,15 @@ class Neo4jGraphStore {
|
|
|
242
242
|
const params = { nodeId };
|
|
243
243
|
if (edgeType) {
|
|
244
244
|
const relType = edgeType.toUpperCase();
|
|
245
|
-
query = `
|
|
246
|
-
MATCH (n:CodeNode {id: $nodeId})-[:${relType}]-(neighbor)
|
|
247
|
-
RETURN DISTINCT neighbor
|
|
245
|
+
query = `
|
|
246
|
+
MATCH (n:CodeNode {id: $nodeId})-[:${relType}]-(neighbor)
|
|
247
|
+
RETURN DISTINCT neighbor
|
|
248
248
|
`;
|
|
249
249
|
}
|
|
250
250
|
else {
|
|
251
|
-
query = `
|
|
252
|
-
MATCH (n:CodeNode {id: $nodeId})--(neighbor)
|
|
253
|
-
RETURN DISTINCT neighbor
|
|
251
|
+
query = `
|
|
252
|
+
MATCH (n:CodeNode {id: $nodeId})--(neighbor)
|
|
253
|
+
RETURN DISTINCT neighbor
|
|
254
254
|
`;
|
|
255
255
|
}
|
|
256
256
|
const result = await session.run(query, params);
|
|
@@ -264,11 +264,11 @@ class Neo4jGraphStore {
|
|
|
264
264
|
await this.initialize();
|
|
265
265
|
const session = this.driver.session({ database: this.database });
|
|
266
266
|
try {
|
|
267
|
-
const result = await session.run(`
|
|
268
|
-
MATCH path = shortestPath(
|
|
269
|
-
(source:CodeNode {id: $sourceId})-[*1..${maxDepth}]-(target:CodeNode {id: $targetId})
|
|
270
|
-
)
|
|
271
|
-
RETURN nodes(path) as pathNodes
|
|
267
|
+
const result = await session.run(`
|
|
268
|
+
MATCH path = shortestPath(
|
|
269
|
+
(source:CodeNode {id: $sourceId})-[*1..${maxDepth}]-(target:CodeNode {id: $targetId})
|
|
270
|
+
)
|
|
271
|
+
RETURN nodes(path) as pathNodes
|
|
272
272
|
`, { sourceId, targetId });
|
|
273
273
|
if (result.records.length === 0)
|
|
274
274
|
return [];
|
|
@@ -283,10 +283,10 @@ class Neo4jGraphStore {
|
|
|
283
283
|
await this.initialize();
|
|
284
284
|
const session = this.driver.session({ database: this.database });
|
|
285
285
|
try {
|
|
286
|
-
const result = await session.run(`
|
|
287
|
-
MATCH (n:CodeNode {projectId: $projectId})
|
|
288
|
-
DETACH DELETE n
|
|
289
|
-
RETURN count(n) as deleted
|
|
286
|
+
const result = await session.run(`
|
|
287
|
+
MATCH (n:CodeNode {projectId: $projectId})
|
|
288
|
+
DETACH DELETE n
|
|
289
|
+
RETURN count(n) as deleted
|
|
290
290
|
`, { projectId });
|
|
291
291
|
return result.records[0]?.get('deleted')?.toNumber() || 0;
|
|
292
292
|
}
|
|
@@ -302,13 +302,13 @@ class Neo4jGraphStore {
|
|
|
302
302
|
try {
|
|
303
303
|
// Delete nodes that match any of the file paths
|
|
304
304
|
// Handles both filePath property and relativePath property
|
|
305
|
-
const result = await session.run(`
|
|
306
|
-
MATCH (n:CodeNode {projectId: $projectId})
|
|
307
|
-
WHERE n.filePath IN $filePaths
|
|
308
|
-
OR n.relativePath IN $filePaths
|
|
309
|
-
OR ANY(fp IN $filePaths WHERE n.id CONTAINS replace(replace(fp, '/', '-'), '\\\\', '-'))
|
|
310
|
-
DETACH DELETE n
|
|
311
|
-
RETURN count(n) as deleted
|
|
305
|
+
const result = await session.run(`
|
|
306
|
+
MATCH (n:CodeNode {projectId: $projectId})
|
|
307
|
+
WHERE n.filePath IN $filePaths
|
|
308
|
+
OR n.relativePath IN $filePaths
|
|
309
|
+
OR ANY(fp IN $filePaths WHERE n.id CONTAINS replace(replace(fp, '/', '-'), '\\\\', '-'))
|
|
310
|
+
DETACH DELETE n
|
|
311
|
+
RETURN count(n) as deleted
|
|
312
312
|
`, { projectId, filePaths });
|
|
313
313
|
return result.records[0]?.get('deleted')?.toNumber() || 0;
|
|
314
314
|
}
|
|
@@ -320,9 +320,9 @@ class Neo4jGraphStore {
|
|
|
320
320
|
await this.initialize();
|
|
321
321
|
const session = this.driver.session({ database: this.database });
|
|
322
322
|
try {
|
|
323
|
-
const result = await session.run(`
|
|
324
|
-
MATCH (n:CodeNode {projectId: $projectId})
|
|
325
|
-
RETURN count(n) as count
|
|
323
|
+
const result = await session.run(`
|
|
324
|
+
MATCH (n:CodeNode {projectId: $projectId})
|
|
325
|
+
RETURN count(n) as count
|
|
326
326
|
`, { projectId });
|
|
327
327
|
return result.records[0]?.get('count')?.toNumber() || 0;
|
|
328
328
|
}
|
|
@@ -41,31 +41,31 @@ class PostgresVectorStore {
|
|
|
41
41
|
// Check if pgvector extension is available
|
|
42
42
|
await client.query(`CREATE EXTENSION IF NOT EXISTS vector`);
|
|
43
43
|
// Create documents table with vector column
|
|
44
|
-
await client.query(`
|
|
45
|
-
CREATE TABLE IF NOT EXISTS vector_documents (
|
|
46
|
-
id TEXT PRIMARY KEY,
|
|
47
|
-
project_id TEXT NOT NULL,
|
|
48
|
-
file_path TEXT NOT NULL,
|
|
49
|
-
content TEXT NOT NULL,
|
|
50
|
-
embedding vector(1536),
|
|
51
|
-
metadata JSONB,
|
|
52
|
-
content_tsvector TSVECTOR GENERATED ALWAYS AS (
|
|
53
|
-
setweight(to_tsvector('english', file_path), 'A') ||
|
|
54
|
-
setweight(to_tsvector('english', content), 'B')
|
|
55
|
-
) STORED,
|
|
56
|
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
57
|
-
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
CREATE INDEX IF NOT EXISTS idx_vd_project ON vector_documents(project_id);
|
|
61
|
-
CREATE INDEX IF NOT EXISTS idx_vd_file ON vector_documents(file_path);
|
|
62
|
-
CREATE INDEX IF NOT EXISTS idx_vd_fts ON vector_documents USING GIN(content_tsvector);
|
|
44
|
+
await client.query(`
|
|
45
|
+
CREATE TABLE IF NOT EXISTS vector_documents (
|
|
46
|
+
id TEXT PRIMARY KEY,
|
|
47
|
+
project_id TEXT NOT NULL,
|
|
48
|
+
file_path TEXT NOT NULL,
|
|
49
|
+
content TEXT NOT NULL,
|
|
50
|
+
embedding vector(1536),
|
|
51
|
+
metadata JSONB,
|
|
52
|
+
content_tsvector TSVECTOR GENERATED ALWAYS AS (
|
|
53
|
+
setweight(to_tsvector('english', file_path), 'A') ||
|
|
54
|
+
setweight(to_tsvector('english', content), 'B')
|
|
55
|
+
) STORED,
|
|
56
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
57
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_vd_project ON vector_documents(project_id);
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_vd_file ON vector_documents(file_path);
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_vd_fts ON vector_documents USING GIN(content_tsvector);
|
|
63
63
|
`);
|
|
64
64
|
// Create vector index (IVFFlat for larger datasets)
|
|
65
|
-
await client.query(`
|
|
66
|
-
CREATE INDEX IF NOT EXISTS idx_vd_embedding ON vector_documents
|
|
67
|
-
USING ivfflat (embedding vector_cosine_ops)
|
|
68
|
-
WITH (lists = 100);
|
|
65
|
+
await client.query(`
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_vd_embedding ON vector_documents
|
|
67
|
+
USING ivfflat (embedding vector_cosine_ops)
|
|
68
|
+
WITH (lists = 100);
|
|
69
69
|
`).catch(() => {
|
|
70
70
|
// IVFFlat requires training data; fall back to HNSW or skip
|
|
71
71
|
console.log('Note: IVFFlat index creation skipped (requires more data)');
|
|
@@ -81,16 +81,16 @@ class PostgresVectorStore {
|
|
|
81
81
|
const embeddingStr = doc.embedding.length > 0
|
|
82
82
|
? `[${doc.embedding.join(',')}]`
|
|
83
83
|
: null;
|
|
84
|
-
await this.pool.query(`
|
|
85
|
-
INSERT INTO vector_documents (id, project_id, file_path, content, embedding, metadata, updated_at)
|
|
86
|
-
VALUES ($1, $2, $3, $4, $5::vector, $6, NOW())
|
|
87
|
-
ON CONFLICT (id) DO UPDATE SET
|
|
88
|
-
project_id = EXCLUDED.project_id,
|
|
89
|
-
file_path = EXCLUDED.file_path,
|
|
90
|
-
content = EXCLUDED.content,
|
|
91
|
-
embedding = EXCLUDED.embedding,
|
|
92
|
-
metadata = EXCLUDED.metadata,
|
|
93
|
-
updated_at = NOW()
|
|
84
|
+
await this.pool.query(`
|
|
85
|
+
INSERT INTO vector_documents (id, project_id, file_path, content, embedding, metadata, updated_at)
|
|
86
|
+
VALUES ($1, $2, $3, $4, $5::vector, $6, NOW())
|
|
87
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
88
|
+
project_id = EXCLUDED.project_id,
|
|
89
|
+
file_path = EXCLUDED.file_path,
|
|
90
|
+
content = EXCLUDED.content,
|
|
91
|
+
embedding = EXCLUDED.embedding,
|
|
92
|
+
metadata = EXCLUDED.metadata,
|
|
93
|
+
updated_at = NOW()
|
|
94
94
|
`, [
|
|
95
95
|
doc.id,
|
|
96
96
|
doc.projectId,
|
|
@@ -109,16 +109,16 @@ class PostgresVectorStore {
|
|
|
109
109
|
const embeddingStr = doc.embedding.length > 0
|
|
110
110
|
? `[${doc.embedding.join(',')}]`
|
|
111
111
|
: null;
|
|
112
|
-
await client.query(`
|
|
113
|
-
INSERT INTO vector_documents (id, project_id, file_path, content, embedding, metadata, updated_at)
|
|
114
|
-
VALUES ($1, $2, $3, $4, $5::vector, $6, NOW())
|
|
115
|
-
ON CONFLICT (id) DO UPDATE SET
|
|
116
|
-
project_id = EXCLUDED.project_id,
|
|
117
|
-
file_path = EXCLUDED.file_path,
|
|
118
|
-
content = EXCLUDED.content,
|
|
119
|
-
embedding = EXCLUDED.embedding,
|
|
120
|
-
metadata = EXCLUDED.metadata,
|
|
121
|
-
updated_at = NOW()
|
|
112
|
+
await client.query(`
|
|
113
|
+
INSERT INTO vector_documents (id, project_id, file_path, content, embedding, metadata, updated_at)
|
|
114
|
+
VALUES ($1, $2, $3, $4, $5::vector, $6, NOW())
|
|
115
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
116
|
+
project_id = EXCLUDED.project_id,
|
|
117
|
+
file_path = EXCLUDED.file_path,
|
|
118
|
+
content = EXCLUDED.content,
|
|
119
|
+
embedding = EXCLUDED.embedding,
|
|
120
|
+
metadata = EXCLUDED.metadata,
|
|
121
|
+
updated_at = NOW()
|
|
122
122
|
`, [
|
|
123
123
|
doc.id,
|
|
124
124
|
doc.projectId,
|
|
@@ -143,14 +143,14 @@ class PostgresVectorStore {
|
|
|
143
143
|
if (embedding.length === 0)
|
|
144
144
|
return [];
|
|
145
145
|
const embeddingStr = `[${embedding.join(',')}]`;
|
|
146
|
-
const result = await this.pool.query(`
|
|
147
|
-
SELECT
|
|
148
|
-
id, project_id, file_path, content, metadata, created_at, updated_at,
|
|
149
|
-
1 - (embedding <=> $1::vector) as similarity
|
|
150
|
-
FROM vector_documents
|
|
151
|
-
WHERE project_id = $2 AND embedding IS NOT NULL
|
|
152
|
-
ORDER BY embedding <=> $1::vector
|
|
153
|
-
LIMIT $3
|
|
146
|
+
const result = await this.pool.query(`
|
|
147
|
+
SELECT
|
|
148
|
+
id, project_id, file_path, content, metadata, created_at, updated_at,
|
|
149
|
+
1 - (embedding <=> $1::vector) as similarity
|
|
150
|
+
FROM vector_documents
|
|
151
|
+
WHERE project_id = $2 AND embedding IS NOT NULL
|
|
152
|
+
ORDER BY embedding <=> $1::vector
|
|
153
|
+
LIMIT $3
|
|
154
154
|
`, [embeddingStr, projectId, limit]);
|
|
155
155
|
return result.rows.map(row => ({
|
|
156
156
|
document: this.rowToDocument(row),
|
|
@@ -167,15 +167,15 @@ class PostgresVectorStore {
|
|
|
167
167
|
.join(' | ');
|
|
168
168
|
if (!tsQuery)
|
|
169
169
|
return [];
|
|
170
|
-
const result = await this.pool.query(`
|
|
171
|
-
SELECT
|
|
172
|
-
id, project_id, file_path, content, metadata, created_at, updated_at,
|
|
173
|
-
ts_rank_cd(content_tsvector, to_tsquery('english', $1)) as rank
|
|
174
|
-
FROM vector_documents
|
|
175
|
-
WHERE project_id = $2
|
|
176
|
-
AND content_tsvector @@ to_tsquery('english', $1)
|
|
177
|
-
ORDER BY rank DESC
|
|
178
|
-
LIMIT $3
|
|
170
|
+
const result = await this.pool.query(`
|
|
171
|
+
SELECT
|
|
172
|
+
id, project_id, file_path, content, metadata, created_at, updated_at,
|
|
173
|
+
ts_rank_cd(content_tsvector, to_tsquery('english', $1)) as rank
|
|
174
|
+
FROM vector_documents
|
|
175
|
+
WHERE project_id = $2
|
|
176
|
+
AND content_tsvector @@ to_tsquery('english', $1)
|
|
177
|
+
ORDER BY rank DESC
|
|
178
|
+
LIMIT $3
|
|
179
179
|
`, [tsQuery, projectId, limit]);
|
|
180
180
|
return result.rows.map(row => ({
|
|
181
181
|
document: this.rowToDocument(row),
|
|
@@ -251,9 +251,9 @@ class PostgresVectorStore {
|
|
|
251
251
|
}
|
|
252
252
|
async getFileHashes(projectId) {
|
|
253
253
|
await this.initialize();
|
|
254
|
-
const result = await this.pool.query(`SELECT DISTINCT ON (file_path) file_path, metadata
|
|
255
|
-
FROM vector_documents
|
|
256
|
-
WHERE project_id = $1 AND metadata IS NOT NULL
|
|
254
|
+
const result = await this.pool.query(`SELECT DISTINCT ON (file_path) file_path, metadata
|
|
255
|
+
FROM vector_documents
|
|
256
|
+
WHERE project_id = $1 AND metadata IS NOT NULL
|
|
257
257
|
ORDER BY file_path`, [projectId]);
|
|
258
258
|
const hashes = new Map();
|
|
259
259
|
for (const row of result.rows) {
|
|
@@ -279,8 +279,8 @@ class PostgresVectorStore {
|
|
|
279
279
|
async getFileMetadata(projectId, filePath) {
|
|
280
280
|
await this.initialize();
|
|
281
281
|
// Fast indexed query to get file metadata from first chunk
|
|
282
|
-
const result = await this.pool.query(`SELECT metadata FROM vector_documents
|
|
283
|
-
WHERE project_id = $1 AND file_path = $2
|
|
282
|
+
const result = await this.pool.query(`SELECT metadata FROM vector_documents
|
|
283
|
+
WHERE project_id = $1 AND file_path = $2
|
|
284
284
|
LIMIT 1`, [projectId, filePath]);
|
|
285
285
|
if (result.rows.length === 0 || !result.rows[0].metadata) {
|
|
286
286
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeseeker",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.3",
|
|
4
4
|
"description": "Graph-powered code intelligence for Claude Code. Semantic search + knowledge graph for better AI code understanding.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -134,6 +134,7 @@
|
|
|
134
134
|
"files": [
|
|
135
135
|
"bin/",
|
|
136
136
|
"dist/",
|
|
137
|
+
"scripts/postinstall.js",
|
|
137
138
|
"README.md",
|
|
138
139
|
"LICENSE"
|
|
139
140
|
],
|
|
@@ -147,5 +148,6 @@
|
|
|
147
148
|
"homepage": "https://github.com/jghiringhelli/codeseeker#readme",
|
|
148
149
|
"publishConfig": {
|
|
149
150
|
"access": "public"
|
|
150
|
-
}
|
|
151
|
+
},
|
|
152
|
+
"mcpName": "io.github.jghiringhelli/codeseeker"
|
|
151
153
|
}
|