raggrep 0.10.1 → 0.10.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.
- package/dist/app/indexer/index.d.ts +30 -0
- package/dist/cli/main.js +169 -39
- package/dist/cli/main.js.map +5 -5
- package/dist/index.js +144 -36
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { EmbeddingModelName, Logger } from "../../domain/ports";
|
|
2
|
+
/**
|
|
3
|
+
* Clear the freshness cache.
|
|
4
|
+
* Call this after explicit indexing operations.
|
|
5
|
+
*/
|
|
6
|
+
export declare function clearFreshnessCache(): void;
|
|
2
7
|
export interface IndexResult {
|
|
3
8
|
moduleId: string;
|
|
4
9
|
indexed: number;
|
|
@@ -18,6 +23,29 @@ export interface IndexOptions {
|
|
|
18
23
|
logger?: Logger;
|
|
19
24
|
/** Number of files to process in parallel (default: auto based on CPU cores) */
|
|
20
25
|
concurrency?: number;
|
|
26
|
+
/** Show timing information for each stage */
|
|
27
|
+
timing?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** Timing information for performance profiling */
|
|
30
|
+
export interface TimingInfo {
|
|
31
|
+
/** Total time in milliseconds */
|
|
32
|
+
totalMs: number;
|
|
33
|
+
/** Time spent on file discovery (glob) */
|
|
34
|
+
fileDiscoveryMs: number;
|
|
35
|
+
/** Time spent on stat checks */
|
|
36
|
+
statCheckMs: number;
|
|
37
|
+
/** Time spent on indexing changed files */
|
|
38
|
+
indexingMs: number;
|
|
39
|
+
/** Time spent on cleanup operations */
|
|
40
|
+
cleanupMs: number;
|
|
41
|
+
/** Number of files discovered */
|
|
42
|
+
filesDiscovered: number;
|
|
43
|
+
/** Number of files that needed stat check */
|
|
44
|
+
filesStatChecked: number;
|
|
45
|
+
/** Number of files that needed indexing */
|
|
46
|
+
filesIndexed: number;
|
|
47
|
+
/** Whether result was from cache */
|
|
48
|
+
fromCache: boolean;
|
|
21
49
|
}
|
|
22
50
|
export interface EnsureFreshResult {
|
|
23
51
|
/** Number of files indexed (new or modified) */
|
|
@@ -26,6 +54,8 @@ export interface EnsureFreshResult {
|
|
|
26
54
|
removed: number;
|
|
27
55
|
/** Number of files unchanged (used cache) */
|
|
28
56
|
unchanged: number;
|
|
57
|
+
/** Timing information (only present if timing option was enabled) */
|
|
58
|
+
timing?: TimingInfo;
|
|
29
59
|
}
|
|
30
60
|
export interface CleanupResult {
|
|
31
61
|
moduleId: string;
|
package/dist/cli/main.js
CHANGED
|
@@ -11235,6 +11235,7 @@ async function watchDirectory(rootDir, options = {}) {
|
|
|
11235
11235
|
isIndexing = true;
|
|
11236
11236
|
const changes = new Map(pendingChanges);
|
|
11237
11237
|
pendingChanges.clear();
|
|
11238
|
+
clearFreshnessCache();
|
|
11238
11239
|
try {
|
|
11239
11240
|
const filesToIndex = [];
|
|
11240
11241
|
const filesToDelete = [];
|
|
@@ -11377,6 +11378,7 @@ __export(exports_indexer, {
|
|
|
11377
11378
|
indexDirectory: () => indexDirectory,
|
|
11378
11379
|
getIndexStatus: () => getIndexStatus,
|
|
11379
11380
|
ensureIndexFresh: () => ensureIndexFresh,
|
|
11381
|
+
clearFreshnessCache: () => clearFreshnessCache,
|
|
11380
11382
|
cleanupIndex: () => cleanupIndex
|
|
11381
11383
|
});
|
|
11382
11384
|
import { glob } from "glob";
|
|
@@ -11384,6 +11386,9 @@ import * as fs8 from "fs/promises";
|
|
|
11384
11386
|
import * as path22 from "path";
|
|
11385
11387
|
import * as os3 from "os";
|
|
11386
11388
|
import * as crypto2 from "crypto";
|
|
11389
|
+
function clearFreshnessCache() {
|
|
11390
|
+
freshnessCache = null;
|
|
11391
|
+
}
|
|
11387
11392
|
function computeContentHash(content) {
|
|
11388
11393
|
return crypto2.createHash("sha256").update(content, "utf-8").digest("hex");
|
|
11389
11394
|
}
|
|
@@ -11427,6 +11432,7 @@ async function indexDirectory(rootDir, options = {}) {
|
|
|
11427
11432
|
const verbose = options.verbose ?? false;
|
|
11428
11433
|
const quiet = options.quiet ?? false;
|
|
11429
11434
|
const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
|
|
11435
|
+
clearFreshnessCache();
|
|
11430
11436
|
const logger = options.logger ? options.logger : quiet ? createSilentLogger() : createLogger({ verbose });
|
|
11431
11437
|
rootDir = path22.resolve(rootDir);
|
|
11432
11438
|
const location = getIndexLocation(rootDir);
|
|
@@ -11525,6 +11531,7 @@ async function deleteIndex(rootDir) {
|
|
|
11525
11531
|
}
|
|
11526
11532
|
async function resetIndex(rootDir) {
|
|
11527
11533
|
rootDir = path22.resolve(rootDir);
|
|
11534
|
+
clearFreshnessCache();
|
|
11528
11535
|
const status = await getIndexStatus(rootDir);
|
|
11529
11536
|
if (!status.exists) {
|
|
11530
11537
|
throw new Error(`No index found for ${rootDir}`);
|
|
@@ -11538,10 +11545,20 @@ async function resetIndex(rootDir) {
|
|
|
11538
11545
|
async function ensureIndexFresh(rootDir, options = {}) {
|
|
11539
11546
|
const verbose = options.verbose ?? false;
|
|
11540
11547
|
const quiet = options.quiet ?? false;
|
|
11548
|
+
const showTiming = options.timing ?? false;
|
|
11549
|
+
const startTime = Date.now();
|
|
11550
|
+
let fileDiscoveryMs = 0;
|
|
11551
|
+
let statCheckMs = 0;
|
|
11552
|
+
let indexingMs = 0;
|
|
11553
|
+
let cleanupMs = 0;
|
|
11554
|
+
let filesDiscovered = 0;
|
|
11555
|
+
let filesStatChecked = 0;
|
|
11556
|
+
let filesIndexed = 0;
|
|
11541
11557
|
const logger = options.logger ? options.logger : quiet ? createSilentLogger() : createLogger({ verbose });
|
|
11542
11558
|
rootDir = path22.resolve(rootDir);
|
|
11543
11559
|
const status = await getIndexStatus(rootDir);
|
|
11544
11560
|
if (!status.exists) {
|
|
11561
|
+
clearFreshnessCache();
|
|
11545
11562
|
logger.info(`No index found. Creating index...
|
|
11546
11563
|
`);
|
|
11547
11564
|
const results = await indexDirectory(rootDir, { ...options, logger });
|
|
@@ -11550,6 +11567,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11550
11567
|
}
|
|
11551
11568
|
const versionCompatible = await isIndexVersionCompatible(rootDir);
|
|
11552
11569
|
if (!versionCompatible) {
|
|
11570
|
+
clearFreshnessCache();
|
|
11553
11571
|
logger.info(`Index version incompatible. Rebuilding...
|
|
11554
11572
|
`);
|
|
11555
11573
|
await deleteIndex(rootDir);
|
|
@@ -11558,14 +11576,44 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11558
11576
|
return { indexed: totalIndexed2, removed: 0, unchanged: 0 };
|
|
11559
11577
|
}
|
|
11560
11578
|
const config = await loadConfig(rootDir);
|
|
11579
|
+
const globalManifestPath = getGlobalManifestPath(rootDir, config);
|
|
11580
|
+
let currentManifestMtime = 0;
|
|
11581
|
+
try {
|
|
11582
|
+
const manifestStats = await fs8.stat(globalManifestPath);
|
|
11583
|
+
currentManifestMtime = manifestStats.mtimeMs;
|
|
11584
|
+
} catch {}
|
|
11585
|
+
const now = Date.now();
|
|
11586
|
+
if (freshnessCache && freshnessCache.rootDir === rootDir && now - freshnessCache.timestamp < FRESHNESS_CACHE_TTL_MS && freshnessCache.manifestMtime === currentManifestMtime) {
|
|
11587
|
+
logger.debug("Using cached freshness check result");
|
|
11588
|
+
const cachedResult = { ...freshnessCache.result };
|
|
11589
|
+
if (showTiming) {
|
|
11590
|
+
cachedResult.timing = {
|
|
11591
|
+
totalMs: Date.now() - startTime,
|
|
11592
|
+
fileDiscoveryMs: 0,
|
|
11593
|
+
statCheckMs: 0,
|
|
11594
|
+
indexingMs: 0,
|
|
11595
|
+
cleanupMs: 0,
|
|
11596
|
+
filesDiscovered: 0,
|
|
11597
|
+
filesStatChecked: 0,
|
|
11598
|
+
filesIndexed: 0,
|
|
11599
|
+
fromCache: true
|
|
11600
|
+
};
|
|
11601
|
+
}
|
|
11602
|
+
return cachedResult;
|
|
11603
|
+
}
|
|
11561
11604
|
await registerBuiltInModules();
|
|
11562
11605
|
const enabledModules = registry.getEnabled(config);
|
|
11563
11606
|
if (enabledModules.length === 0) {
|
|
11564
11607
|
return { indexed: 0, removed: 0, unchanged: 0 };
|
|
11565
11608
|
}
|
|
11609
|
+
const fileDiscoveryStart = Date.now();
|
|
11566
11610
|
const introspection = new IntrospectionIndex(rootDir);
|
|
11567
|
-
await
|
|
11568
|
-
|
|
11611
|
+
const [, currentFiles] = await Promise.all([
|
|
11612
|
+
introspection.initialize(),
|
|
11613
|
+
findFiles(rootDir, config)
|
|
11614
|
+
]);
|
|
11615
|
+
fileDiscoveryMs = Date.now() - fileDiscoveryStart;
|
|
11616
|
+
filesDiscovered = currentFiles.length;
|
|
11569
11617
|
const currentFileSet = new Set(currentFiles.map((f) => path22.relative(rootDir, f)));
|
|
11570
11618
|
let totalIndexed = 0;
|
|
11571
11619
|
let totalRemoved = 0;
|
|
@@ -11594,20 +11642,21 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11594
11642
|
filesToRemove.push(filepath);
|
|
11595
11643
|
}
|
|
11596
11644
|
}
|
|
11645
|
+
const cleanupStart = Date.now();
|
|
11597
11646
|
const removedFilepaths = [];
|
|
11598
|
-
|
|
11599
|
-
|
|
11600
|
-
|
|
11601
|
-
|
|
11602
|
-
|
|
11603
|
-
|
|
11604
|
-
|
|
11605
|
-
|
|
11606
|
-
|
|
11607
|
-
|
|
11608
|
-
|
|
11609
|
-
|
|
11610
|
-
totalRemoved
|
|
11647
|
+
if (filesToRemove.length > 0) {
|
|
11648
|
+
await Promise.all(filesToRemove.map(async (filepath) => {
|
|
11649
|
+
logger.debug(` Removing stale: ${filepath}`);
|
|
11650
|
+
const indexFilePath = path22.join(indexPath, filepath.replace(/\.[^.]+$/, ".json"));
|
|
11651
|
+
const symbolicFilePath = path22.join(indexPath, "symbolic", filepath.replace(/\.[^.]+$/, ".json"));
|
|
11652
|
+
await Promise.all([
|
|
11653
|
+
fs8.unlink(indexFilePath).catch(() => {}),
|
|
11654
|
+
fs8.unlink(symbolicFilePath).catch(() => {})
|
|
11655
|
+
]);
|
|
11656
|
+
delete manifest.files[filepath];
|
|
11657
|
+
removedFilepaths.push(filepath);
|
|
11658
|
+
}));
|
|
11659
|
+
totalRemoved += removedFilepaths.length;
|
|
11611
11660
|
}
|
|
11612
11661
|
if (removedFilepaths.length > 0) {
|
|
11613
11662
|
try {
|
|
@@ -11621,6 +11670,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11621
11670
|
await literalIndex.save();
|
|
11622
11671
|
} catch {}
|
|
11623
11672
|
}
|
|
11673
|
+
cleanupMs += Date.now() - cleanupStart;
|
|
11624
11674
|
const ctx = {
|
|
11625
11675
|
rootDir,
|
|
11626
11676
|
config,
|
|
@@ -11635,21 +11685,51 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11635
11685
|
},
|
|
11636
11686
|
getIntrospection: (filepath) => introspection.getFile(filepath)
|
|
11637
11687
|
};
|
|
11638
|
-
const
|
|
11639
|
-
let completedCount = 0;
|
|
11640
|
-
const processIncrementalFile = async (filepath) => {
|
|
11688
|
+
const statCheck = async (filepath) => {
|
|
11641
11689
|
const relativePath = path22.relative(rootDir, filepath);
|
|
11642
11690
|
try {
|
|
11643
11691
|
const stats = await fs8.stat(filepath);
|
|
11644
11692
|
const lastModified = stats.mtime.toISOString();
|
|
11645
11693
|
const existingEntry = manifest.files[relativePath];
|
|
11646
|
-
if (existingEntry
|
|
11647
|
-
|
|
11648
|
-
return { relativePath, status: "unchanged" };
|
|
11694
|
+
if (!existingEntry) {
|
|
11695
|
+
return { filepath, relativePath, lastModified, needsCheck: true, isNew: true };
|
|
11649
11696
|
}
|
|
11697
|
+
if (existingEntry.lastModified === lastModified) {
|
|
11698
|
+
return { filepath, relativePath, lastModified, needsCheck: false, isNew: false };
|
|
11699
|
+
}
|
|
11700
|
+
return { filepath, relativePath, lastModified, needsCheck: true, isNew: false };
|
|
11701
|
+
} catch {
|
|
11702
|
+
return null;
|
|
11703
|
+
}
|
|
11704
|
+
};
|
|
11705
|
+
const statCheckStart = Date.now();
|
|
11706
|
+
const statResults = await parallelMap(currentFiles, statCheck, STAT_CONCURRENCY);
|
|
11707
|
+
statCheckMs += Date.now() - statCheckStart;
|
|
11708
|
+
filesStatChecked += currentFiles.length;
|
|
11709
|
+
const filesToProcess = [];
|
|
11710
|
+
let unchangedCount = 0;
|
|
11711
|
+
for (const result2 of statResults) {
|
|
11712
|
+
if (!result2.success || !result2.value)
|
|
11713
|
+
continue;
|
|
11714
|
+
if (result2.value.needsCheck) {
|
|
11715
|
+
filesToProcess.push(result2.value);
|
|
11716
|
+
} else {
|
|
11717
|
+
unchangedCount++;
|
|
11718
|
+
}
|
|
11719
|
+
}
|
|
11720
|
+
if (filesToProcess.length === 0) {
|
|
11721
|
+
totalUnchanged += unchangedCount;
|
|
11722
|
+
continue;
|
|
11723
|
+
}
|
|
11724
|
+
let completedCount = 0;
|
|
11725
|
+
const totalToProcess = filesToProcess.length;
|
|
11726
|
+
const processChangedFile = async (statResult) => {
|
|
11727
|
+
const { filepath, relativePath, lastModified, isNew } = statResult;
|
|
11728
|
+
try {
|
|
11650
11729
|
const content = await fs8.readFile(filepath, "utf-8");
|
|
11651
11730
|
const contentHash = computeContentHash(content);
|
|
11652
|
-
|
|
11731
|
+
const existingEntry = manifest.files[relativePath];
|
|
11732
|
+
if (!isNew && existingEntry?.contentHash && existingEntry.contentHash === contentHash) {
|
|
11653
11733
|
completedCount++;
|
|
11654
11734
|
return {
|
|
11655
11735
|
relativePath,
|
|
@@ -11659,7 +11739,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11659
11739
|
};
|
|
11660
11740
|
}
|
|
11661
11741
|
completedCount++;
|
|
11662
|
-
logger.progress(` [${completedCount}/${
|
|
11742
|
+
logger.progress(` [${completedCount}/${totalToProcess}] Indexing: ${relativePath}`);
|
|
11663
11743
|
introspection.addFile(relativePath, content);
|
|
11664
11744
|
const fileIndex = await module2.indexFile(relativePath, content, ctx);
|
|
11665
11745
|
if (!fileIndex) {
|
|
@@ -11678,8 +11758,12 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11678
11758
|
return { relativePath, status: "error", error };
|
|
11679
11759
|
}
|
|
11680
11760
|
};
|
|
11761
|
+
const indexingStart = Date.now();
|
|
11681
11762
|
const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
|
|
11682
|
-
const results = await parallelMap(
|
|
11763
|
+
const results = await parallelMap(filesToProcess, processChangedFile, concurrency);
|
|
11764
|
+
indexingMs += Date.now() - indexingStart;
|
|
11765
|
+
filesIndexed += filesToProcess.length;
|
|
11766
|
+
totalUnchanged += unchangedCount;
|
|
11683
11767
|
logger.clearProgress();
|
|
11684
11768
|
let mtimeUpdates = 0;
|
|
11685
11769
|
for (const item of results) {
|
|
@@ -11733,12 +11817,38 @@ async function ensureIndexFresh(rootDir, options = {}) {
|
|
|
11733
11817
|
}
|
|
11734
11818
|
if (totalIndexed > 0 || totalRemoved > 0) {
|
|
11735
11819
|
await updateGlobalManifest(rootDir, enabledModules, config);
|
|
11820
|
+
clearFreshnessCache();
|
|
11736
11821
|
}
|
|
11737
|
-
|
|
11822
|
+
const result = {
|
|
11738
11823
|
indexed: totalIndexed,
|
|
11739
11824
|
removed: totalRemoved,
|
|
11740
11825
|
unchanged: totalUnchanged
|
|
11741
11826
|
};
|
|
11827
|
+
if (showTiming) {
|
|
11828
|
+
result.timing = {
|
|
11829
|
+
totalMs: Date.now() - startTime,
|
|
11830
|
+
fileDiscoveryMs,
|
|
11831
|
+
statCheckMs,
|
|
11832
|
+
indexingMs,
|
|
11833
|
+
cleanupMs,
|
|
11834
|
+
filesDiscovered,
|
|
11835
|
+
filesStatChecked,
|
|
11836
|
+
filesIndexed,
|
|
11837
|
+
fromCache: false
|
|
11838
|
+
};
|
|
11839
|
+
}
|
|
11840
|
+
let finalManifestMtime = currentManifestMtime;
|
|
11841
|
+
try {
|
|
11842
|
+
const manifestStats = await fs8.stat(globalManifestPath);
|
|
11843
|
+
finalManifestMtime = manifestStats.mtimeMs;
|
|
11844
|
+
} catch {}
|
|
11845
|
+
freshnessCache = {
|
|
11846
|
+
rootDir,
|
|
11847
|
+
result: { indexed: totalIndexed, removed: totalRemoved, unchanged: totalUnchanged },
|
|
11848
|
+
timestamp: Date.now(),
|
|
11849
|
+
manifestMtime: finalManifestMtime
|
|
11850
|
+
};
|
|
11851
|
+
return result;
|
|
11742
11852
|
}
|
|
11743
11853
|
async function indexWithModule(rootDir, files, module2, config, verbose, introspection, logger, concurrency = DEFAULT_CONCURRENCY) {
|
|
11744
11854
|
const result = {
|
|
@@ -11876,16 +11986,13 @@ async function indexWithModule(rootDir, files, module2, config, verbose, introsp
|
|
|
11876
11986
|
async function findFiles(rootDir, config) {
|
|
11877
11987
|
const patterns = config.extensions.map((ext) => `**/*${ext}`);
|
|
11878
11988
|
const ignorePatterns = config.ignorePaths.map((p) => `**/${p}/**`);
|
|
11879
|
-
const
|
|
11880
|
-
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
files.push(...matches);
|
|
11887
|
-
}
|
|
11888
|
-
return [...new Set(files)];
|
|
11989
|
+
const results = await Promise.all(patterns.map((pattern) => glob(pattern, {
|
|
11990
|
+
cwd: rootDir,
|
|
11991
|
+
absolute: true,
|
|
11992
|
+
ignore: ignorePatterns
|
|
11993
|
+
})));
|
|
11994
|
+
const allFiles = results.flat();
|
|
11995
|
+
return [...new Set(allFiles)];
|
|
11889
11996
|
}
|
|
11890
11997
|
async function loadModuleManifest(rootDir, moduleId, config) {
|
|
11891
11998
|
const manifestPath = getModuleManifestPath(rootDir, moduleId, config);
|
|
@@ -12054,7 +12161,7 @@ async function getIndexStatus(rootDir) {
|
|
|
12054
12161
|
}
|
|
12055
12162
|
return status;
|
|
12056
12163
|
}
|
|
12057
|
-
var INDEX_SCHEMA_VERSION = "2.0.0", DEFAULT_CONCURRENCY;
|
|
12164
|
+
var FRESHNESS_CACHE_TTL_MS = 5000, freshnessCache = null, INDEX_SCHEMA_VERSION = "2.0.0", DEFAULT_CONCURRENCY, STAT_CONCURRENCY;
|
|
12058
12165
|
var init_indexer = __esm(() => {
|
|
12059
12166
|
init_config2();
|
|
12060
12167
|
init_registry();
|
|
@@ -12062,6 +12169,7 @@ var init_indexer = __esm(() => {
|
|
|
12062
12169
|
init_logger();
|
|
12063
12170
|
init_watcher();
|
|
12064
12171
|
DEFAULT_CONCURRENCY = getOptimalConcurrency();
|
|
12172
|
+
STAT_CONCURRENCY = Math.max(32, getOptimalConcurrency() * 4);
|
|
12065
12173
|
});
|
|
12066
12174
|
|
|
12067
12175
|
// node_modules/balanced-match/index.js
|
|
@@ -13635,7 +13743,7 @@ init_logger();
|
|
|
13635
13743
|
// package.json
|
|
13636
13744
|
var package_default = {
|
|
13637
13745
|
name: "raggrep",
|
|
13638
|
-
version: "0.10.
|
|
13746
|
+
version: "0.10.4",
|
|
13639
13747
|
description: "Local filesystem-based RAG system for codebases - semantic search using local embeddings",
|
|
13640
13748
|
type: "module",
|
|
13641
13749
|
main: "./dist/index.js",
|
|
@@ -13732,6 +13840,7 @@ function parseFlags(args3) {
|
|
|
13732
13840
|
help: false,
|
|
13733
13841
|
verbose: false,
|
|
13734
13842
|
watch: false,
|
|
13843
|
+
timing: false,
|
|
13735
13844
|
remaining: []
|
|
13736
13845
|
};
|
|
13737
13846
|
for (let i2 = 0;i2 < args3.length; i2++) {
|
|
@@ -13742,6 +13851,8 @@ function parseFlags(args3) {
|
|
|
13742
13851
|
flags2.verbose = true;
|
|
13743
13852
|
} else if (arg === "--watch" || arg === "-w") {
|
|
13744
13853
|
flags2.watch = true;
|
|
13854
|
+
} else if (arg === "--timing" || arg === "-T") {
|
|
13855
|
+
flags2.timing = true;
|
|
13745
13856
|
} else if (arg === "--model" || arg === "-m") {
|
|
13746
13857
|
const modelName = args3[++i2];
|
|
13747
13858
|
if (modelName && modelName in EMBEDDING_MODELS) {
|
|
@@ -13900,6 +14011,7 @@ Options:
|
|
|
13900
14011
|
-s, --min-score <n> Minimum similarity score 0-1 (default: 0.15)
|
|
13901
14012
|
-t, --type <ext> Filter by file extension (e.g., ts, tsx, js)
|
|
13902
14013
|
-f, --filter <path> Filter by path or glob pattern (can be used multiple times)
|
|
14014
|
+
-T, --timing Show timing breakdown for performance profiling
|
|
13903
14015
|
-h, --help Show this help message
|
|
13904
14016
|
|
|
13905
14017
|
Note:
|
|
@@ -13953,7 +14065,8 @@ Examples:
|
|
|
13953
14065
|
const freshStats = await ensureIndexFresh2(process.cwd(), {
|
|
13954
14066
|
model: flags2.model,
|
|
13955
14067
|
quiet: true,
|
|
13956
|
-
logger: silentLogger
|
|
14068
|
+
logger: silentLogger,
|
|
14069
|
+
timing: flags2.timing
|
|
13957
14070
|
});
|
|
13958
14071
|
console.log("RAGgrep Search");
|
|
13959
14072
|
console.log(`==============
|
|
@@ -13970,6 +14083,23 @@ Examples:
|
|
|
13970
14083
|
`);
|
|
13971
14084
|
} else {
|
|
13972
14085
|
console.log(`Using cached index (no changes detected).
|
|
14086
|
+
`);
|
|
14087
|
+
}
|
|
14088
|
+
if (flags2.timing && freshStats.timing) {
|
|
14089
|
+
const t = freshStats.timing;
|
|
14090
|
+
console.log("┌─ Timing ─────────────────────────────────────┐");
|
|
14091
|
+
if (t.fromCache) {
|
|
14092
|
+
console.log(`│ Cache hit (TTL-based) │`);
|
|
14093
|
+
console.log(`│ Total: ${t.totalMs.toFixed(0).padStart(6)}ms │`);
|
|
14094
|
+
} else {
|
|
14095
|
+
console.log(`│ File discovery: ${t.fileDiscoveryMs.toFixed(0).padStart(6)}ms (${t.filesDiscovered} files)`.padEnd(47) + "│");
|
|
14096
|
+
console.log(`│ Stat checks: ${t.statCheckMs.toFixed(0).padStart(6)}ms (${t.filesStatChecked} files)`.padEnd(47) + "│");
|
|
14097
|
+
console.log(`│ Indexing: ${t.indexingMs.toFixed(0).padStart(6)}ms (${t.filesIndexed} files)`.padEnd(47) + "│");
|
|
14098
|
+
console.log(`│ Cleanup: ${t.cleanupMs.toFixed(0).padStart(6)}ms`.padEnd(47) + "│");
|
|
14099
|
+
console.log(`│ ─────────────────────────────────────────── │`);
|
|
14100
|
+
console.log(`│ Total: ${t.totalMs.toFixed(0).padStart(6)}ms`.padEnd(47) + "│");
|
|
14101
|
+
}
|
|
14102
|
+
console.log(`└──────────────────────────────────────────────┘
|
|
13973
14103
|
`);
|
|
13974
14104
|
}
|
|
13975
14105
|
const filePatterns = flags2.fileType ? [`*.${flags2.fileType}`] : undefined;
|
|
@@ -14229,4 +14359,4 @@ Run 'raggrep <command> --help' for more information.
|
|
|
14229
14359
|
}
|
|
14230
14360
|
main();
|
|
14231
14361
|
|
|
14232
|
-
//# debugId=
|
|
14362
|
+
//# debugId=5A4116C9AF3188E264756E2164756E21
|