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.
@@ -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.1",
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
  }