@mhalder/qdrant-mcp-server 3.3.3 → 3.3.4

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.
Files changed (168) hide show
  1. package/.github/workflows/ci.yml +0 -2
  2. package/.github/workflows/claude-code-review.yml +1 -1
  3. package/CHANGELOG.md +6 -0
  4. package/README.md +1 -1
  5. package/biome.json +3 -2
  6. package/build/code/chunker/tree-sitter-chunker.d.ts.map +1 -1
  7. package/build/code/chunker/tree-sitter-chunker.js +2 -12
  8. package/build/code/chunker/tree-sitter-chunker.js.map +1 -1
  9. package/build/code/indexer.d.ts.map +1 -1
  10. package/build/code/indexer.js +12 -18
  11. package/build/code/indexer.js.map +1 -1
  12. package/build/code/scanner.js +1 -1
  13. package/build/code/scanner.js.map +1 -1
  14. package/build/embeddings/cohere.d.ts +1 -1
  15. package/build/embeddings/cohere.d.ts.map +1 -1
  16. package/build/embeddings/cohere.js +2 -2
  17. package/build/embeddings/cohere.js.map +1 -1
  18. package/build/embeddings/cohere.test.js +1 -5
  19. package/build/embeddings/cohere.test.js.map +1 -1
  20. package/build/embeddings/factory.d.ts +1 -1
  21. package/build/embeddings/factory.d.ts.map +1 -1
  22. package/build/embeddings/factory.js +7 -9
  23. package/build/embeddings/factory.js.map +1 -1
  24. package/build/embeddings/factory.test.js +3 -3
  25. package/build/embeddings/factory.test.js.map +1 -1
  26. package/build/embeddings/ollama.d.ts +1 -1
  27. package/build/embeddings/ollama.d.ts.map +1 -1
  28. package/build/embeddings/ollama.js +6 -8
  29. package/build/embeddings/ollama.js.map +1 -1
  30. package/build/embeddings/ollama.test.js +2 -6
  31. package/build/embeddings/ollama.test.js.map +1 -1
  32. package/build/embeddings/openai.d.ts +1 -1
  33. package/build/embeddings/openai.d.ts.map +1 -1
  34. package/build/embeddings/openai.js +4 -7
  35. package/build/embeddings/openai.js.map +1 -1
  36. package/build/embeddings/openai.test.js +3 -12
  37. package/build/embeddings/openai.test.js.map +1 -1
  38. package/build/embeddings/sparse.test.js +12 -2
  39. package/build/embeddings/sparse.test.js.map +1 -1
  40. package/build/embeddings/voyage.d.ts +1 -1
  41. package/build/embeddings/voyage.d.ts.map +1 -1
  42. package/build/embeddings/voyage.js +2 -3
  43. package/build/embeddings/voyage.js.map +1 -1
  44. package/build/embeddings/voyage.test.js +2 -6
  45. package/build/embeddings/voyage.test.js.map +1 -1
  46. package/build/git/chunker.d.ts.map +1 -1
  47. package/build/git/chunker.js +2 -2
  48. package/build/git/chunker.js.map +1 -1
  49. package/build/git/chunker.test.js +1 -1
  50. package/build/git/chunker.test.js.map +1 -1
  51. package/build/git/extractor.d.ts.map +1 -1
  52. package/build/git/extractor.integration.test.js +9 -5
  53. package/build/git/extractor.integration.test.js.map +1 -1
  54. package/build/git/extractor.js +1 -1
  55. package/build/git/extractor.js.map +1 -1
  56. package/build/git/extractor.test.js +2 -2
  57. package/build/git/extractor.test.js.map +1 -1
  58. package/build/git/index.d.ts +4 -4
  59. package/build/git/index.d.ts.map +1 -1
  60. package/build/git/index.js +3 -3
  61. package/build/git/index.js.map +1 -1
  62. package/build/git/indexer.d.ts.map +1 -1
  63. package/build/git/indexer.js +9 -21
  64. package/build/git/indexer.js.map +1 -1
  65. package/build/git/indexer.test.js +4 -8
  66. package/build/git/indexer.test.js.map +1 -1
  67. package/build/git/sync/synchronizer.d.ts.map +1 -1
  68. package/build/git/sync/synchronizer.js.map +1 -1
  69. package/build/git/sync/synchronizer.test.js +4 -2
  70. package/build/git/sync/synchronizer.test.js.map +1 -1
  71. package/build/index.js +5 -9
  72. package/build/index.js.map +1 -1
  73. package/build/index.test.js +3 -3
  74. package/build/index.test.js.map +1 -1
  75. package/build/logger.d.ts.map +1 -1
  76. package/build/logger.js +1 -9
  77. package/build/logger.js.map +1 -1
  78. package/build/prompts/register.d.ts.map +1 -1
  79. package/build/prompts/register.js.map +1 -1
  80. package/build/qdrant/client.d.ts.map +1 -1
  81. package/build/qdrant/client.js.map +1 -1
  82. package/build/qdrant/client.test.js +10 -34
  83. package/build/qdrant/client.test.js.map +1 -1
  84. package/build/resources/index.d.ts +1 -1
  85. package/build/resources/index.d.ts.map +1 -1
  86. package/build/resources/index.js +1 -1
  87. package/build/resources/index.js.map +1 -1
  88. package/build/tools/code.d.ts.map +1 -1
  89. package/build/tools/code.js +3 -9
  90. package/build/tools/code.js.map +1 -1
  91. package/build/tools/collection.d.ts.map +1 -1
  92. package/build/tools/collection.js +1 -3
  93. package/build/tools/collection.js.map +1 -1
  94. package/build/tools/document.d.ts.map +1 -1
  95. package/build/tools/document.js +1 -1
  96. package/build/tools/document.js.map +1 -1
  97. package/build/tools/federated.d.ts.map +1 -1
  98. package/build/tools/federated.js +15 -6
  99. package/build/tools/federated.js.map +1 -1
  100. package/build/tools/federated.test.js +18 -22
  101. package/build/tools/federated.test.js.map +1 -1
  102. package/build/tools/git-history.d.ts.map +1 -1
  103. package/build/tools/git-history.js +3 -7
  104. package/build/tools/git-history.js.map +1 -1
  105. package/build/tools/index.d.ts.map +1 -1
  106. package/build/tools/index.js.map +1 -1
  107. package/build/tools/logging.d.ts.map +1 -1
  108. package/build/tools/logging.js +1 -3
  109. package/build/tools/logging.js.map +1 -1
  110. package/build/tools/logging.test.js +1 -1
  111. package/build/tools/logging.test.js.map +1 -1
  112. package/build/tools/schemas.d.ts.map +1 -1
  113. package/build/tools/schemas.js +17 -64
  114. package/build/tools/schemas.js.map +1 -1
  115. package/build/tools/search.d.ts.map +1 -1
  116. package/build/tools/search.js +1 -1
  117. package/build/tools/search.js.map +1 -1
  118. package/commitlint.config.js +12 -23
  119. package/package.json +1 -1
  120. package/scripts/verify-providers.js +12 -32
  121. package/src/code/chunker/tree-sitter-chunker.ts +9 -35
  122. package/src/code/indexer.ts +45 -107
  123. package/src/code/scanner.ts +1 -1
  124. package/src/embeddings/cohere.test.ts +17 -45
  125. package/src/embeddings/cohere.ts +10 -17
  126. package/src/embeddings/factory.test.ts +18 -18
  127. package/src/embeddings/factory.ts +18 -25
  128. package/src/embeddings/ollama.test.ts +38 -67
  129. package/src/embeddings/ollama.ts +15 -27
  130. package/src/embeddings/openai.test.ts +17 -53
  131. package/src/embeddings/openai.ts +11 -22
  132. package/src/embeddings/sparse.test.ts +12 -2
  133. package/src/embeddings/voyage.test.ts +39 -80
  134. package/src/embeddings/voyage.ts +9 -13
  135. package/src/git/chunker.test.ts +1 -1
  136. package/src/git/chunker.ts +6 -22
  137. package/src/git/extractor.integration.test.ts +12 -16
  138. package/src/git/extractor.test.ts +21 -35
  139. package/src/git/extractor.ts +14 -36
  140. package/src/git/index.ts +9 -10
  141. package/src/git/indexer.test.ts +29 -57
  142. package/src/git/indexer.ts +38 -86
  143. package/src/git/sync/synchronizer.test.ts +6 -9
  144. package/src/git/sync/synchronizer.ts +2 -5
  145. package/src/index.test.ts +7 -9
  146. package/src/index.ts +34 -80
  147. package/src/logger.ts +3 -14
  148. package/src/prompts/register.ts +3 -10
  149. package/src/qdrant/client.test.ts +63 -169
  150. package/src/qdrant/client.ts +19 -45
  151. package/src/resources/index.ts +4 -10
  152. package/src/tools/code.ts +43 -66
  153. package/src/tools/collection.ts +19 -38
  154. package/src/tools/document.ts +10 -19
  155. package/src/tools/federated.test.ts +34 -57
  156. package/src/tools/federated.ts +88 -108
  157. package/src/tools/git-history.ts +32 -60
  158. package/src/tools/index.ts +1 -4
  159. package/src/tools/logging.test.ts +10 -10
  160. package/src/tools/logging.ts +8 -18
  161. package/src/tools/schemas.ts +23 -78
  162. package/src/tools/search.ts +77 -94
  163. package/tests/code/chunker/tree-sitter-chunker.test.ts +6 -19
  164. package/tests/code/indexer.test.ts +100 -192
  165. package/tests/code/integration.test.ts +61 -117
  166. package/tests/code/scanner.test.ts +12 -39
  167. package/tests/code/sync/snapshot.test.ts +4 -14
  168. package/tests/code/sync/synchronizer.test.ts +10 -40
@@ -5,9 +5,9 @@
5
5
  import { createHash } from "node:crypto";
6
6
  import { promises as fs } from "node:fs";
7
7
  import { resolve } from "node:path";
8
- import logger from "../logger.js";
9
8
  import type { EmbeddingProvider } from "../embeddings/base.js";
10
9
  import { BM25SparseVectorGenerator } from "../embeddings/sparse.js";
10
+ import logger from "../logger.js";
11
11
  import type { QdrantManager } from "../qdrant/client.js";
12
12
  import { CommitChunker } from "./chunker.js";
13
13
  import { GIT_INDEXING_METADATA_ID } from "./config.js";
@@ -31,7 +31,7 @@ export class GitHistoryIndexer {
31
31
  constructor(
32
32
  private qdrant: QdrantManager,
33
33
  private embeddings: EmbeddingProvider,
34
- private config: GitConfig,
34
+ private config: GitConfig
35
35
  ) {}
36
36
 
37
37
  /**
@@ -54,7 +54,7 @@ export class GitHistoryIndexer {
54
54
  async indexHistory(
55
55
  path: string,
56
56
  options?: GitIndexOptions,
57
- progressCallback?: GitProgressCallback,
57
+ progressCallback?: GitProgressCallback
58
58
  ): Promise<GitIndexStats> {
59
59
  const startTime = Date.now();
60
60
  const stats: GitIndexStats = {
@@ -69,10 +69,7 @@ export class GitHistoryIndexer {
69
69
  const absolutePath = await this.validatePath(path);
70
70
  const collectionName = await this.getCollectionName(absolutePath);
71
71
 
72
- this.log.info(
73
- { path: absolutePath, collectionName },
74
- "Git indexing started",
75
- );
72
+ this.log.info({ path: absolutePath, collectionName }, "Git indexing started");
76
73
 
77
74
  try {
78
75
  // 1. Validate repository
@@ -92,8 +89,7 @@ export class GitHistoryIndexer {
92
89
  }
93
90
 
94
91
  // 2. Create or verify collection
95
- const collectionExists =
96
- await this.qdrant.collectionExists(collectionName);
92
+ const collectionExists = await this.qdrant.collectionExists(collectionName);
97
93
 
98
94
  if (options?.forceReindex && collectionExists) {
99
95
  await this.qdrant.deleteCollection(collectionName);
@@ -105,7 +101,7 @@ export class GitHistoryIndexer {
105
101
  collectionName,
106
102
  vectorSize,
107
103
  "Cosine",
108
- this.config.enableHybridSearch,
104
+ this.config.enableHybridSearch
109
105
  );
110
106
  }
111
107
 
@@ -165,11 +161,8 @@ export class GitHistoryIndexer {
165
161
 
166
162
  stats.commitsIndexed++;
167
163
  } catch (error) {
168
- const errorMessage =
169
- error instanceof Error ? error.message : String(error);
170
- stats.errors?.push(
171
- `Failed to process commit ${commit.shortHash}: ${errorMessage}`,
172
- );
164
+ const errorMessage = error instanceof Error ? error.message : String(error);
165
+ stats.errors?.push(`Failed to process commit ${commit.shortHash}: ${errorMessage}`);
173
166
  }
174
167
  }
175
168
 
@@ -184,10 +177,7 @@ export class GitHistoryIndexer {
184
177
 
185
178
  // 5. Generate embeddings and store in batches
186
179
  const batchSize = this.config.batchSize;
187
- this.log.debug(
188
- { totalChunks: allChunks.length, batchSize },
189
- "Starting embedding generation",
190
- );
180
+ this.log.debug({ totalChunks: allChunks.length, batchSize }, "Starting embedding generation");
191
181
  for (let i = 0; i < allChunks.length; i += batchSize) {
192
182
  const batch = allChunks.slice(i, i + batchSize);
193
183
 
@@ -195,8 +185,7 @@ export class GitHistoryIndexer {
195
185
  phase: "embedding",
196
186
  current: i + batch.length,
197
187
  total: allChunks.length,
198
- percentage:
199
- 40 + Math.round(((i + batch.length) / allChunks.length) * 30),
188
+ percentage: 40 + Math.round(((i + batch.length) / allChunks.length) * 30),
200
189
  message: `Generating embeddings ${i + batch.length}/${allChunks.length}`,
201
190
  });
202
191
 
@@ -204,11 +193,7 @@ export class GitHistoryIndexer {
204
193
  let lastError: Error | null = null;
205
194
  let success = false;
206
195
 
207
- for (
208
- let attempt = 1;
209
- attempt <= this.config.batchRetryAttempts;
210
- attempt++
211
- ) {
196
+ for (let attempt = 1; attempt <= this.config.batchRetryAttempts; attempt++) {
212
197
  try {
213
198
  const texts = batch.map((b) => b.chunk.content);
214
199
  const embeddings = await this.embeddings.embedBatch(texts);
@@ -217,8 +202,7 @@ export class GitHistoryIndexer {
217
202
  phase: "storing",
218
203
  current: i + batch.length,
219
204
  total: allChunks.length,
220
- percentage:
221
- 70 + Math.round(((i + batch.length) / allChunks.length) * 30),
205
+ percentage: 70 + Math.round(((i + batch.length) / allChunks.length) * 30),
222
206
  message: `Storing chunks ${i + batch.length}/${allChunks.length}`,
223
207
  });
224
208
 
@@ -245,14 +229,9 @@ export class GitHistoryIndexer {
245
229
  const sparseGenerator = new BM25SparseVectorGenerator();
246
230
  const hybridPoints = points.map((point, idx) => ({
247
231
  ...point,
248
- sparseVector: sparseGenerator.generate(
249
- batch[idx].chunk.content,
250
- ),
232
+ sparseVector: sparseGenerator.generate(batch[idx].chunk.content),
251
233
  }));
252
- await this.qdrant.addPointsWithSparse(
253
- collectionName,
254
- hybridPoints,
255
- );
234
+ await this.qdrant.addPointsWithSparse(collectionName, hybridPoints);
256
235
  } else {
257
236
  await this.qdrant.addPoints(collectionName, points);
258
237
  }
@@ -260,11 +239,10 @@ export class GitHistoryIndexer {
260
239
  success = true;
261
240
  break;
262
241
  } catch (error) {
263
- lastError =
264
- error instanceof Error ? error : new Error(String(error));
242
+ lastError = error instanceof Error ? error : new Error(String(error));
265
243
  if (attempt < this.config.batchRetryAttempts) {
266
244
  // Exponential backoff: 1s, 2s, 4s...
267
- const delay = Math.pow(2, attempt - 1) * 1000;
245
+ const delay = 2 ** (attempt - 1) * 1000;
268
246
  await new Promise((resolve) => setTimeout(resolve, delay));
269
247
  }
270
248
  }
@@ -272,7 +250,7 @@ export class GitHistoryIndexer {
272
250
 
273
251
  if (!success && lastError) {
274
252
  stats.errors?.push(
275
- `Failed to process batch at index ${i} after ${this.config.batchRetryAttempts} attempts: ${lastError.message}`,
253
+ `Failed to process batch at index ${i} after ${this.config.batchRetryAttempts} attempts: ${lastError.message}`
276
254
  );
277
255
  stats.status = "partial";
278
256
  }
@@ -284,8 +262,7 @@ export class GitHistoryIndexer {
284
262
  const synchronizer = new GitSynchronizer(absolutePath, collectionName);
285
263
  await synchronizer.updateSnapshot(latestHash, stats.commitsIndexed);
286
264
  } catch (error) {
287
- const errorMessage =
288
- error instanceof Error ? error.message : String(error);
265
+ const errorMessage = error instanceof Error ? error.message : String(error);
289
266
  this.log.error({ err: error }, "Failed to save snapshot");
290
267
  stats.errors?.push(`Snapshot save failed: ${errorMessage}`);
291
268
  }
@@ -300,12 +277,11 @@ export class GitHistoryIndexer {
300
277
  chunksCreated: stats.chunksCreated,
301
278
  durationMs: stats.durationMs,
302
279
  },
303
- "Git indexing complete",
280
+ "Git indexing complete"
304
281
  );
305
282
  return stats;
306
283
  } catch (error) {
307
- const errorMessage =
308
- error instanceof Error ? error.message : String(error);
284
+ const errorMessage = error instanceof Error ? error.message : String(error);
309
285
  stats.status = "failed";
310
286
  stats.errors?.push(`Indexing failed: ${errorMessage}`);
311
287
  stats.durationMs = Date.now() - startTime;
@@ -319,7 +295,7 @@ export class GitHistoryIndexer {
319
295
  async searchHistory(
320
296
  path: string,
321
297
  query: string,
322
- options?: GitSearchOptions,
298
+ options?: GitSearchOptions
323
299
  ): Promise<GitSearchResult[]> {
324
300
  // Validate date range if both dates are provided
325
301
  if (options?.dateFrom && options?.dateTo) {
@@ -327,7 +303,7 @@ export class GitHistoryIndexer {
327
303
  const toDate = new Date(options.dateTo);
328
304
  if (fromDate > toDate) {
329
305
  throw new Error(
330
- `Invalid date range: dateFrom (${options.dateFrom}) must be before dateTo (${options.dateTo})`,
306
+ `Invalid date range: dateFrom (${options.dateFrom}) must be before dateTo (${options.dateTo})`
331
307
  );
332
308
  }
333
309
  }
@@ -344,8 +320,7 @@ export class GitHistoryIndexer {
344
320
  // Check if collection has hybrid search enabled
345
321
  const collectionInfo = await this.qdrant.getCollectionInfo(collectionName);
346
322
  const useHybrid =
347
- (options?.useHybrid ?? this.config.enableHybridSearch) &&
348
- collectionInfo.hybridEnabled;
323
+ (options?.useHybrid ?? this.config.enableHybridSearch) && collectionInfo.hybridEnabled;
349
324
 
350
325
  // Generate query embedding
351
326
  const { embedding } = await this.embeddings.embed(query);
@@ -363,14 +338,14 @@ export class GitHistoryIndexer {
363
338
  embedding,
364
339
  sparseVector,
365
340
  options?.limit || this.config.defaultSearchLimit,
366
- filter,
341
+ filter
367
342
  );
368
343
  } else {
369
344
  results = await this.qdrant.search(
370
345
  collectionName,
371
346
  embedding,
372
347
  options?.limit || this.config.defaultSearchLimit,
373
- filter,
348
+ filter
374
349
  );
375
350
  }
376
351
 
@@ -406,19 +381,14 @@ export class GitHistoryIndexer {
406
381
  }
407
382
 
408
383
  // Check for indexing marker
409
- const indexingMarker = await this.qdrant.getPoint(
410
- collectionName,
411
- GIT_INDEXING_METADATA_ID,
412
- );
384
+ const indexingMarker = await this.qdrant.getPoint(collectionName, GIT_INDEXING_METADATA_ID);
413
385
  const info = await this.qdrant.getCollectionInfo(collectionName);
414
386
 
415
387
  const isComplete = indexingMarker?.payload?.indexingComplete === true;
416
388
  const isInProgress = indexingMarker?.payload?.indexingComplete === false;
417
389
 
418
390
  // Subtract 1 from points count if marker exists
419
- const actualChunksCount = indexingMarker
420
- ? Math.max(0, info.pointsCount - 1)
421
- : info.pointsCount;
391
+ const actualChunksCount = indexingMarker ? Math.max(0, info.pointsCount - 1) : info.pointsCount;
422
392
 
423
393
  // Load snapshot for additional info
424
394
  const synchronizer = new GitSynchronizer(absolutePath, collectionName);
@@ -439,12 +409,8 @@ export class GitHistoryIndexer {
439
409
  status: "indexed",
440
410
  collectionName,
441
411
  chunksCount: actualChunksCount,
442
- commitsCount: hasSnapshot
443
- ? synchronizer.getCommitsIndexed()
444
- : undefined,
445
- lastCommitHash: hasSnapshot
446
- ? (synchronizer.getLastCommitHash() ?? undefined)
447
- : undefined,
412
+ commitsCount: hasSnapshot ? synchronizer.getCommitsIndexed() : undefined,
413
+ lastCommitHash: hasSnapshot ? (synchronizer.getLastCommitHash() ?? undefined) : undefined,
448
414
  lastIndexedAt: hasSnapshot
449
415
  ? (synchronizer.getLastIndexedAt() ?? undefined)
450
416
  : indexingMarker?.payload?.completedAt
@@ -460,12 +426,8 @@ export class GitHistoryIndexer {
460
426
  status: "indexed",
461
427
  collectionName,
462
428
  chunksCount: actualChunksCount,
463
- commitsCount: hasSnapshot
464
- ? synchronizer.getCommitsIndexed()
465
- : undefined,
466
- lastCommitHash: hasSnapshot
467
- ? (synchronizer.getLastCommitHash() ?? undefined)
468
- : undefined,
429
+ commitsCount: hasSnapshot ? synchronizer.getCommitsIndexed() : undefined,
430
+ lastCommitHash: hasSnapshot ? (synchronizer.getLastCommitHash() ?? undefined) : undefined,
469
431
  };
470
432
  }
471
433
 
@@ -482,7 +444,7 @@ export class GitHistoryIndexer {
482
444
  */
483
445
  async indexNewCommits(
484
446
  path: string,
485
- progressCallback?: GitProgressCallback,
447
+ progressCallback?: GitProgressCallback
486
448
  ): Promise<GitChangeStats> {
487
449
  const startTime = Date.now();
488
450
  const stats: GitChangeStats = {
@@ -497,9 +459,7 @@ export class GitHistoryIndexer {
497
459
  // Check if collection exists
498
460
  const exists = await this.qdrant.collectionExists(collectionName);
499
461
  if (!exists) {
500
- throw new Error(
501
- `Git history not indexed: ${path}. Use index_git_history first.`,
502
- );
462
+ throw new Error(`Git history not indexed: ${path}. Use index_git_history first.`);
503
463
  }
504
464
 
505
465
  // Initialize synchronizer
@@ -507,9 +467,7 @@ export class GitHistoryIndexer {
507
467
  const hasSnapshot = await synchronizer.initialize();
508
468
 
509
469
  if (!hasSnapshot) {
510
- throw new Error(
511
- "No previous snapshot found. Use index_git_history for initial indexing.",
512
- );
470
+ throw new Error("No previous snapshot found. Use index_git_history for initial indexing.");
513
471
  }
514
472
 
515
473
  const lastCommitHash = synchronizer.getLastCommitHash();
@@ -576,8 +534,7 @@ export class GitHistoryIndexer {
576
534
  phase: "embedding",
577
535
  current: i + batch.length,
578
536
  total: allChunks.length,
579
- percentage:
580
- 40 + Math.round(((i + batch.length) / allChunks.length) * 30),
537
+ percentage: 40 + Math.round(((i + batch.length) / allChunks.length) * 30),
581
538
  message: `Generating embeddings ${i + batch.length}/${allChunks.length}`,
582
539
  });
583
540
 
@@ -588,8 +545,7 @@ export class GitHistoryIndexer {
588
545
  phase: "storing",
589
546
  current: i + batch.length,
590
547
  total: allChunks.length,
591
- percentage:
592
- 70 + Math.round(((i + batch.length) / allChunks.length) * 30),
548
+ percentage: 70 + Math.round(((i + batch.length) / allChunks.length) * 30),
593
549
  message: `Storing chunks ${i + batch.length}/${allChunks.length}`,
594
550
  });
595
551
 
@@ -658,16 +614,12 @@ export class GitHistoryIndexer {
658
614
  /**
659
615
  * Store indexing status marker in the collection
660
616
  */
661
- private async storeIndexingMarker(
662
- collectionName: string,
663
- complete: boolean,
664
- ): Promise<void> {
617
+ private async storeIndexingMarker(collectionName: string, complete: boolean): Promise<void> {
665
618
  try {
666
619
  const vectorSize = this.embeddings.getDimensions();
667
620
  const zeroVector = new Array(vectorSize).fill(0);
668
621
 
669
- const collectionInfo =
670
- await this.qdrant.getCollectionInfo(collectionName);
622
+ const collectionInfo = await this.qdrant.getCollectionInfo(collectionName);
671
623
 
672
624
  const payload = {
673
625
  _type: "git_indexing_metadata",
@@ -1,4 +1,4 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
2
  import { GitSynchronizer } from "./synchronizer.js";
3
3
 
4
4
  // Mock fs module
@@ -51,9 +51,7 @@ describe("GitSynchronizer", () => {
51
51
  });
52
52
 
53
53
  it("should return false when snapshot does not exist", async () => {
54
- vi.mocked(fs.readFile).mockRejectedValue(
55
- new Error("ENOENT: no such file"),
56
- );
54
+ vi.mocked(fs.readFile).mockRejectedValue(new Error("ENOENT: no such file"));
57
55
 
58
56
  const result = await synchronizer.initialize();
59
57
 
@@ -157,14 +155,13 @@ describe("GitSynchronizer", () => {
157
155
 
158
156
  await synchronizer.updateSnapshot("def456", 200);
159
157
 
160
- expect(fs.mkdir).toHaveBeenCalledWith(
161
- expect.stringContaining("git-snapshots"),
162
- { recursive: true },
163
- );
158
+ expect(fs.mkdir).toHaveBeenCalledWith(expect.stringContaining("git-snapshots"), {
159
+ recursive: true,
160
+ });
164
161
  // Check the file was written with correct data (JSON may be formatted)
165
162
  expect(fs.writeFile).toHaveBeenCalledWith(
166
163
  expect.stringContaining(".tmp"),
167
- expect.stringMatching(/lastCommitHash.*def456/s),
164
+ expect.stringMatching(/lastCommitHash.*def456/s)
168
165
  );
169
166
  expect(fs.rename).toHaveBeenCalled();
170
167
 
@@ -13,7 +13,7 @@ export class GitSynchronizer {
13
13
 
14
14
  constructor(
15
15
  private repoPath: string,
16
- collectionName: string,
16
+ collectionName: string
17
17
  ) {
18
18
  // Store snapshots in ~/.qdrant-mcp/git-snapshots/
19
19
  const snapshotDir = join(homedir(), ".qdrant-mcp", "git-snapshots");
@@ -67,10 +67,7 @@ export class GitSynchronizer {
67
67
  /**
68
68
  * Update snapshot with new indexing state
69
69
  */
70
- async updateSnapshot(
71
- lastCommitHash: string,
72
- commitsIndexed: number,
73
- ): Promise<void> {
70
+ async updateSnapshot(lastCommitHash: string, commitsIndexed: number): Promise<void> {
74
71
  this.snapshot = {
75
72
  repoPath: this.repoPath,
76
73
  lastCommitHash,
package/src/index.test.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
1
+ import { describe, expect, it, vi } from "vitest";
2
2
 
3
3
  vi.mock("./qdrant/client.js");
4
4
  vi.mock("./embeddings/openai.js");
@@ -31,9 +31,7 @@ describe("MCP Server Tool Schemas", () => {
31
31
  name: "test-collection",
32
32
  distance: "Cosine" as const,
33
33
  };
34
- expect(() =>
35
- CreateCollectionSchema.parse(validInputWithDistance),
36
- ).not.toThrow();
34
+ expect(() => CreateCollectionSchema.parse(validInputWithDistance)).not.toThrow();
37
35
  });
38
36
 
39
37
  it("should reject invalid distance metric", async () => {
@@ -72,7 +70,7 @@ describe("MCP Server Tool Schemas", () => {
72
70
  id: z.union([z.string(), z.number()]),
73
71
  text: z.string(),
74
72
  metadata: z.record(z.string(), z.any()).optional(),
75
- }),
73
+ })
76
74
  ),
77
75
  });
78
76
 
@@ -97,7 +95,7 @@ describe("MCP Server Tool Schemas", () => {
97
95
  id: z.union([z.string(), z.number()]),
98
96
  text: z.string(),
99
97
  metadata: z.record(z.string(), z.any()).optional(),
100
- }),
98
+ })
101
99
  ),
102
100
  });
103
101
 
@@ -124,7 +122,7 @@ describe("MCP Server Tool Schemas", () => {
124
122
  id: z.union([z.string(), z.number()]),
125
123
  text: z.string(),
126
124
  metadata: z.record(z.string(), z.any()).optional(),
127
- }),
125
+ })
128
126
  ),
129
127
  });
130
128
 
@@ -292,7 +290,7 @@ describe("MCP Server Resource URIs", () => {
292
290
  const match = collectionUri.match(/^qdrant:\/\/collection\/(.+)$/);
293
291
 
294
292
  expect(match).not.toBeNull();
295
- expect(match![1]).toBe("my-collection");
293
+ expect(match?.[1]).toBe("my-collection");
296
294
  });
297
295
 
298
296
  it("should extract collection name from URI", () => {
@@ -304,7 +302,7 @@ describe("MCP Server Resource URIs", () => {
304
302
 
305
303
  testCases.forEach(({ uri, expected }) => {
306
304
  const match = uri.match(/^qdrant:\/\/collection\/(.+)$/);
307
- expect(match![1]).toBe(expected);
305
+ expect(match?.[1]).toBe(expected);
308
306
  });
309
307
  });
310
308