raggrep 0.10.5 → 0.10.8

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,14 +38,23 @@ export interface TimingInfo {
38
38
  indexingMs: number;
39
39
  /** Time spent on cleanup operations */
40
40
  cleanupMs: number;
41
- /** Number of files discovered */
41
+ /** Number of files discovered on disk */
42
42
  filesDiscovered: number;
43
- /** Number of files that needed stat check */
43
+ /** Number of files that had stat checks performed (may be > filesDiscovered due to multiple modules) */
44
44
  filesStatChecked: number;
45
- /** Number of files that needed indexing */
46
- filesIndexed: number;
45
+ /** Number of files with detected changes (mtime or size changed) that went to Phase 2 */
46
+ filesWithChanges: number;
47
+ /** Number of files that were actually re-indexed (content changed) */
48
+ filesReindexed: number;
47
49
  /** Whether result was from cache */
48
50
  fromCache: boolean;
51
+ /** Diagnostic: breakdown of why files went to Phase 2 */
52
+ phase2Reasons?: {
53
+ newFiles: number;
54
+ noFileSize: number;
55
+ sizeMismatch: number;
56
+ noContentHash: number;
57
+ };
49
58
  }
50
59
  export interface EnsureFreshResult {
51
60
  /** Number of files indexed (new or modified) */
package/dist/cli/main.js CHANGED
@@ -12057,7 +12057,12 @@ async function ensureIndexFresh(rootDir, options = {}) {
12057
12057
  let cleanupMs = 0;
12058
12058
  let filesDiscovered = 0;
12059
12059
  let filesStatChecked = 0;
12060
- let filesIndexed = 0;
12060
+ let filesWithChanges = 0;
12061
+ let filesReindexed = 0;
12062
+ let totalDiagNewFiles = 0;
12063
+ let totalDiagNoFileSize = 0;
12064
+ let totalDiagSizeMismatch = 0;
12065
+ let totalDiagNoContentHash = 0;
12061
12066
  const logger = options.logger ? options.logger : quiet ? createSilentLogger() : createLogger({ verbose });
12062
12067
  rootDir = path22.resolve(rootDir);
12063
12068
  const status = await getIndexStatus(rootDir);
@@ -12099,7 +12104,8 @@ async function ensureIndexFresh(rootDir, options = {}) {
12099
12104
  cleanupMs: 0,
12100
12105
  filesDiscovered: 0,
12101
12106
  filesStatChecked: 0,
12102
- filesIndexed: 0,
12107
+ filesWithChanges: 0,
12108
+ filesReindexed: 0,
12103
12109
  fromCache: true
12104
12110
  };
12105
12111
  }
@@ -12194,41 +12200,91 @@ async function ensureIndexFresh(rootDir, options = {}) {
12194
12200
  try {
12195
12201
  const stats = await fs8.stat(filepath);
12196
12202
  const lastModified = stats.mtime.toISOString();
12203
+ const fileSize = stats.size;
12197
12204
  const existingEntry = manifest.files[relativePath];
12198
12205
  if (!existingEntry) {
12199
- return { filepath, relativePath, lastModified, needsCheck: true, isNew: true };
12206
+ return { filepath, relativePath, lastModified, fileSize, needsCheck: true, isNew: true };
12200
12207
  }
12201
12208
  if (existingEntry.lastModified === lastModified) {
12202
- return { filepath, relativePath, lastModified, needsCheck: false, isNew: false };
12209
+ return { filepath, relativePath, lastModified, fileSize, needsCheck: false, isNew: false };
12203
12210
  }
12204
- return { filepath, relativePath, lastModified, needsCheck: true, isNew: false };
12211
+ if (existingEntry.fileSize !== undefined && existingEntry.fileSize === fileSize && existingEntry.contentHash) {
12212
+ return { filepath, relativePath, lastModified, fileSize, needsCheck: false, isNew: false, existingContentHash: existingEntry.contentHash };
12213
+ }
12214
+ return { filepath, relativePath, lastModified, fileSize, needsCheck: true, isNew: false, existingContentHash: existingEntry.contentHash };
12205
12215
  } catch {
12206
12216
  return null;
12207
12217
  }
12208
12218
  };
12219
+ const moduleFiles = module2.supportsFile ? currentFiles.filter((f) => module2.supportsFile(f)) : currentFiles;
12209
12220
  const statCheckStart = Date.now();
12210
- const statResults = await parallelMap(currentFiles, statCheck, STAT_CONCURRENCY);
12221
+ const statResults = await parallelMap(moduleFiles, statCheck, STAT_CONCURRENCY);
12211
12222
  statCheckMs += Date.now() - statCheckStart;
12212
- filesStatChecked += currentFiles.length;
12223
+ filesStatChecked += moduleFiles.length;
12213
12224
  const filesToProcess = [];
12225
+ const filesWithMtimeOnlyChange = [];
12214
12226
  let unchangedCount = 0;
12227
+ let diagNewFiles = 0;
12228
+ let diagNoFileSize = 0;
12229
+ let diagSizeMismatch = 0;
12230
+ let diagNoContentHash = 0;
12215
12231
  for (const result2 of statResults) {
12216
12232
  if (!result2.success || !result2.value)
12217
12233
  continue;
12218
12234
  if (result2.value.needsCheck) {
12219
12235
  filesToProcess.push(result2.value);
12236
+ if (result2.value.isNew) {
12237
+ diagNewFiles++;
12238
+ } else {
12239
+ const existingEntry = manifest.files[result2.value.relativePath];
12240
+ if (existingEntry) {
12241
+ if (existingEntry.fileSize === undefined)
12242
+ diagNoFileSize++;
12243
+ else if (existingEntry.fileSize !== result2.value.fileSize)
12244
+ diagSizeMismatch++;
12245
+ else if (!existingEntry.contentHash)
12246
+ diagNoContentHash++;
12247
+ }
12248
+ }
12220
12249
  } else {
12221
12250
  unchangedCount++;
12251
+ const existingEntry = manifest.files[result2.value.relativePath];
12252
+ if (existingEntry && existingEntry.lastModified !== result2.value.lastModified) {
12253
+ filesWithMtimeOnlyChange.push(result2.value);
12254
+ }
12255
+ }
12256
+ }
12257
+ totalDiagNewFiles += diagNewFiles;
12258
+ totalDiagNoFileSize += diagNoFileSize;
12259
+ totalDiagSizeMismatch += diagSizeMismatch;
12260
+ totalDiagNoContentHash += diagNoContentHash;
12261
+ if (filesToProcess.length > 100 && verbose) {
12262
+ logger.info(` [Diagnostic] Phase 2 reasons: new=${diagNewFiles}, noSize=${diagNoFileSize}, sizeMismatch=${diagSizeMismatch}, noHash=${diagNoContentHash}`);
12263
+ }
12264
+ let mtimeOnlyUpdates = 0;
12265
+ for (const file of filesWithMtimeOnlyChange) {
12266
+ const existingEntry = manifest.files[file.relativePath];
12267
+ if (existingEntry) {
12268
+ manifest.files[file.relativePath] = {
12269
+ ...existingEntry,
12270
+ lastModified: file.lastModified,
12271
+ fileSize: file.fileSize
12272
+ };
12273
+ mtimeOnlyUpdates++;
12222
12274
  }
12223
12275
  }
12224
12276
  if (filesToProcess.length === 0) {
12225
12277
  totalUnchanged += unchangedCount;
12278
+ if (mtimeOnlyUpdates > 0) {
12279
+ manifest.lastUpdated = new Date().toISOString();
12280
+ await writeModuleManifest(rootDir, module2.id, manifest, config);
12281
+ }
12226
12282
  continue;
12227
12283
  }
12228
12284
  let completedCount = 0;
12229
12285
  const totalToProcess = filesToProcess.length;
12230
12286
  const processChangedFile = async (statResult) => {
12231
- const { filepath, relativePath, lastModified, isNew } = statResult;
12287
+ const { filepath, relativePath, lastModified, fileSize, isNew } = statResult;
12232
12288
  try {
12233
12289
  const content = await fs8.readFile(filepath, "utf-8");
12234
12290
  const contentHash = computeContentHash(content);
@@ -12239,6 +12295,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
12239
12295
  relativePath,
12240
12296
  status: "mtime_updated",
12241
12297
  lastModified,
12298
+ fileSize,
12242
12299
  contentHash
12243
12300
  };
12244
12301
  }
@@ -12247,13 +12304,14 @@ async function ensureIndexFresh(rootDir, options = {}) {
12247
12304
  introspection.addFile(relativePath, content);
12248
12305
  const fileIndex = await module2.indexFile(relativePath, content, ctx);
12249
12306
  if (!fileIndex) {
12250
- return { relativePath, status: "unchanged" };
12307
+ return { relativePath, status: "unchanged", fileSize };
12251
12308
  }
12252
12309
  await writeFileIndex(rootDir, module2.id, relativePath, fileIndex, config);
12253
12310
  return {
12254
12311
  relativePath,
12255
12312
  status: "indexed",
12256
12313
  lastModified,
12314
+ fileSize,
12257
12315
  chunkCount: fileIndex.chunks.length,
12258
12316
  contentHash
12259
12317
  };
@@ -12266,7 +12324,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
12266
12324
  const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
12267
12325
  const results = await parallelMap(filesToProcess, processChangedFile, concurrency);
12268
12326
  indexingMs += Date.now() - indexingStart;
12269
- filesIndexed += filesToProcess.length;
12327
+ filesWithChanges += filesToProcess.length;
12270
12328
  totalUnchanged += unchangedCount;
12271
12329
  logger.clearProgress();
12272
12330
  let mtimeUpdates = 0;
@@ -12280,7 +12338,8 @@ async function ensureIndexFresh(rootDir, options = {}) {
12280
12338
  manifest.files[fileResult.relativePath] = {
12281
12339
  lastModified: fileResult.lastModified,
12282
12340
  chunkCount: fileResult.chunkCount,
12283
- contentHash: fileResult.contentHash
12341
+ contentHash: fileResult.contentHash,
12342
+ fileSize: fileResult.fileSize
12284
12343
  };
12285
12344
  totalIndexed++;
12286
12345
  break;
@@ -12289,7 +12348,8 @@ async function ensureIndexFresh(rootDir, options = {}) {
12289
12348
  manifest.files[fileResult.relativePath] = {
12290
12349
  ...manifest.files[fileResult.relativePath],
12291
12350
  lastModified: fileResult.lastModified,
12292
- contentHash: fileResult.contentHash
12351
+ contentHash: fileResult.contentHash,
12352
+ fileSize: fileResult.fileSize
12293
12353
  };
12294
12354
  mtimeUpdates++;
12295
12355
  }
@@ -12303,7 +12363,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
12303
12363
  break;
12304
12364
  }
12305
12365
  }
12306
- const hasManifestChanges = totalIndexed > 0 || totalRemoved > 0 || mtimeUpdates > 0;
12366
+ const hasManifestChanges = totalIndexed > 0 || totalRemoved > 0 || mtimeUpdates > 0 || mtimeOnlyUpdates > 0;
12307
12367
  if (hasManifestChanges) {
12308
12368
  manifest.lastUpdated = new Date().toISOString();
12309
12369
  await writeModuleManifest(rootDir, module2.id, manifest, config);
@@ -12337,8 +12397,15 @@ async function ensureIndexFresh(rootDir, options = {}) {
12337
12397
  cleanupMs,
12338
12398
  filesDiscovered,
12339
12399
  filesStatChecked,
12340
- filesIndexed,
12341
- fromCache: false
12400
+ filesWithChanges,
12401
+ filesReindexed: totalIndexed,
12402
+ fromCache: false,
12403
+ phase2Reasons: {
12404
+ newFiles: totalDiagNewFiles,
12405
+ noFileSize: totalDiagNoFileSize,
12406
+ sizeMismatch: totalDiagSizeMismatch,
12407
+ noContentHash: totalDiagNoContentHash
12408
+ }
12342
12409
  };
12343
12410
  }
12344
12411
  let finalManifestMtime = currentManifestMtime;
@@ -12407,6 +12474,7 @@ async function indexWithModule(rootDir, files, module2, config, verbose, introsp
12407
12474
  try {
12408
12475
  const stats = await fs8.stat(filepath);
12409
12476
  const lastModified = stats.mtime.toISOString();
12477
+ const fileSize = stats.size;
12410
12478
  const existingEntry = manifest.files[relativePath];
12411
12479
  if (existingEntry && existingEntry.lastModified === lastModified) {
12412
12480
  completedCount++;
@@ -12422,6 +12490,7 @@ async function indexWithModule(rootDir, files, module2, config, verbose, introsp
12422
12490
  relativePath,
12423
12491
  status: "skipped",
12424
12492
  lastModified,
12493
+ fileSize,
12425
12494
  contentHash
12426
12495
  };
12427
12496
  }
@@ -12431,13 +12500,14 @@ async function indexWithModule(rootDir, files, module2, config, verbose, introsp
12431
12500
  const fileIndex = await module2.indexFile(relativePath, content, ctx);
12432
12501
  if (!fileIndex) {
12433
12502
  logger.debug(` [${completedCount}/${totalFiles}] Skipped ${relativePath} (no chunks)`);
12434
- return { relativePath, status: "skipped" };
12503
+ return { relativePath, status: "skipped", fileSize };
12435
12504
  }
12436
12505
  await writeFileIndex(rootDir, module2.id, relativePath, fileIndex, config);
12437
12506
  return {
12438
12507
  relativePath,
12439
12508
  status: "indexed",
12440
12509
  lastModified,
12510
+ fileSize,
12441
12511
  chunkCount: fileIndex.chunks.length,
12442
12512
  contentHash
12443
12513
  };
@@ -12460,7 +12530,8 @@ async function indexWithModule(rootDir, files, module2, config, verbose, introsp
12460
12530
  manifest.files[fileResult.relativePath] = {
12461
12531
  lastModified: fileResult.lastModified,
12462
12532
  chunkCount: fileResult.chunkCount,
12463
- contentHash: fileResult.contentHash
12533
+ contentHash: fileResult.contentHash,
12534
+ fileSize: fileResult.fileSize
12464
12535
  };
12465
12536
  result.indexed++;
12466
12537
  break;
@@ -12471,7 +12542,8 @@ async function indexWithModule(rootDir, files, module2, config, verbose, introsp
12471
12542
  manifest.files[fileResult.relativePath] = {
12472
12543
  ...existingEntry,
12473
12544
  lastModified: fileResult.lastModified,
12474
- contentHash: fileResult.contentHash
12545
+ contentHash: fileResult.contentHash,
12546
+ fileSize: fileResult.fileSize
12475
12547
  };
12476
12548
  }
12477
12549
  }
@@ -14247,7 +14319,7 @@ init_logger();
14247
14319
  // package.json
14248
14320
  var package_default = {
14249
14321
  name: "raggrep",
14250
- version: "0.10.5",
14322
+ version: "0.10.8",
14251
14323
  description: "Local filesystem-based RAG system for codebases - semantic search using local embeddings",
14252
14324
  type: "module",
14253
14325
  main: "./dist/index.js",
@@ -14592,19 +14664,28 @@ Examples:
14592
14664
  }
14593
14665
  if (flags2.timing && freshStats.timing) {
14594
14666
  const t = freshStats.timing;
14595
- console.log("┌─ Timing ─────────────────────────────────────┐");
14667
+ console.log("┌─ Timing ───────────────────────────────────────────────┐");
14596
14668
  if (t.fromCache) {
14597
- console.log(`│ Cache hit (TTL-based) │`);
14598
- console.log(`│ Total: ${t.totalMs.toFixed(0).padStart(6)}ms │`);
14669
+ console.log(`│ Cache hit (TTL-based) │`);
14670
+ console.log(`│ Total: ${t.totalMs.toFixed(0).padStart(6)}ms │`);
14599
14671
  } else {
14600
- console.log(`│ File discovery: ${t.fileDiscoveryMs.toFixed(0).padStart(6)}ms (${t.filesDiscovered} files)`.padEnd(47) + "│");
14601
- console.log(`│ Stat checks: ${t.statCheckMs.toFixed(0).padStart(6)}ms (${t.filesStatChecked} files)`.padEnd(47) + "│");
14602
- console.log(`│ Indexing: ${t.indexingMs.toFixed(0).padStart(6)}ms (${t.filesIndexed} files)`.padEnd(47) + "│");
14603
- console.log(`│ Cleanup: ${t.cleanupMs.toFixed(0).padStart(6)}ms`.padEnd(47) + "│");
14604
- console.log(`│ ─────────────────────────────────────────── │`);
14605
- console.log(`│ Total: ${t.totalMs.toFixed(0).padStart(6)}ms`.padEnd(47) + "│");
14672
+ console.log(`│ File discovery: ${t.fileDiscoveryMs.toFixed(0).padStart(6)}ms${String(t.filesDiscovered).padStart(6)} files found`.padEnd(57) + "│");
14673
+ console.log(`│ Stat checks: ${t.statCheckMs.toFixed(0).padStart(6)}ms${String(t.filesStatChecked).padStart(6)} stats checked`.padEnd(57) + "│");
14674
+ console.log(`│ Indexing: ${t.indexingMs.toFixed(0).padStart(6)}ms │ ${String(t.filesWithChanges).padStart(6)} with changes → ${t.filesReindexed} reindexed`.padEnd(57) + "│");
14675
+ console.log(`│ Cleanup: ${t.cleanupMs.toFixed(0).padStart(6)}ms │`.padEnd(57) + "│");
14676
+ console.log(`│ ───────────────────────────────────────────────────── │`);
14677
+ console.log(`│ Total: ${t.totalMs.toFixed(0).padStart(6)}ms`.padEnd(57) + "│");
14678
+ if (t.phase2Reasons && t.filesWithChanges > 0) {
14679
+ const r = t.phase2Reasons;
14680
+ console.log(`│ ───────────────────────────────────────────────────── │`);
14681
+ console.log(`│ Phase 2 breakdown (why files needed verification): │`);
14682
+ console.log(`│ New files: ${String(r.newFiles).padStart(6)}`.padEnd(57) + "│");
14683
+ console.log(`│ No cached size: ${String(r.noFileSize).padStart(6)}`.padEnd(57) + "│");
14684
+ console.log(`│ Size mismatch: ${String(r.sizeMismatch).padStart(6)}`.padEnd(57) + "│");
14685
+ console.log(`│ No cached hash: ${String(r.noContentHash).padStart(6)}`.padEnd(57) + "│");
14686
+ }
14606
14687
  }
14607
- console.log(`└──────────────────────────────────────────────┘
14688
+ console.log(`└────────────────────────────────────────────────────────┘
14608
14689
  `);
14609
14690
  }
14610
14691
  const filePatterns = flags2.fileType ? [`*.${flags2.fileType}`] : undefined;
@@ -14864,4 +14945,4 @@ Run 'raggrep <command> --help' for more information.
14864
14945
  }
14865
14946
  main();
14866
14947
 
14867
- //# debugId=D79BF0530F7DE02664756E2164756E21
14948
+ //# debugId=BAC395AB000714B764756E2164756E21