raggrep 0.10.0 → 0.10.2

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/README.md CHANGED
@@ -7,6 +7,8 @@ RAGgrep indexes your code and lets you search it using natural language. Everyth
7
7
  ## Features
8
8
 
9
9
  - **Zero-config search** — Just run `raggrep query` and it works. Index is created and updated automatically.
10
+ - **Multi-language support** — Deep understanding of TypeScript, JavaScript, Python, Go, and Rust with AST-aware parsing.
11
+ - **Vocabulary-based search** — Search `user` to find `getUserById`, `fetchUserData`, `UserService`, etc. Understands code naming conventions.
10
12
  - **Local-first** — All indexing and search happens on your machine. No cloud dependencies.
11
13
  - **Incremental** — Only re-indexes files that have changed. Instant search when nothing changed.
12
14
  - **Watch mode** — Keep the index fresh in real-time as you code.
@@ -184,15 +186,42 @@ The index is stored in a system temp directory, keeping your project clean.
184
186
 
185
187
  ## What Gets Indexed
186
188
 
187
- **TypeScript/JavaScript:** `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`, `.cjs` — AST-parsed for functions, classes, interfaces, types, enums
189
+ ### Supported Languages
188
190
 
189
- **Documentation:** `.md`, `.txt` Section-aware parsing with heading extraction
191
+ **TypeScript/JavaScript** (`.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`, `.cjs`)
192
+ - AST-parsed for functions, classes, interfaces, types, enums
193
+ - Full file chunks for broad context
194
+ - JSDoc and comment association
190
195
 
191
- **Data:** `.json` — Structure-aware with key/value extraction
196
+ **Python** (`.py`)
197
+ - AST-parsed for functions, classes, decorators
198
+ - Docstring extraction and association
199
+ - Fallback regex parsing for robustness
192
200
 
193
- **Other languages:** `.py`, `.go`, `.rs`, `.java`, `.yaml`, `.yml`, `.toml`, `.sql` — Symbol extraction and keyword search
201
+ **Go** (`.go`)
202
+ - AST-parsed for functions, methods, structs, interfaces
203
+ - Doc comment extraction (`//` style)
204
+ - Exported symbol detection
194
205
 
195
- **Automatically ignored:** `node_modules`, `dist`, `build`, `.git`, and other common directories
206
+ **Rust** (`.rs`)
207
+ - AST-parsed for functions, structs, traits, impls, enums
208
+ - Doc comment extraction (`///` and `//!` style)
209
+ - Visibility detection (`pub`)
210
+
211
+ **Markdown** (`.md`)
212
+ - Hierarchical chunking at multiple heading levels (H1-H5)
213
+ - Each heading level creates separate searchable chunks
214
+ - Nested content included for context
215
+
216
+ **JSON** (`.json`)
217
+ - Structure-aware with key/value extraction
218
+ - Path-based indexing
219
+
220
+ **Other formats:** `.yaml`, `.yml`, `.toml`, `.sql`, `.txt` — Keyword search and full-text indexing
221
+
222
+ ### Automatically Ignored
223
+
224
+ `node_modules`, `dist`, `build`, `.git`, `.next`, `.cache`, `__pycache__`, `target`, and other common build/dependency directories
196
225
 
197
226
  ## Documentation
198
227
 
@@ -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;
package/dist/cli/main.js CHANGED
@@ -8334,9 +8334,9 @@ class TreeSitterParser {
8334
8334
  }
8335
8335
  async initializeTreeSitter() {
8336
8336
  try {
8337
- const Parser2 = await Promise.resolve().then(() => (init_web_tree_sitter(), exports_web_tree_sitter));
8338
- await Parser2.default.init();
8339
- this.parserInstance = new Parser2.default;
8337
+ const { Parser: Parser2 } = await Promise.resolve().then(() => (init_web_tree_sitter(), exports_web_tree_sitter));
8338
+ await Parser2.init();
8339
+ this.parserInstance = new Parser2;
8340
8340
  } catch (error) {
8341
8341
  console.error("Failed to initialize web-tree-sitter:", error);
8342
8342
  throw error;
@@ -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}`);
@@ -11542,6 +11549,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
11542
11549
  rootDir = path22.resolve(rootDir);
11543
11550
  const status = await getIndexStatus(rootDir);
11544
11551
  if (!status.exists) {
11552
+ clearFreshnessCache();
11545
11553
  logger.info(`No index found. Creating index...
11546
11554
  `);
11547
11555
  const results = await indexDirectory(rootDir, { ...options, logger });
@@ -11550,6 +11558,7 @@ async function ensureIndexFresh(rootDir, options = {}) {
11550
11558
  }
11551
11559
  const versionCompatible = await isIndexVersionCompatible(rootDir);
11552
11560
  if (!versionCompatible) {
11561
+ clearFreshnessCache();
11553
11562
  logger.info(`Index version incompatible. Rebuilding...
11554
11563
  `);
11555
11564
  await deleteIndex(rootDir);
@@ -11558,6 +11567,17 @@ async function ensureIndexFresh(rootDir, options = {}) {
11558
11567
  return { indexed: totalIndexed2, removed: 0, unchanged: 0 };
11559
11568
  }
11560
11569
  const config = await loadConfig(rootDir);
11570
+ const globalManifestPath = getGlobalManifestPath(rootDir, config);
11571
+ let currentManifestMtime = 0;
11572
+ try {
11573
+ const manifestStats = await fs8.stat(globalManifestPath);
11574
+ currentManifestMtime = manifestStats.mtimeMs;
11575
+ } catch {}
11576
+ const now = Date.now();
11577
+ if (freshnessCache && freshnessCache.rootDir === rootDir && now - freshnessCache.timestamp < FRESHNESS_CACHE_TTL_MS && freshnessCache.manifestMtime === currentManifestMtime) {
11578
+ logger.debug("Using cached freshness check result");
11579
+ return freshnessCache.result;
11580
+ }
11561
11581
  await registerBuiltInModules();
11562
11582
  const enabledModules = registry.getEnabled(config);
11563
11583
  if (enabledModules.length === 0) {
@@ -11733,12 +11753,25 @@ async function ensureIndexFresh(rootDir, options = {}) {
11733
11753
  }
11734
11754
  if (totalIndexed > 0 || totalRemoved > 0) {
11735
11755
  await updateGlobalManifest(rootDir, enabledModules, config);
11756
+ clearFreshnessCache();
11736
11757
  }
11737
- return {
11758
+ const result = {
11738
11759
  indexed: totalIndexed,
11739
11760
  removed: totalRemoved,
11740
11761
  unchanged: totalUnchanged
11741
11762
  };
11763
+ let finalManifestMtime = currentManifestMtime;
11764
+ try {
11765
+ const manifestStats = await fs8.stat(globalManifestPath);
11766
+ finalManifestMtime = manifestStats.mtimeMs;
11767
+ } catch {}
11768
+ freshnessCache = {
11769
+ rootDir,
11770
+ result,
11771
+ timestamp: Date.now(),
11772
+ manifestMtime: finalManifestMtime
11773
+ };
11774
+ return result;
11742
11775
  }
11743
11776
  async function indexWithModule(rootDir, files, module2, config, verbose, introspection, logger, concurrency = DEFAULT_CONCURRENCY) {
11744
11777
  const result = {
@@ -12054,7 +12087,7 @@ async function getIndexStatus(rootDir) {
12054
12087
  }
12055
12088
  return status;
12056
12089
  }
12057
- var INDEX_SCHEMA_VERSION = "1.1.0", DEFAULT_CONCURRENCY;
12090
+ var FRESHNESS_CACHE_TTL_MS = 5000, freshnessCache = null, INDEX_SCHEMA_VERSION = "2.0.0", DEFAULT_CONCURRENCY;
12058
12091
  var init_indexer = __esm(() => {
12059
12092
  init_config2();
12060
12093
  init_registry();
@@ -13635,7 +13668,7 @@ init_logger();
13635
13668
  // package.json
13636
13669
  var package_default = {
13637
13670
  name: "raggrep",
13638
- version: "0.10.0",
13671
+ version: "0.10.2",
13639
13672
  description: "Local filesystem-based RAG system for codebases - semantic search using local embeddings",
13640
13673
  type: "module",
13641
13674
  main: "./dist/index.js",
@@ -14229,4 +14262,4 @@ Run 'raggrep <command> --help' for more information.
14229
14262
  }
14230
14263
  main();
14231
14264
 
14232
- //# debugId=C678ED010B798B7464756E2164756E21
14265
+ //# debugId=04D75A20D6C87C2264756E2164756E21