@matperez/coderag 0.1.24

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 (147) hide show
  1. package/README.md +154 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/ast-chunking.d.ts +40 -0
  4. package/dist/ast-chunking.d.ts.map +1 -0
  5. package/dist/ast-chunking.js +88 -0
  6. package/dist/ast-chunking.js.map +1 -0
  7. package/dist/ast-chunking.test.d.ts +5 -0
  8. package/dist/ast-chunking.test.d.ts.map +1 -0
  9. package/dist/ast-chunking.test.js +173 -0
  10. package/dist/ast-chunking.test.js.map +1 -0
  11. package/dist/code-tokenizer.d.ts +62 -0
  12. package/dist/code-tokenizer.d.ts.map +1 -0
  13. package/dist/code-tokenizer.js +129 -0
  14. package/dist/code-tokenizer.js.map +1 -0
  15. package/dist/code-tokenizer.test.d.ts +5 -0
  16. package/dist/code-tokenizer.test.d.ts.map +1 -0
  17. package/dist/code-tokenizer.test.js +96 -0
  18. package/dist/code-tokenizer.test.js.map +1 -0
  19. package/dist/db/client-pg.d.ts +16 -0
  20. package/dist/db/client-pg.d.ts.map +1 -0
  21. package/dist/db/client-pg.js +38 -0
  22. package/dist/db/client-pg.js.map +1 -0
  23. package/dist/db/client.d.ts +36 -0
  24. package/dist/db/client.d.ts.map +1 -0
  25. package/dist/db/client.js +81 -0
  26. package/dist/db/client.js.map +1 -0
  27. package/dist/db/migrations-pg.d.ts +6 -0
  28. package/dist/db/migrations-pg.d.ts.map +1 -0
  29. package/dist/db/migrations-pg.js +88 -0
  30. package/dist/db/migrations-pg.js.map +1 -0
  31. package/dist/db/migrations.d.ts +9 -0
  32. package/dist/db/migrations.d.ts.map +1 -0
  33. package/dist/db/migrations.js +164 -0
  34. package/dist/db/migrations.js.map +1 -0
  35. package/dist/db/schema-pg.d.ts +611 -0
  36. package/dist/db/schema-pg.d.ts.map +1 -0
  37. package/dist/db/schema-pg.js +66 -0
  38. package/dist/db/schema-pg.js.map +1 -0
  39. package/dist/db/schema.d.ts +630 -0
  40. package/dist/db/schema.d.ts.map +1 -0
  41. package/dist/db/schema.js +85 -0
  42. package/dist/db/schema.js.map +1 -0
  43. package/dist/embeddings.d.ts +92 -0
  44. package/dist/embeddings.d.ts.map +1 -0
  45. package/dist/embeddings.js +275 -0
  46. package/dist/embeddings.js.map +1 -0
  47. package/dist/embeddings.test.d.ts +5 -0
  48. package/dist/embeddings.test.d.ts.map +1 -0
  49. package/dist/embeddings.test.js +255 -0
  50. package/dist/embeddings.test.js.map +1 -0
  51. package/dist/hybrid-search.d.ts +47 -0
  52. package/dist/hybrid-search.d.ts.map +1 -0
  53. package/dist/hybrid-search.js +215 -0
  54. package/dist/hybrid-search.js.map +1 -0
  55. package/dist/hybrid-search.test.d.ts +5 -0
  56. package/dist/hybrid-search.test.d.ts.map +1 -0
  57. package/dist/hybrid-search.test.js +252 -0
  58. package/dist/hybrid-search.test.js.map +1 -0
  59. package/dist/incremental-tfidf.d.ts +77 -0
  60. package/dist/incremental-tfidf.d.ts.map +1 -0
  61. package/dist/incremental-tfidf.js +248 -0
  62. package/dist/incremental-tfidf.js.map +1 -0
  63. package/dist/incremental-tfidf.test.d.ts +5 -0
  64. package/dist/incremental-tfidf.test.d.ts.map +1 -0
  65. package/dist/incremental-tfidf.test.js +276 -0
  66. package/dist/incremental-tfidf.test.js.map +1 -0
  67. package/dist/index.d.ts +18 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +19 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/indexer.d.ts +205 -0
  72. package/dist/indexer.d.ts.map +1 -0
  73. package/dist/indexer.js +1331 -0
  74. package/dist/indexer.js.map +1 -0
  75. package/dist/indexer.test.d.ts +12 -0
  76. package/dist/indexer.test.d.ts.map +1 -0
  77. package/dist/indexer.test.js +471 -0
  78. package/dist/indexer.test.js.map +1 -0
  79. package/dist/language-config.d.ts +54 -0
  80. package/dist/language-config.d.ts.map +1 -0
  81. package/dist/language-config.js +75 -0
  82. package/dist/language-config.js.map +1 -0
  83. package/dist/search-cache.d.ts +63 -0
  84. package/dist/search-cache.d.ts.map +1 -0
  85. package/dist/search-cache.js +118 -0
  86. package/dist/search-cache.js.map +1 -0
  87. package/dist/search-cache.test.d.ts +5 -0
  88. package/dist/search-cache.test.d.ts.map +1 -0
  89. package/dist/search-cache.test.js +194 -0
  90. package/dist/search-cache.test.js.map +1 -0
  91. package/dist/storage-factory.d.ts +11 -0
  92. package/dist/storage-factory.d.ts.map +1 -0
  93. package/dist/storage-factory.js +17 -0
  94. package/dist/storage-factory.js.map +1 -0
  95. package/dist/storage-persistent-pg.d.ts +75 -0
  96. package/dist/storage-persistent-pg.d.ts.map +1 -0
  97. package/dist/storage-persistent-pg.js +579 -0
  98. package/dist/storage-persistent-pg.js.map +1 -0
  99. package/dist/storage-persistent-pg.test.d.ts +7 -0
  100. package/dist/storage-persistent-pg.test.d.ts.map +1 -0
  101. package/dist/storage-persistent-pg.test.js +90 -0
  102. package/dist/storage-persistent-pg.test.js.map +1 -0
  103. package/dist/storage-persistent-types.d.ts +110 -0
  104. package/dist/storage-persistent-types.d.ts.map +1 -0
  105. package/dist/storage-persistent-types.js +5 -0
  106. package/dist/storage-persistent-types.js.map +1 -0
  107. package/dist/storage-persistent.d.ts +231 -0
  108. package/dist/storage-persistent.d.ts.map +1 -0
  109. package/dist/storage-persistent.js +897 -0
  110. package/dist/storage-persistent.js.map +1 -0
  111. package/dist/storage-persistent.test.d.ts +5 -0
  112. package/dist/storage-persistent.test.d.ts.map +1 -0
  113. package/dist/storage-persistent.test.js +325 -0
  114. package/dist/storage-persistent.test.js.map +1 -0
  115. package/dist/storage.d.ts +63 -0
  116. package/dist/storage.d.ts.map +1 -0
  117. package/dist/storage.js +67 -0
  118. package/dist/storage.js.map +1 -0
  119. package/dist/storage.test.d.ts +5 -0
  120. package/dist/storage.test.d.ts.map +1 -0
  121. package/dist/storage.test.js +157 -0
  122. package/dist/storage.test.js.map +1 -0
  123. package/dist/tfidf.d.ts +97 -0
  124. package/dist/tfidf.d.ts.map +1 -0
  125. package/dist/tfidf.js +308 -0
  126. package/dist/tfidf.js.map +1 -0
  127. package/dist/tfidf.test.d.ts +5 -0
  128. package/dist/tfidf.test.d.ts.map +1 -0
  129. package/dist/tfidf.test.js +181 -0
  130. package/dist/tfidf.test.js.map +1 -0
  131. package/dist/utils.d.ts +61 -0
  132. package/dist/utils.d.ts.map +1 -0
  133. package/dist/utils.js +264 -0
  134. package/dist/utils.js.map +1 -0
  135. package/dist/utils.test.d.ts +5 -0
  136. package/dist/utils.test.d.ts.map +1 -0
  137. package/dist/utils.test.js +94 -0
  138. package/dist/utils.test.js.map +1 -0
  139. package/dist/vector-storage.d.ts +120 -0
  140. package/dist/vector-storage.d.ts.map +1 -0
  141. package/dist/vector-storage.js +264 -0
  142. package/dist/vector-storage.js.map +1 -0
  143. package/dist/vector-storage.test.d.ts +5 -0
  144. package/dist/vector-storage.test.d.ts.map +1 -0
  145. package/dist/vector-storage.test.js +345 -0
  146. package/dist/vector-storage.test.js.map +1 -0
  147. package/package.json +85 -0
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Tests for TF-IDF search functionality (StarCoder2 tokenizer)
3
+ */
4
+ import { beforeAll, describe, expect, it } from 'vitest';
5
+ import { buildSearchIndex, calculateCosineSimilarity, initializeTokenizer, searchDocuments, tokenize, } from './tfidf.js';
6
+ // Skip if running in CI without model cache
7
+ const shouldSkip = process.env.CI === 'true' && !process.env.HF_HOME;
8
+ describe('TF-IDF', () => {
9
+ beforeAll(async () => {
10
+ if (shouldSkip)
11
+ return;
12
+ // Initialize tokenizer once for all tests
13
+ await initializeTokenizer();
14
+ }, 60000);
15
+ describe('tokenize', () => {
16
+ it.skipIf(shouldSkip)('should tokenize code', async () => {
17
+ const text = 'function getUserData() { return user.data; }';
18
+ const tokens = await tokenize(text);
19
+ expect(tokens.length).toBeGreaterThan(0);
20
+ });
21
+ it.skipIf(shouldSkip)('should handle empty input', async () => {
22
+ const tokens = await tokenize('');
23
+ expect(tokens).toEqual([]);
24
+ });
25
+ });
26
+ describe('buildSearchIndex', () => {
27
+ it.skipIf(shouldSkip)('should build index for single document', async () => {
28
+ const documents = [{ uri: 'file://test.ts', content: 'function getUserData() { return user.data; }' }];
29
+ const index = await buildSearchIndex(documents);
30
+ expect(index.documents).toHaveLength(1);
31
+ expect(index.idf).toBeDefined();
32
+ expect(index.totalDocuments).toBe(1);
33
+ expect(index.documents[0].uri).toBe('file://test.ts');
34
+ });
35
+ it.skipIf(shouldSkip)('should build index for multiple documents', async () => {
36
+ const documents = [
37
+ { uri: 'file://user.ts', content: 'class User { getData() { return this.data; } }' },
38
+ {
39
+ uri: 'file://auth.ts',
40
+ content: 'function authenticate(user, password) { return true; }',
41
+ },
42
+ ];
43
+ const index = await buildSearchIndex(documents);
44
+ expect(index.documents).toHaveLength(2);
45
+ expect(index.totalDocuments).toBe(2);
46
+ });
47
+ it.skipIf(shouldSkip)('should calculate IDF for terms', async () => {
48
+ const documents = [
49
+ { uri: 'file://1.ts', content: 'user data' },
50
+ { uri: 'file://2.ts', content: 'user authentication' },
51
+ { uri: 'file://3.ts', content: 'admin data' },
52
+ ];
53
+ const index = await buildSearchIndex(documents);
54
+ // Should have IDF scores for terms
55
+ expect(index.idf.size).toBeGreaterThan(0);
56
+ });
57
+ it.skipIf(shouldSkip)('should handle empty documents', async () => {
58
+ const documents = [];
59
+ const index = await buildSearchIndex(documents);
60
+ expect(index.documents).toHaveLength(0);
61
+ expect(index.totalDocuments).toBe(0);
62
+ });
63
+ });
64
+ describe('searchDocuments', () => {
65
+ let testIndex;
66
+ beforeAll(async () => {
67
+ if (shouldSkip)
68
+ return;
69
+ testIndex = await buildSearchIndex([
70
+ { uri: 'file://user.ts', content: 'class User { getName() { return this.name; } }' },
71
+ {
72
+ uri: 'file://auth.ts',
73
+ content: 'function authenticateUser(username, password) { return true; }',
74
+ },
75
+ {
76
+ uri: 'file://admin.ts',
77
+ content: 'class Admin extends User { getPermissions() { return []; } }',
78
+ },
79
+ ]);
80
+ });
81
+ it.skipIf(shouldSkip)('should find relevant documents', async () => {
82
+ const results = await searchDocuments('user', testIndex);
83
+ expect(results.length).toBeGreaterThanOrEqual(0);
84
+ });
85
+ it.skipIf(shouldSkip)('should rank by relevance', async () => {
86
+ const results = await searchDocuments('user authentication', testIndex);
87
+ // First result should have highest score
88
+ for (let i = 1; i < results.length; i++) {
89
+ expect(results[i - 1].score).toBeGreaterThanOrEqual(results[i].score);
90
+ }
91
+ });
92
+ it.skipIf(shouldSkip)('should return matched terms', async () => {
93
+ const results = await searchDocuments('user name', testIndex);
94
+ if (results.length > 0) {
95
+ expect(results[0].matchedTerms).toBeDefined();
96
+ }
97
+ });
98
+ it.skipIf(shouldSkip)('should respect limit option', async () => {
99
+ const results = await searchDocuments('user', testIndex, { limit: 1 });
100
+ expect(results.length).toBeLessThanOrEqual(1);
101
+ });
102
+ it.skipIf(shouldSkip)('should respect minScore option', async () => {
103
+ const results = await searchDocuments('user', testIndex, { minScore: 0.5 });
104
+ for (const result of results) {
105
+ expect(result.score).toBeGreaterThanOrEqual(0.5);
106
+ }
107
+ });
108
+ it.skipIf(shouldSkip)('should handle queries with no matches', async () => {
109
+ const results = await searchDocuments('nonexistent_term_xyz', testIndex);
110
+ // Filter for documents with score > 0
111
+ const relevantResults = results.filter((r) => r.score > 0);
112
+ expect(relevantResults).toHaveLength(0);
113
+ });
114
+ it.skipIf(shouldSkip)('should handle empty query', async () => {
115
+ const results = await searchDocuments('', testIndex);
116
+ // Empty query returns no results or all with 0 score
117
+ const relevantResults = results.filter((r) => r.score > 0);
118
+ expect(relevantResults).toHaveLength(0);
119
+ });
120
+ });
121
+ describe('calculateCosineSimilarity', () => {
122
+ it('should return 1 for identical vectors', () => {
123
+ const queryVec = new Map([
124
+ ['a', 0.5],
125
+ ['b', 0.5],
126
+ ]);
127
+ const docVec = {
128
+ uri: 'test',
129
+ terms: new Map([
130
+ ['a', 0.5],
131
+ ['b', 0.5],
132
+ ]),
133
+ rawTerms: new Map(),
134
+ magnitude: Math.sqrt(0.5 * 0.5 + 0.5 * 0.5),
135
+ };
136
+ const similarity = calculateCosineSimilarity(queryVec, docVec);
137
+ expect(similarity).toBeCloseTo(1, 5);
138
+ });
139
+ it('should return 0 for orthogonal vectors', () => {
140
+ const queryVec = new Map([['a', 1]]);
141
+ const docVec = {
142
+ uri: 'test',
143
+ terms: new Map([['b', 1]]),
144
+ rawTerms: new Map(),
145
+ magnitude: 1,
146
+ };
147
+ const similarity = calculateCosineSimilarity(queryVec, docVec);
148
+ expect(similarity).toBe(0);
149
+ });
150
+ it('should return value between 0 and 1', () => {
151
+ const queryVec = new Map([
152
+ ['a', 0.5],
153
+ ['b', 0.3],
154
+ ]);
155
+ const docVec = {
156
+ uri: 'test',
157
+ terms: new Map([
158
+ ['a', 0.3],
159
+ ['c', 0.4],
160
+ ]),
161
+ rawTerms: new Map(),
162
+ magnitude: Math.sqrt(0.3 * 0.3 + 0.4 * 0.4),
163
+ };
164
+ const similarity = calculateCosineSimilarity(queryVec, docVec);
165
+ expect(similarity).toBeGreaterThanOrEqual(0);
166
+ expect(similarity).toBeLessThanOrEqual(1);
167
+ });
168
+ it('should handle empty vectors', () => {
169
+ const queryVec = new Map();
170
+ const docVec = {
171
+ uri: 'test',
172
+ terms: new Map([['a', 1]]),
173
+ rawTerms: new Map(),
174
+ magnitude: 1,
175
+ };
176
+ const similarity = calculateCosineSimilarity(queryVec, docVec);
177
+ expect(similarity).toBe(0);
178
+ });
179
+ });
180
+ });
181
+ //# sourceMappingURL=tfidf.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tfidf.test.js","sourceRoot":"","sources":["../src/tfidf.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * File scanning utilities for codebase indexing
3
+ */
4
+ import { type Ignore } from 'ignore';
5
+ export type { Ignore };
6
+ /**
7
+ * Detect programming language from file extension
8
+ */
9
+ export declare function detectLanguage(filePath: string): string | undefined;
10
+ /**
11
+ * Check if file is text-based (not binary)
12
+ */
13
+ export declare function isTextFile(filePath: string): boolean;
14
+ /**
15
+ * Load .gitignore file and create ignore filter
16
+ */
17
+ export declare function loadGitignore(codebaseRoot: string): Ignore;
18
+ /**
19
+ * Scan directory recursively for files
20
+ */
21
+ export interface ScanOptions {
22
+ ignoreFilter?: Ignore;
23
+ codebaseRoot?: string;
24
+ maxFileSize?: number;
25
+ }
26
+ export interface ScanResult {
27
+ path: string;
28
+ absolutePath: string;
29
+ content: string;
30
+ size: number;
31
+ mtime: number;
32
+ language?: string;
33
+ }
34
+ /**
35
+ * File metadata without content (memory optimization)
36
+ */
37
+ export interface FileMetadata {
38
+ path: string;
39
+ absolutePath: string;
40
+ size: number;
41
+ mtime: number;
42
+ language?: string;
43
+ }
44
+ /**
45
+ * Scan files in directory with .gitignore support
46
+ */
47
+ export declare function scanFiles(dir: string, options?: ScanOptions): ScanResult[];
48
+ /**
49
+ * Scan file metadata only (without reading content) - Memory optimization
50
+ * Returns generator that yields file metadata one at a time
51
+ */
52
+ export declare function scanFileMetadata(dir: string, options?: ScanOptions): Generator<FileMetadata>;
53
+ /**
54
+ * Read file content (separate from scanning for memory efficiency)
55
+ */
56
+ export declare function readFileContent(absolutePath: string): string | null;
57
+ /**
58
+ * Calculate simple hash for file content (for change detection)
59
+ */
60
+ export declare function simpleHash(content: string): string;
61
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAe,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE5C,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA4BnE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAgDpD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAyC1D;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,EAAE,CA4D9E;AAED;;;GAGG;AACH,wBAAiB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,SAAS,CAAC,YAAY,CAAC,CAsDjG;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMnE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQlD"}
package/dist/utils.js ADDED
@@ -0,0 +1,264 @@
1
+ /**
2
+ * File scanning utilities for codebase indexing
3
+ */
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import ignore from 'ignore';
7
+ /**
8
+ * Detect programming language from file extension
9
+ */
10
+ export function detectLanguage(filePath) {
11
+ const ext = path.extname(filePath).toLowerCase();
12
+ const languageMap = {
13
+ '.ts': 'TypeScript',
14
+ '.tsx': 'TSX',
15
+ '.js': 'JavaScript',
16
+ '.jsx': 'JSX',
17
+ '.py': 'Python',
18
+ '.java': 'Java',
19
+ '.go': 'Go',
20
+ '.rs': 'Rust',
21
+ '.c': 'C',
22
+ '.cpp': 'C++',
23
+ '.cs': 'C#',
24
+ '.rb': 'Ruby',
25
+ '.php': 'PHP',
26
+ '.swift': 'Swift',
27
+ '.kt': 'Kotlin',
28
+ '.md': 'Markdown',
29
+ '.json': 'JSON',
30
+ '.yaml': 'YAML',
31
+ '.yml': 'YAML',
32
+ '.toml': 'TOML',
33
+ '.sql': 'SQL',
34
+ '.sh': 'Shell',
35
+ '.bash': 'Bash',
36
+ };
37
+ return languageMap[ext];
38
+ }
39
+ /**
40
+ * Check if file is text-based (not binary)
41
+ */
42
+ export function isTextFile(filePath) {
43
+ const textExtensions = new Set([
44
+ '.ts',
45
+ '.tsx',
46
+ '.js',
47
+ '.jsx',
48
+ '.py',
49
+ '.java',
50
+ '.go',
51
+ '.rs',
52
+ '.c',
53
+ '.cpp',
54
+ '.h',
55
+ '.hpp',
56
+ '.cs',
57
+ '.rb',
58
+ '.php',
59
+ '.swift',
60
+ '.kt',
61
+ '.md',
62
+ '.txt',
63
+ '.json',
64
+ '.yaml',
65
+ '.yml',
66
+ '.toml',
67
+ '.xml',
68
+ '.sql',
69
+ '.sh',
70
+ '.bash',
71
+ '.zsh',
72
+ '.fish',
73
+ '.dockerfile',
74
+ '.gitignore',
75
+ '.env',
76
+ '.config',
77
+ ]);
78
+ const ext = path.extname(filePath).toLowerCase();
79
+ const basename = path.basename(filePath).toLowerCase();
80
+ // Check extension or common config files without extensions
81
+ return (textExtensions.has(ext) ||
82
+ basename === 'dockerfile' ||
83
+ basename === 'makefile' ||
84
+ basename === '.gitignore' ||
85
+ basename.startsWith('.env'));
86
+ }
87
+ /**
88
+ * Load .gitignore file and create ignore filter
89
+ */
90
+ export function loadGitignore(codebaseRoot) {
91
+ const ig = ignore();
92
+ // Add default ignore patterns
93
+ ig.add([
94
+ 'node_modules',
95
+ '.git',
96
+ '.svn',
97
+ '.hg',
98
+ '.DS_Store',
99
+ '.idea',
100
+ '.vscode',
101
+ '*.suo',
102
+ '*.ntvs*',
103
+ '*.njsproj',
104
+ '*.sln',
105
+ '*.swp',
106
+ '.cache',
107
+ 'dist',
108
+ 'build',
109
+ 'coverage',
110
+ '.nyc_output',
111
+ '*.log',
112
+ 'tmp',
113
+ 'temp',
114
+ // Coderag storage folder (prevent scanning own index)
115
+ '.coderag',
116
+ ]);
117
+ const gitignorePath = path.join(codebaseRoot, '.gitignore');
118
+ if (fs.existsSync(gitignorePath)) {
119
+ try {
120
+ const content = fs.readFileSync(gitignorePath, 'utf8');
121
+ ig.add(content);
122
+ }
123
+ catch (error) {
124
+ console.error(`[ERROR] Failed to read .gitignore: ${error}`);
125
+ }
126
+ }
127
+ return ig;
128
+ }
129
+ /**
130
+ * Scan files in directory with .gitignore support
131
+ */
132
+ export function scanFiles(dir, options = {}) {
133
+ const results = [];
134
+ const ignoreFilter = options.ignoreFilter;
135
+ const codebaseRoot = options.codebaseRoot || dir;
136
+ const maxFileSize = options.maxFileSize || 1024 * 1024; // 1MB default
137
+ function scan(currentDir) {
138
+ let entries;
139
+ try {
140
+ entries = fs.readdirSync(currentDir, { withFileTypes: true });
141
+ }
142
+ catch (_error) {
143
+ // Skip directories that can't be read (permissions, etc.)
144
+ return;
145
+ }
146
+ for (const entry of entries) {
147
+ const fullPath = path.join(currentDir, entry.name);
148
+ const relativePath = path.relative(codebaseRoot, fullPath);
149
+ // Skip ignored files
150
+ if (ignoreFilter?.ignores(relativePath)) {
151
+ continue;
152
+ }
153
+ if (entry.isDirectory()) {
154
+ scan(fullPath);
155
+ }
156
+ else if (entry.isFile()) {
157
+ try {
158
+ const stats = fs.statSync(fullPath);
159
+ // Skip files that are too large
160
+ if (stats.size > maxFileSize) {
161
+ continue;
162
+ }
163
+ // Only process text files
164
+ if (!isTextFile(fullPath)) {
165
+ continue;
166
+ }
167
+ const content = fs.readFileSync(fullPath, 'utf8');
168
+ results.push({
169
+ path: relativePath,
170
+ absolutePath: fullPath,
171
+ content,
172
+ size: stats.size,
173
+ mtime: stats.mtimeMs,
174
+ language: detectLanguage(fullPath),
175
+ });
176
+ }
177
+ catch (_error) {
178
+ // Skip files that can't be read (permissions, etc.)
179
+ console.warn(`[WARN] Failed to read file: ${relativePath}`);
180
+ }
181
+ }
182
+ }
183
+ }
184
+ scan(dir);
185
+ return results;
186
+ }
187
+ /**
188
+ * Scan file metadata only (without reading content) - Memory optimization
189
+ * Returns generator that yields file metadata one at a time
190
+ */
191
+ export function* scanFileMetadata(dir, options = {}) {
192
+ const ignoreFilter = options.ignoreFilter;
193
+ const codebaseRoot = options.codebaseRoot || dir;
194
+ const maxFileSize = options.maxFileSize || 1024 * 1024; // 1MB default
195
+ function* scan(currentDir) {
196
+ let entries;
197
+ try {
198
+ entries = fs.readdirSync(currentDir, { withFileTypes: true });
199
+ }
200
+ catch (_error) {
201
+ // Skip directories that can't be read (permissions, etc.)
202
+ return;
203
+ }
204
+ for (const entry of entries) {
205
+ const fullPath = path.join(currentDir, entry.name);
206
+ const relativePath = path.relative(codebaseRoot, fullPath);
207
+ // Skip ignored files
208
+ if (ignoreFilter?.ignores(relativePath)) {
209
+ continue;
210
+ }
211
+ if (entry.isDirectory()) {
212
+ yield* scan(fullPath);
213
+ }
214
+ else if (entry.isFile()) {
215
+ try {
216
+ const stats = fs.statSync(fullPath);
217
+ // Skip files that are too large
218
+ if (stats.size > maxFileSize) {
219
+ continue;
220
+ }
221
+ // Only process text files
222
+ if (!isTextFile(fullPath)) {
223
+ continue;
224
+ }
225
+ yield {
226
+ path: relativePath,
227
+ absolutePath: fullPath,
228
+ size: stats.size,
229
+ mtime: stats.mtimeMs,
230
+ language: detectLanguage(fullPath),
231
+ };
232
+ }
233
+ catch (_error) {
234
+ // Skip files that can't be read (permissions, etc.)
235
+ }
236
+ }
237
+ }
238
+ }
239
+ yield* scan(dir);
240
+ }
241
+ /**
242
+ * Read file content (separate from scanning for memory efficiency)
243
+ */
244
+ export function readFileContent(absolutePath) {
245
+ try {
246
+ return fs.readFileSync(absolutePath, 'utf8');
247
+ }
248
+ catch (_error) {
249
+ return null;
250
+ }
251
+ }
252
+ /**
253
+ * Calculate simple hash for file content (for change detection)
254
+ */
255
+ export function simpleHash(content) {
256
+ let hash = 0;
257
+ for (let i = 0; i < content.length; i++) {
258
+ const char = content.charCodeAt(i);
259
+ hash = (hash << 5) - hash + char;
260
+ hash &= hash; // Convert to 32-bit integer
261
+ }
262
+ return hash.toString(36);
263
+ }
264
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for utility functions
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../src/utils.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Tests for utility functions
3
+ */
4
+ import { describe, expect, it } from 'vitest';
5
+ import { detectLanguage, isTextFile, simpleHash } from './utils.js';
6
+ describe('utils', () => {
7
+ describe('simpleHash', () => {
8
+ it('should generate consistent hash for same input', () => {
9
+ const content = 'test content';
10
+ const hash1 = simpleHash(content);
11
+ const hash2 = simpleHash(content);
12
+ expect(hash1).toBe(hash2);
13
+ });
14
+ it('should generate different hashes for different inputs', () => {
15
+ const hash1 = simpleHash('content1');
16
+ const hash2 = simpleHash('content2');
17
+ expect(hash1).not.toBe(hash2);
18
+ });
19
+ it('should handle empty string', () => {
20
+ const hash = simpleHash('');
21
+ expect(hash).toBeDefined();
22
+ expect(typeof hash).toBe('string');
23
+ });
24
+ it('should handle unicode characters', () => {
25
+ const hash1 = simpleHash('hello 世界');
26
+ const hash2 = simpleHash('hello 世界');
27
+ expect(hash1).toBe(hash2);
28
+ });
29
+ });
30
+ describe('detectLanguage', () => {
31
+ it('should detect TypeScript', () => {
32
+ expect(detectLanguage('test.ts')).toBe('TypeScript');
33
+ expect(detectLanguage('test.tsx')).toBe('TSX');
34
+ });
35
+ it('should detect JavaScript', () => {
36
+ expect(detectLanguage('test.js')).toBe('JavaScript');
37
+ expect(detectLanguage('test.jsx')).toBe('JSX');
38
+ });
39
+ it('should detect Python', () => {
40
+ expect(detectLanguage('test.py')).toBe('Python');
41
+ });
42
+ it('should detect Go', () => {
43
+ expect(detectLanguage('test.go')).toBe('Go');
44
+ });
45
+ it('should detect Rust', () => {
46
+ expect(detectLanguage('test.rs')).toBe('Rust');
47
+ });
48
+ it('should detect JSON', () => {
49
+ expect(detectLanguage('test.json')).toBe('JSON');
50
+ expect(detectLanguage('package.json')).toBe('JSON');
51
+ });
52
+ it('should detect YAML', () => {
53
+ expect(detectLanguage('test.yaml')).toBe('YAML');
54
+ expect(detectLanguage('test.yml')).toBe('YAML');
55
+ });
56
+ it('should detect Markdown', () => {
57
+ expect(detectLanguage('README.md')).toBe('Markdown');
58
+ });
59
+ it('should return undefined for unknown extensions', () => {
60
+ expect(detectLanguage('test.xyz')).toBeUndefined();
61
+ expect(detectLanguage('no-extension')).toBeUndefined();
62
+ });
63
+ it('should be case-insensitive', () => {
64
+ expect(detectLanguage('TEST.TS')).toBe('TypeScript');
65
+ expect(detectLanguage('Test.Js')).toBe('JavaScript');
66
+ });
67
+ });
68
+ describe('isTextFile', () => {
69
+ it('should return true for text files', () => {
70
+ expect(isTextFile('test.ts')).toBe(true);
71
+ expect(isTextFile('test.js')).toBe(true);
72
+ expect(isTextFile('test.py')).toBe(true);
73
+ expect(isTextFile('test.md')).toBe(true);
74
+ expect(isTextFile('test.json')).toBe(true);
75
+ expect(isTextFile('test.txt')).toBe(true);
76
+ });
77
+ it('should return false for binary files', () => {
78
+ expect(isTextFile('image.png')).toBe(false);
79
+ expect(isTextFile('image.jpg')).toBe(false);
80
+ expect(isTextFile('image.gif')).toBe(false);
81
+ expect(isTextFile('file.pdf')).toBe(false);
82
+ expect(isTextFile('archive.zip')).toBe(false);
83
+ expect(isTextFile('binary.exe')).toBe(false);
84
+ });
85
+ it('should return false for files without extension', () => {
86
+ expect(isTextFile('no-extension')).toBe(false);
87
+ });
88
+ it('should be case-insensitive', () => {
89
+ expect(isTextFile('TEST.TS')).toBe(true);
90
+ expect(isTextFile('IMAGE.PNG')).toBe(false);
91
+ });
92
+ });
93
+ });
94
+ //# sourceMappingURL=utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../src/utils.test.ts"],"names":[],"mappings":"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"}