raggrep 0.14.2 → 0.15.0

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 (36) hide show
  1. package/dist/app/search/index.d.ts +16 -0
  2. package/dist/cli/main.js +714 -260
  3. package/dist/cli/main.js.map +20 -15
  4. package/dist/domain/entities/index.d.ts +1 -1
  5. package/dist/domain/entities/searchResult.d.ts +54 -0
  6. package/dist/domain/ports/filesystem.d.ts +3 -1
  7. package/dist/domain/services/index.d.ts +1 -0
  8. package/dist/domain/services/simpleSearch.d.ts +75 -0
  9. package/dist/domain/usecases/exactSearch.d.ts +53 -0
  10. package/dist/domain/usecases/index.d.ts +1 -0
  11. package/dist/index.d.ts +38 -3
  12. package/dist/index.js +673 -237
  13. package/dist/index.js.map +18 -15
  14. package/dist/types.d.ts +1 -1
  15. package/package.json +2 -1
  16. package/dist/domain/services/bm25.test.d.ts +0 -4
  17. package/dist/domain/services/configValidator.test.d.ts +0 -1
  18. package/dist/domain/services/conventions/conventions.test.d.ts +0 -4
  19. package/dist/domain/services/introspection.test.d.ts +0 -4
  20. package/dist/domain/services/jsonPathExtractor.test.d.ts +0 -4
  21. package/dist/domain/services/lexicon.test.d.ts +0 -6
  22. package/dist/domain/services/literalExtractor.test.d.ts +0 -6
  23. package/dist/domain/services/phraseMatch.test.d.ts +0 -4
  24. package/dist/domain/services/queryLiteralParser.test.d.ts +0 -7
  25. package/dist/infrastructure/embeddings/embeddings.test.d.ts +0 -4
  26. package/dist/infrastructure/parsing/parsing.test.d.ts +0 -10
  27. package/dist/modules/core/symbols.test.d.ts +0 -4
  28. package/dist/modules/language/go/index.test.d.ts +0 -1
  29. package/dist/modules/language/rust/index.test.d.ts +0 -1
  30. package/dist/modules/language/typescript/parseCode.test.d.ts +0 -4
  31. package/dist/tests/integration.test.d.ts +0 -9
  32. package/dist/tests/ranking.test.d.ts +0 -12
  33. package/dist/tests/simulation-phrase-matching.test.d.ts +0 -14
  34. package/dist/tests/simulation-vocabulary.test.d.ts +0 -17
  35. package/dist/tests/vocabulary-scoring.test.d.ts +0 -16
  36. package/dist/tests/vocabulary.test.d.ts +0 -10
@@ -8,7 +8,7 @@ export type { Chunk, ChunkType } from "./chunk";
8
8
  export { createChunkId } from "./chunk";
9
9
  export type { FileIndex, FileManifestEntry, ModuleManifest, GlobalManifest, } from "./fileIndex";
10
10
  export type { FileSummary, SymbolicIndexMeta, Tier1Manifest, } from "./fileSummary";
11
- export type { SearchResult, SearchOptions, SearchContributions, CoreContribution, LanguageContribution, IntrospectionContribution, } from "./searchResult";
11
+ export type { SearchResult, SearchOptions, SearchContributions, CoreContribution, LanguageContribution, IntrospectionContribution, ExactMatchOccurrence, ExactMatchFile, ExactMatchResults, HybridSearchResults, } from "./searchResult";
12
12
  export { DEFAULT_SEARCH_OPTIONS } from "./searchResult";
13
13
  export type { Config, ModuleConfig } from "./config";
14
14
  export { DEFAULT_IGNORE_PATHS, DEFAULT_EXTENSIONS, createDefaultConfig, } from "./config";
@@ -104,3 +104,57 @@ export interface SearchOptions {
104
104
  * Default search options.
105
105
  */
106
106
  export declare const DEFAULT_SEARCH_OPTIONS: Required<SearchOptions>;
107
+ /**
108
+ * A single exact match occurrence in a file.
109
+ * Represents a grep-like match with surrounding context.
110
+ */
111
+ export interface ExactMatchOccurrence {
112
+ /** Line number where the match was found (1-indexed) */
113
+ line: number;
114
+ /** Column where the match starts (0-indexed) */
115
+ column: number;
116
+ /** The full line containing the match */
117
+ lineContent: string;
118
+ /** Line before the match (if available) */
119
+ contextBefore?: string;
120
+ /** Line after the match (if available) */
121
+ contextAfter?: string;
122
+ }
123
+ /**
124
+ * Exact matches found in a single file.
125
+ */
126
+ export interface ExactMatchFile {
127
+ /** Path to the file */
128
+ filepath: string;
129
+ /** All occurrences of the literal in this file */
130
+ occurrences: ExactMatchOccurrence[];
131
+ /** Total number of matches in this file */
132
+ matchCount: number;
133
+ }
134
+ /**
135
+ * Result of exact/literal search across the codebase.
136
+ * This is separate from semantic search results.
137
+ */
138
+ export interface ExactMatchResults {
139
+ /** The literal that was searched for */
140
+ query: string;
141
+ /** Files containing exact matches, sorted by match count */
142
+ files: ExactMatchFile[];
143
+ /** Total number of matches across all files */
144
+ totalMatches: number;
145
+ /** Total number of files with matches */
146
+ totalFiles: number;
147
+ /** Whether results were truncated (more matches exist) */
148
+ truncated: boolean;
149
+ }
150
+ /**
151
+ * Combined search results with both semantic and exact match tracks.
152
+ */
153
+ export interface HybridSearchResults {
154
+ /** Semantic/BM25 search results (existing behavior) */
155
+ results: SearchResult[];
156
+ /** Exact match results for literal queries (optional) */
157
+ exactMatches?: ExactMatchResults;
158
+ /** Whether exact matches influenced the semantic result ranking */
159
+ fusionApplied: boolean;
160
+ }
@@ -10,8 +10,10 @@
10
10
  export interface FileStats {
11
11
  /** ISO timestamp of last modification */
12
12
  lastModified: string;
13
- /** File size in bytes */
13
+ /** File size in bytes (undefined for directories) */
14
14
  size?: number;
15
+ /** Whether this is a directory */
16
+ isDirectory?: boolean;
15
17
  }
16
18
  /**
17
19
  * Abstract filesystem interface.
@@ -17,3 +17,4 @@ export { extractJsonPaths, extractJsonKeywords } from "./jsonPathExtractor";
17
17
  export { introspectFile, findNearestReadme, introspectionToKeywords, detectScopeFromName, findProjectForFile, calculateIntrospectionBoost, type IntrospectFileOptions, } from "./introspection";
18
18
  export { validateConfig, formatValidationIssues, type ValidationIssue, type ValidationResult, } from "./configValidator";
19
19
  export { calculatePhraseMatch, hasExactPhrase, calculateTokenCoverage, tokenizeForMatching, PHRASE_MATCH_CONSTANTS, type PhraseMatchResult, } from "./phraseMatch";
20
+ export { isIdentifierQuery, extractSearchLiteral, findOccurrences, searchFiles, extractIdentifiersFromContent, isSearchableContent, } from "./simpleSearch";
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Simple Search Service
3
+ *
4
+ * Provides grep-like exact text matching across files.
5
+ * This is a pure domain service - no file I/O, just algorithms.
6
+ *
7
+ * Used for:
8
+ * - Finding exact occurrences of identifiers (SCREAMING_SNAKE, camelCase)
9
+ * - Providing a guaranteed "exact match" track separate from semantic search
10
+ * - Context lines around matches (+/- 1 line)
11
+ */
12
+ import type { ExactMatchOccurrence, ExactMatchResults } from "../entities/searchResult";
13
+ /**
14
+ * Check if a query string looks like a programming identifier.
15
+ * These queries should trigger simple search in addition to semantic search.
16
+ *
17
+ * @param query - The search query
18
+ * @returns true if the query looks like an identifier
19
+ */
20
+ export declare function isIdentifierQuery(query: string): boolean;
21
+ /**
22
+ * Extract the literal to search for from a query.
23
+ * Removes quoting if present.
24
+ *
25
+ * @param query - The search query
26
+ * @returns The literal to search for
27
+ */
28
+ export declare function extractSearchLiteral(query: string): string;
29
+ /**
30
+ * Find all occurrences of a literal in file content.
31
+ *
32
+ * @param content - The file content to search
33
+ * @param literal - The exact string to find
34
+ * @param options - Search options
35
+ * @returns Array of match occurrences with context
36
+ */
37
+ export declare function findOccurrences(content: string, literal: string, options?: {
38
+ /** Maximum occurrences to return per file */
39
+ maxOccurrences?: number;
40
+ /** Whether to do case-insensitive matching */
41
+ caseInsensitive?: boolean;
42
+ }): ExactMatchOccurrence[];
43
+ /**
44
+ * Search multiple files for exact matches of a literal.
45
+ *
46
+ * @param files - Map of filepath to content
47
+ * @param literal - The exact string to find
48
+ * @param options - Search options
49
+ * @returns Exact match results
50
+ */
51
+ export declare function searchFiles(files: Map<string, string>, literal: string, options?: {
52
+ /** Maximum files to return */
53
+ maxFiles?: number;
54
+ /** Maximum occurrences per file */
55
+ maxOccurrencesPerFile?: number;
56
+ /** Case-insensitive matching */
57
+ caseInsensitive?: boolean;
58
+ }): ExactMatchResults;
59
+ /**
60
+ * Extract all identifier-like literals from content.
61
+ * Used during indexing to build a literal index for plain text files.
62
+ *
63
+ * @param content - File content to extract from
64
+ * @returns Array of unique identifier literals found
65
+ */
66
+ export declare function extractIdentifiersFromContent(content: string): string[];
67
+ /**
68
+ * Check if a file should be included in simple search based on its content.
69
+ * Excludes binary files and very large files.
70
+ *
71
+ * @param content - File content
72
+ * @param filepath - File path for extension checking
73
+ * @returns true if file should be searchable
74
+ */
75
+ export declare function isSearchableContent(content: string, filepath: string): boolean;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Exact Search Use Case
3
+ *
4
+ * Orchestrates grep-like exact text search across source files.
5
+ * This use case coordinates filesystem access and the simple search service.
6
+ */
7
+ import type { FileSystem } from "../ports";
8
+ import type { ExactMatchResults } from "../entities";
9
+ /**
10
+ * Options for exact search operation.
11
+ */
12
+ export interface ExactSearchOptions {
13
+ /** Root directory to search in */
14
+ rootDir: string;
15
+ /** The literal string to search for */
16
+ literal: string;
17
+ /** Optional path filter patterns */
18
+ pathFilter?: string[];
19
+ /** Maximum number of files to return */
20
+ maxFiles?: number;
21
+ /** Maximum occurrences per file */
22
+ maxOccurrencesPerFile?: number;
23
+ /** Case-insensitive matching */
24
+ caseInsensitive?: boolean;
25
+ }
26
+ /**
27
+ * Check if a file path matches any of the given filters.
28
+ *
29
+ * Supports two modes:
30
+ * - Glob patterns: Contains wildcards like *, ?, etc.
31
+ * - Path prefixes: Plain directory paths
32
+ *
33
+ * @param relativePath - File path relative to root
34
+ * @param filters - Array of filters (glob patterns or path prefixes)
35
+ * @param matchFn - Function to test glob patterns (e.g., minimatch)
36
+ * @returns true if the path matches any filter
37
+ */
38
+ export declare function matchesPathFilter(relativePath: string, filters: string[], matchFn: (path: string, pattern: string) => boolean): boolean;
39
+ /**
40
+ * Execute exact search across the codebase.
41
+ *
42
+ * This use case:
43
+ * 1. Walks the filesystem to find searchable files
44
+ * 2. Filters files based on path patterns
45
+ * 3. Uses the simple search service to find exact matches
46
+ * 4. Returns results sorted by match count
47
+ *
48
+ * @param fs - FileSystem implementation (injected dependency)
49
+ * @param options - Search options
50
+ * @param matchFn - Glob pattern matching function (e.g., minimatch)
51
+ * @returns Exact match results
52
+ */
53
+ export declare function executeExactSearch(fs: FileSystem, options: ExactSearchOptions, matchFn: (path: string, pattern: string) => boolean): Promise<ExactMatchResults>;
@@ -7,3 +7,4 @@
7
7
  export { indexDirectory, type IndexResult, type IndexDirectoryOptions, type IndexDirectoryDependencies } from './indexDirectory';
8
8
  export { searchIndex, formatSearchResults, type SearchIndexOptions, type SearchIndexDependencies } from './searchIndex';
9
9
  export { cleanupIndex, type CleanupResult, type CleanupIndexOptions, type CleanupIndexDependencies } from './cleanupIndex';
10
+ export { executeExactSearch, matchesPathFilter, type ExactSearchOptions, } from './exactSearch';
package/dist/index.d.ts CHANGED
@@ -31,11 +31,11 @@
31
31
  * ```
32
32
  */
33
33
  import type { IndexResult, IndexOptions, CleanupResult, CleanupOptions, ResetResult } from "./app/indexer";
34
- import { formatSearchResults } from "./app/search";
35
- import type { SearchOptions, SearchResult } from "./types";
34
+ import { formatSearchResults, formatHybridSearchResults } from "./app/search";
35
+ import type { SearchOptions, SearchResult, HybridSearchResults } from "./types";
36
36
  import { ConsoleLogger, InlineProgressLogger, SilentLogger, createLogger, createInlineLogger, createSilentLogger } from "./infrastructure/logger";
37
37
  export type { IndexResult, IndexOptions, CleanupResult, CleanupOptions, ResetResult, } from "./app/indexer";
38
- export type { SearchOptions, SearchResult, Chunk, FileIndex } from "./types";
38
+ export type { SearchOptions, SearchResult, HybridSearchResults, Chunk, FileIndex, } from "./types";
39
39
  export type { Logger, LoggerFactory } from "./domain/ports";
40
40
  export { ConsoleLogger, InlineProgressLogger, SilentLogger, createLogger, createInlineLogger, createSilentLogger, };
41
41
  /**
@@ -118,6 +118,32 @@ export declare function cleanup(directory: string, options?: CleanupOptions): Pr
118
118
  * ```
119
119
  */
120
120
  export declare function reset(directory: string): Promise<ResetResult>;
121
+ /**
122
+ * Hybrid search with both semantic and exact match tracks.
123
+ *
124
+ * Returns semantic results with optional exact match results for identifier queries.
125
+ * Exact matches are found using grep-like text search and are displayed separately.
126
+ *
127
+ * @param directory - Path to the indexed directory
128
+ * @param query - Natural language or identifier search query
129
+ * @param options - Search options
130
+ * @returns Hybrid search results with both tracks
131
+ *
132
+ * @example
133
+ * ```ts
134
+ * // Search for an identifier (triggers exact match)
135
+ * const results = await raggrep.hybridSearch('./my-project', 'AUTH_SERVICE_URL');
136
+ *
137
+ * // Check for exact matches
138
+ * if (results.exactMatches) {
139
+ * console.log(`Found ${results.exactMatches.totalMatches} exact matches`);
140
+ * }
141
+ *
142
+ * // Semantic results (with fusion boost if exact matches found)
143
+ * console.log(`${results.results.length} semantic results`);
144
+ * ```
145
+ */
146
+ export declare function hybridSearch(directory: string, query: string, options?: SearchOptions): Promise<HybridSearchResults>;
121
147
  /**
122
148
  * Format search results for display.
123
149
  *
@@ -125,11 +151,20 @@ export declare function reset(directory: string): Promise<ResetResult>;
125
151
  * @returns Formatted string for console output
126
152
  */
127
153
  export { formatSearchResults };
154
+ /**
155
+ * Format hybrid search results including exact matches.
156
+ *
157
+ * @param results - Hybrid search results
158
+ * @returns Formatted string for console output
159
+ */
160
+ export { formatHybridSearchResults };
128
161
  declare const raggrep: {
129
162
  index: typeof index;
130
163
  search: typeof search;
164
+ hybridSearch: typeof hybridSearch;
131
165
  cleanup: typeof cleanup;
132
166
  reset: typeof reset;
133
167
  formatSearchResults: typeof formatSearchResults;
168
+ formatHybridSearchResults: typeof formatHybridSearchResults;
134
169
  };
135
170
  export default raggrep;