raggrep 0.5.0 → 0.5.1

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.
@@ -4,6 +4,8 @@ export interface IndexResult {
4
4
  indexed: number;
5
5
  skipped: number;
6
6
  errors: number;
7
+ /** Time taken in milliseconds */
8
+ durationMs?: number;
7
9
  }
8
10
  export interface IndexOptions {
9
11
  /** Override the embedding model (semantic module) */
package/dist/cli/main.js CHANGED
@@ -325,6 +325,7 @@ var init_searchResult = __esm(() => {
325
325
  topK: 10,
326
326
  minScore: 0.15,
327
327
  filePatterns: [],
328
+ pathFilter: [],
328
329
  ensureFresh: true
329
330
  };
330
331
  });
@@ -2087,6 +2088,9 @@ class CoreModule {
2087
2088
  name = "Core Search";
2088
2089
  description = "Language-agnostic text search with symbol extraction";
2089
2090
  version = "1.0.0";
2091
+ supportsFile(_filepath) {
2092
+ return true;
2093
+ }
2090
2094
  symbolIndex = new Map;
2091
2095
  bm25Index = null;
2092
2096
  rootDir = "";
@@ -2979,6 +2983,7 @@ var init_storage = __esm(() => {
2979
2983
  // src/modules/language/typescript/index.ts
2980
2984
  var exports_typescript = {};
2981
2985
  __export(exports_typescript, {
2986
+ supportsFile: () => supportsFile,
2982
2987
  isTypeScriptFile: () => isTypeScriptFile,
2983
2988
  TypeScriptModule: () => TypeScriptModule,
2984
2989
  TYPESCRIPT_EXTENSIONS: () => TYPESCRIPT_EXTENSIONS,
@@ -3017,6 +3022,9 @@ class TypeScriptModule {
3017
3022
  name = "TypeScript Search";
3018
3023
  description = "TypeScript-aware code search with AST parsing and semantic embeddings";
3019
3024
  version = "1.0.0";
3025
+ supportsFile(filepath) {
3026
+ return isTypeScriptFile(filepath);
3027
+ }
3020
3028
  embeddingConfig = null;
3021
3029
  symbolicIndex = null;
3022
3030
  pendingSummaries = new Map;
@@ -3240,7 +3248,7 @@ class TypeScriptModule {
3240
3248
  return references;
3241
3249
  }
3242
3250
  }
3243
- var DEFAULT_MIN_SCORE2 = 0.15, DEFAULT_TOP_K2 = 10, SEMANTIC_WEIGHT = 0.7, BM25_WEIGHT = 0.3, TYPESCRIPT_EXTENSIONS;
3251
+ var DEFAULT_MIN_SCORE2 = 0.15, DEFAULT_TOP_K2 = 10, SEMANTIC_WEIGHT = 0.7, BM25_WEIGHT = 0.3, TYPESCRIPT_EXTENSIONS, supportsFile;
3244
3252
  var init_typescript = __esm(() => {
3245
3253
  init_embeddings();
3246
3254
  init_services();
@@ -3257,11 +3265,13 @@ var init_typescript = __esm(() => {
3257
3265
  ".mts",
3258
3266
  ".cts"
3259
3267
  ];
3268
+ supportsFile = isTypeScriptFile;
3260
3269
  });
3261
3270
 
3262
3271
  // src/modules/data/json/index.ts
3263
3272
  var exports_json = {};
3264
3273
  __export(exports_json, {
3274
+ supportsFile: () => supportsFile2,
3265
3275
  isJsonFile: () => isJsonFile,
3266
3276
  JsonModule: () => JsonModule,
3267
3277
  JSON_EXTENSIONS: () => JSON_EXTENSIONS,
@@ -3318,6 +3328,9 @@ class JsonModule {
3318
3328
  name = "JSON Search";
3319
3329
  description = "JSON file search with structure-aware indexing";
3320
3330
  version = "1.0.0";
3331
+ supportsFile(filepath) {
3332
+ return isJsonFile(filepath);
3333
+ }
3321
3334
  embeddingConfig = null;
3322
3335
  symbolicIndex = null;
3323
3336
  pendingSummaries = new Map;
@@ -3479,18 +3492,20 @@ class JsonModule {
3479
3492
  return results.slice(0, topK);
3480
3493
  }
3481
3494
  }
3482
- var DEFAULT_MIN_SCORE3 = 0.15, DEFAULT_TOP_K3 = 10, SEMANTIC_WEIGHT2 = 0.7, BM25_WEIGHT2 = 0.3, JSON_EXTENSIONS;
3495
+ var DEFAULT_MIN_SCORE3 = 0.15, DEFAULT_TOP_K3 = 10, SEMANTIC_WEIGHT2 = 0.7, BM25_WEIGHT2 = 0.3, JSON_EXTENSIONS, supportsFile2;
3483
3496
  var init_json = __esm(() => {
3484
3497
  init_embeddings();
3485
3498
  init_services();
3486
3499
  init_config2();
3487
3500
  init_storage();
3488
3501
  JSON_EXTENSIONS = [".json"];
3502
+ supportsFile2 = isJsonFile;
3489
3503
  });
3490
3504
 
3491
3505
  // src/modules/docs/markdown/index.ts
3492
3506
  var exports_markdown = {};
3493
3507
  __export(exports_markdown, {
3508
+ supportsFile: () => supportsFile3,
3494
3509
  isMarkdownFile: () => isMarkdownFile,
3495
3510
  MarkdownModule: () => MarkdownModule,
3496
3511
  MARKDOWN_EXTENSIONS: () => MARKDOWN_EXTENSIONS,
@@ -3596,6 +3611,9 @@ class MarkdownModule {
3596
3611
  name = "Markdown Search";
3597
3612
  description = "Markdown documentation search with section-aware indexing";
3598
3613
  version = "1.0.0";
3614
+ supportsFile(filepath) {
3615
+ return isMarkdownFile(filepath);
3616
+ }
3599
3617
  embeddingConfig = null;
3600
3618
  symbolicIndex = null;
3601
3619
  pendingSummaries = new Map;
@@ -3765,13 +3783,14 @@ ${section.content}` : section.content,
3765
3783
  return results.slice(0, topK);
3766
3784
  }
3767
3785
  }
3768
- var DEFAULT_MIN_SCORE4 = 0.15, DEFAULT_TOP_K4 = 10, SEMANTIC_WEIGHT3 = 0.7, BM25_WEIGHT3 = 0.3, MARKDOWN_EXTENSIONS;
3786
+ var DEFAULT_MIN_SCORE4 = 0.15, DEFAULT_TOP_K4 = 10, SEMANTIC_WEIGHT3 = 0.7, BM25_WEIGHT3 = 0.3, MARKDOWN_EXTENSIONS, supportsFile3;
3769
3787
  var init_markdown = __esm(() => {
3770
3788
  init_embeddings();
3771
3789
  init_services();
3772
3790
  init_config2();
3773
3791
  init_storage();
3774
3792
  MARKDOWN_EXTENSIONS = [".md", ".txt"];
3793
+ supportsFile3 = isMarkdownFile;
3775
3794
  });
3776
3795
 
3777
3796
  // src/modules/registry.ts
@@ -4275,6 +4294,18 @@ async function parallelMap(items, processor, concurrency) {
4275
4294
  await Promise.all(workers);
4276
4295
  return results;
4277
4296
  }
4297
+ function formatDuration(ms) {
4298
+ if (ms < 1000) {
4299
+ return `${ms}ms`;
4300
+ }
4301
+ const seconds = ms / 1000;
4302
+ if (seconds < 60) {
4303
+ return `${seconds.toFixed(1)}s`;
4304
+ }
4305
+ const minutes = Math.floor(seconds / 60);
4306
+ const remainingSeconds = seconds % 60;
4307
+ return `${minutes}m ${remainingSeconds.toFixed(1)}s`;
4308
+ }
4278
4309
  async function indexDirectory(rootDir, options = {}) {
4279
4310
  const verbose = options.verbose ?? false;
4280
4311
  const quiet = options.quiet ?? false;
@@ -4301,8 +4332,10 @@ async function indexDirectory(rootDir, options = {}) {
4301
4332
  logger.info(`Enabled modules: ${enabledModules.map((m) => m.id).join(", ")}`);
4302
4333
  const files = await findFiles(rootDir, config);
4303
4334
  logger.info(`Found ${files.length} files to index`);
4335
+ const overallStart = Date.now();
4304
4336
  const results = [];
4305
4337
  for (const module of enabledModules) {
4338
+ const moduleStart = Date.now();
4306
4339
  logger.info(`
4307
4340
  [${module.name}] Starting indexing...`);
4308
4341
  const moduleConfig = getModuleConfig(config, module.id);
@@ -4320,7 +4353,9 @@ async function indexDirectory(rootDir, options = {}) {
4320
4353
  };
4321
4354
  await module.initialize(configWithOverrides);
4322
4355
  }
4323
- const result = await indexWithModule(rootDir, files, module, config, verbose, introspection, logger, concurrency);
4356
+ const moduleFiles = module.supportsFile ? files.filter((f) => module.supportsFile(f)) : files;
4357
+ logger.info(` Processing ${moduleFiles.length} files...`);
4358
+ const result = await indexWithModule(rootDir, moduleFiles, module, config, verbose, introspection, logger, concurrency);
4324
4359
  results.push(result);
4325
4360
  if (module.finalize) {
4326
4361
  logger.info(`[${module.name}] Building secondary indexes...`);
@@ -4339,9 +4374,18 @@ async function indexDirectory(rootDir, options = {}) {
4339
4374
  };
4340
4375
  await module.finalize(ctx);
4341
4376
  }
4342
- logger.info(`[${module.name}] Complete: ${result.indexed} indexed, ${result.skipped} skipped, ${result.errors} errors`);
4377
+ const moduleDuration = Date.now() - moduleStart;
4378
+ result.durationMs = moduleDuration;
4379
+ logger.info(`[${module.name}] Complete: ${result.indexed} indexed, ${result.skipped} skipped, ${result.errors} errors (${formatDuration(moduleDuration)})`);
4343
4380
  }
4344
4381
  await introspection.save(config);
4382
+ const overallDuration = Date.now() - overallStart;
4383
+ logger.info(`
4384
+ Indexing complete in ${formatDuration(overallDuration)}`);
4385
+ const totalIndexed = results.reduce((sum, r) => sum + r.indexed, 0);
4386
+ const totalSkipped = results.reduce((sum, r) => sum + r.skipped, 0);
4387
+ const totalErrors = results.reduce((sum, r) => sum + r.errors, 0);
4388
+ logger.info(`Total: ${totalIndexed} indexed, ${totalSkipped} skipped, ${totalErrors} errors`);
4345
4389
  await updateGlobalManifest(rootDir, enabledModules, config);
4346
4390
  return results;
4347
4391
  }
@@ -4862,9 +4906,17 @@ async function search(rootDir, query, options = {}) {
4862
4906
  const moduleResults = await module.search(query, ctx, options);
4863
4907
  allResults.push(...moduleResults);
4864
4908
  }
4865
- allResults.sort((a, b) => b.score - a.score);
4909
+ let filteredResults = allResults;
4910
+ if (options.pathFilter && options.pathFilter.length > 0) {
4911
+ const normalizedFilters = options.pathFilter.map((p) => p.replace(/\\/g, "/").replace(/^\//, "").replace(/\/$/, ""));
4912
+ filteredResults = allResults.filter((result) => {
4913
+ const normalizedPath = result.filepath.replace(/\\/g, "/");
4914
+ return normalizedFilters.some((filter) => normalizedPath.startsWith(filter + "/") || normalizedPath === filter || normalizedPath.startsWith("./" + filter + "/") || normalizedPath === "./" + filter);
4915
+ });
4916
+ }
4917
+ filteredResults.sort((a, b) => b.score - a.score);
4866
4918
  const topK = options.topK ?? 10;
4867
- return allResults.slice(0, topK);
4919
+ return filteredResults.slice(0, topK);
4868
4920
  }
4869
4921
  function createSearchContext(rootDir, moduleId, config) {
4870
4922
  const indexPath = getModuleIndexPath(rootDir, moduleId, config);
@@ -4973,7 +5025,7 @@ init_logger();
4973
5025
  // package.json
4974
5026
  var package_default = {
4975
5027
  name: "raggrep",
4976
- version: "0.5.0",
5028
+ version: "0.5.1",
4977
5029
  description: "Local filesystem-based RAG system for codebases - semantic search using local embeddings",
4978
5030
  type: "module",
4979
5031
  main: "./dist/index.js",
@@ -5117,6 +5169,17 @@ function parseFlags(args2) {
5117
5169
  console.error(`Invalid concurrency: ${args2[i]}. Must be a positive integer.`);
5118
5170
  process.exit(1);
5119
5171
  }
5172
+ } else if (arg === "--filter" || arg === "-f") {
5173
+ const filterPath = args2[++i];
5174
+ if (filterPath) {
5175
+ if (!flags.pathFilter) {
5176
+ flags.pathFilter = [];
5177
+ }
5178
+ flags.pathFilter.push(filterPath);
5179
+ } else {
5180
+ console.error("--filter requires a path (e.g., src/auth)");
5181
+ process.exit(1);
5182
+ }
5120
5183
  } else if (!arg.startsWith("-")) {
5121
5184
  flags.remaining.push(arg);
5122
5185
  }
@@ -5225,6 +5288,7 @@ Options:
5225
5288
  -k, --top <n> Number of results to return (default: 10)
5226
5289
  -s, --min-score <n> Minimum similarity score 0-1 (default: 0.15)
5227
5290
  -t, --type <ext> Filter by file extension (e.g., ts, tsx, js)
5291
+ -f, --filter <path> Filter by path prefix (can be used multiple times)
5228
5292
  -h, --help Show this help message
5229
5293
 
5230
5294
  Note:
@@ -5239,6 +5303,8 @@ Examples:
5239
5303
  raggrep query "handle errors" --top 5
5240
5304
  raggrep query "database" --min-score 0.1
5241
5305
  raggrep query "interface" --type ts
5306
+ raggrep query "login" --filter src/auth
5307
+ raggrep query "api" --filter src/api --filter src/routes
5242
5308
  `);
5243
5309
  process.exit(0);
5244
5310
  }
@@ -5279,6 +5345,7 @@ Examples:
5279
5345
  topK: flags.topK ?? 10,
5280
5346
  minScore: flags.minScore,
5281
5347
  filePatterns,
5348
+ pathFilter: flags.pathFilter,
5282
5349
  ensureFresh: false
5283
5350
  });
5284
5351
  console.log(formatSearchResults2(results));
@@ -5419,4 +5486,4 @@ Run 'raggrep <command> --help' for more information.
5419
5486
  }
5420
5487
  main();
5421
5488
 
5422
- //# debugId=5CA623D9974ACF4364756E2164756E21
5489
+ //# debugId=E73618F0DDE8326264756E2164756E21