smart-coding-mcp-gemini-milvus 1.1.0 → 1.2.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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "mcp__smart-coding-mcp__f_get_status"
5
+ ]
6
+ }
7
+ }
@@ -1,190 +1 @@
1
- {
2
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/tokenizer.js": {
3
- "hash": "8e8079f04b792cbf036279b2fb0db35e",
4
- "mtime": 1771087911134.589
5
- },
6
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/resource-throttle.js": {
7
- "hash": "4eddc24af891e87a45022da5c0addfe0",
8
- "mtime": 1771087610935.307
9
- },
10
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/config.json": {
11
- "hash": "9161b026a736806d8c73faa613d1c0b2",
12
- "mtime": 1771087580493.4426
13
- },
14
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/features/index-codebase.js": {
15
- "hash": "268e98054d4a713088ce4b08fb3c72ce",
16
- "mtime": 1771087522019.3533
17
- },
18
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/features/get-status.js": {
19
- "hash": "c73114a6b1d9d288490be33fd746f6bd",
20
- "mtime": 1771084620614.6008
21
- },
22
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/gemini-embedder.js": {
23
- "hash": "6f19eab9c428b2ee5d8dc3634b7d184c",
24
- "mtime": 1771084612777.3147
25
- },
26
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/gemini-embedder.test.js": {
27
- "hash": "bfdeb2a52d7b0a14b898518658d2cd16",
28
- "mtime": 1771084521998.729
29
- },
30
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/package-lock.json": {
31
- "hash": "2d37ce7d0f732a630d2010f02aa30683",
32
- "mtime": 1771084445053.39
33
- },
34
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/milvus-cache.js": {
35
- "hash": "aa7a1fdf3ef223bd41d7641d46e46387",
36
- "mtime": 1771084242267.3271
37
- },
38
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/package.json": {
39
- "hash": "75ce628ac7dd866af7dad0e0294a2517",
40
- "mtime": 1771084219080.064
41
- },
42
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/embedding-worker.js": {
43
- "hash": "0151b174b7184a319fc07e37b70da415",
44
- "mtime": 1771084208041.383
45
- },
46
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/mrl-embedder.js": {
47
- "hash": "864b230ac707c1c04ea765f0606ce7ac",
48
- "mtime": 1771084174768.6392
49
- },
50
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/config.js": {
51
- "hash": "098adf521b99cc9517d0ae22466f48cd",
52
- "mtime": 1771084170927.3357
53
- },
54
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/index-codebase-stats.test.js": {
55
- "hash": "c5963c1e75e69f1f2c4e485a3fd44802",
56
- "mtime": 1771077042007.516
57
- },
58
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/get-status.test.js": {
59
- "hash": "3430f4649acc851e71e5b96b952581e8",
60
- "mtime": 1771077042005.2527
61
- },
62
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/hybrid-search-ann.test.js": {
63
- "hash": "e5b74e8654c56d14f455816b4552e0f1",
64
- "mtime": 1771077042003.2507
65
- },
66
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/milvus-cache-contract.test.js": {
67
- "hash": "1d1eb913893e9ab2bd39aa7c1068197d",
68
- "mtime": 1771077042001.4485
69
- },
70
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/features/hybrid-search.js": {
71
- "hash": "087072c9a1c02e7b0f214d8ab8ae5e0b",
72
- "mtime": 1771077041995.566
73
- },
74
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/cache.js": {
75
- "hash": "334f21e2f05ca8c454e0bf6e61717ce0",
76
- "mtime": 1771077041993.4663
77
- },
78
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/sqlite-cache.js": {
79
- "hash": "b7d8e33a5ed14e44a0eee4d139351ac5",
80
- "mtime": 1771077041991.1516
81
- },
82
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/cache-factory.js": {
83
- "hash": "7779bb61cf6dc30dbfab851f7aab3694",
84
- "mtime": 1771072047648.4636
85
- },
86
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/features/set-workspace.js": {
87
- "hash": "4168a410a51d03f2bdf1a1f87d03b35a",
88
- "mtime": 1771070083275.8286
89
- },
90
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/cache-factory.test.js": {
91
- "hash": "787e29fc8dfbbfaf56922b3159d46159",
92
- "mtime": 1771069789276.2405
93
- },
94
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/device-detection.test.js": {
95
- "hash": "8ae16a6f0b93198cf3677fd7916608df",
96
- "mtime": 1771069782733.0254
97
- },
98
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/index.js": {
99
- "hash": "a4009fd24c67da4716d566a2a6243302",
100
- "mtime": 1771069757113.6812
101
- },
102
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/better-sqlite3.test.js": {
103
- "hash": "41107d0d1dc24fb598d10eddf515e2a4",
104
- "mtime": 1771068416258.471
105
- },
106
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/vitest.config.js": {
107
- "hash": "85a21c82a6d89b922fe0bf4ba7a74541",
108
- "mtime": 1771065100930.4365
109
- },
110
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/tokenizer.test.js": {
111
- "hash": "d2f29674b17ff60fe3c8675d10a191d2",
112
- "mtime": 1771065100930.324
113
- },
114
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/mrl-recovery.test.js": {
115
- "hash": "dbd0f7ddae1f1dd44413492b9fd3cf48",
116
- "mtime": 1771065100930.078
117
- },
118
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/mrl-recovery-real.test.js": {
119
- "hash": "be35979b904bff5b555a8e4b6a933ecf",
120
- "mtime": 1771065100929.9595
121
- },
122
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/mrl-embedder.test.js": {
123
- "hash": "8f13c243379bef3736409049440c7008",
124
- "mtime": 1771065100929.8054
125
- },
126
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/model-cache-recovery.test.js": {
127
- "hash": "72a56ecb446cc36eaa71ad54e7e57d1e",
128
- "mtime": 1771065100929.6157
129
- },
130
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/integration.test.js": {
131
- "hash": "8dd0dc5a16eecba17ad05f432b286895",
132
- "mtime": 1771065100929.507
133
- },
134
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/index-codebase.test.js": {
135
- "hash": "de3c8b44bf104dda118e14bb929dfd65",
136
- "mtime": 1771065100929.3975
137
- },
138
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/hybrid-search.test.js": {
139
- "hash": "06a99b26e1479f17002a1a3340837e22",
140
- "mtime": 1771065100929.2893
141
- },
142
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/helpers.js": {
143
- "hash": "29857c4325e1eecdc897afa584e8a203",
144
- "mtime": 1771065100929.032
145
- },
146
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/embedding-model.test.js": {
147
- "hash": "552b11b36718913c7b9fc5191203083e",
148
- "mtime": 1771065100928.9631
149
- },
150
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/clear-cache.test.js": {
151
- "hash": "a913875616880671553f0ad5d5b15065",
152
- "mtime": 1771065100928.6343
153
- },
154
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/check-last-version.test.js": {
155
- "hash": "24e0cf7dee2cfd1c03271f183a81a03d",
156
- "mtime": 1771065100928.2485
157
- },
158
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/test/ast-chunker.test.js": {
159
- "hash": "4d949b8eac7c83863f154b27d3aedd73",
160
- "mtime": 1771065100927.7698
161
- },
162
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/scripts/clear-cache.js": {
163
- "hash": "ca7dfeeb78157c02ba12cf4af0604566",
164
- "mtime": 1771065100927.6084
165
- },
166
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/utils.js": {
167
- "hash": "ac675071c867ddb5298692460aad9d55",
168
- "mtime": 1771065100927.1428
169
- },
170
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/project-detector.js": {
171
- "hash": "a1ed243397053c14fdac68cf9d60c2f8",
172
- "mtime": 1771065100926.347
173
- },
174
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/ignore-patterns.js": {
175
- "hash": "e416d37425878c5e2c1866f0a8bf0357",
176
- "mtime": 1771065100926.0576
177
- },
178
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/lib/ast-chunker.js": {
179
- "hash": "84fdfcba2f50cab3e303d604dfcd3b2a",
180
- "mtime": 1771065100925.265
181
- },
182
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/features/clear-cache.js": {
183
- "hash": "88a8bbc2a439bd24fd1791f92d828a3f",
184
- "mtime": 1771065100923.2666
185
- },
186
- "/Users/jun/Library/Mobile Documents/iCloud~md~obsidian/Documents/new/700_projects/smart-coding-mcp/features/check-last-version.js": {
187
- "hash": "0f4c738022fd37ef6a88472fa558675c",
188
- "mtime": 1771065100923.1416
189
- }
190
- }
1
+ {}
@@ -407,6 +407,7 @@ export class CodebaseIndexer {
407
407
  // Extract directory names from glob patterns in config.excludePatterns
408
408
  // Patterns like "**/node_modules/**" -> "node_modules"
409
409
  const excludeDirs = new Set();
410
+ const excludeFilePatterns = [];
410
411
  for (const pattern of this.config.excludePatterns) {
411
412
  // Extract directory names from glob patterns
412
413
  const match = pattern.match(/\*\*\/([^/*]+)\/?\*?\*?$/);
@@ -418,19 +419,69 @@ export class CodebaseIndexer {
418
419
  if (match2) {
419
420
  excludeDirs.add(match2[1]);
420
421
  }
422
+ // Extract file-level glob patterns like **/*.test.js, **/test_*.py
423
+ const fileMatch = pattern.match(/\*\*\/(\*[^/]+|[^/*]+\*[^/]*)$/);
424
+ if (fileMatch) {
425
+ const glob = fileMatch[1];
426
+ // Convert glob to regex: *.test.js -> /\.test\.js$/, test_*.py -> /^test_.*\.py$/
427
+ const escaped = glob
428
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
429
+ .replace(/\*/g, '.*');
430
+ try {
431
+ excludeFilePatterns.push(new RegExp(`^${escaped}$`));
432
+ } catch {
433
+ // skip invalid patterns
434
+ }
435
+ }
421
436
  }
422
437
 
423
438
  // Always exclude cache directory
424
439
  excludeDirs.add(".smart-coding-cache");
425
440
 
441
+ const isExcludedDirectory = (dirName) => {
442
+ if (!dirName) {
443
+ return false;
444
+ }
445
+
446
+ const normalized = dirName.replace(/[\\/]+$/g, "");
447
+ if (excludeDirs.has(normalized)) {
448
+ return true;
449
+ }
450
+
451
+ const normalizedSegments = normalized.split(/[\\/]+/);
452
+ if (normalizedSegments.some((segment) => excludeDirs.has(segment))) {
453
+ return true;
454
+ }
455
+
456
+ const basename = path.basename(normalized);
457
+ if (excludeDirs.has(basename)) {
458
+ return true;
459
+ }
460
+
461
+ return false;
462
+ };
463
+
426
464
  if (this.config.verbose) {
427
- console.error(`[Indexer] Using ${excludeDirs.size} exclude directories from config`);
465
+ console.error(`[Indexer] Using ${excludeDirs.size} exclude directories, ${excludeFilePatterns.length} file patterns from config`);
428
466
  }
467
+ // Debug: always log for diagnosing test exclusion
468
+ console.error(`[Indexer] excludeDirs: ${[...excludeDirs].join(', ')}`);
469
+ console.error(`[Indexer] excludeFilePatterns: ${excludeFilePatterns.map(r => r.source).join(', ')}`);
429
470
 
430
471
  const api = new fdir()
431
472
  .withFullPaths()
432
- .exclude((dirName) => excludeDirs.has(dirName))
433
- .filter((filePath) => extensions.has(path.extname(filePath)))
473
+ .exclude(isExcludedDirectory)
474
+ .filter((filePath) => {
475
+ if (!extensions.has(path.extname(filePath))) return false;
476
+ // Apply file-level exclusion patterns
477
+ if (excludeFilePatterns.length > 0) {
478
+ const basename = path.basename(filePath);
479
+ for (const re of excludeFilePatterns) {
480
+ if (re.test(basename)) return false;
481
+ }
482
+ }
483
+ return true;
484
+ })
434
485
  .crawl(this.config.searchDirectory);
435
486
 
436
487
  const files = await api.withPromise();
@@ -7,6 +7,7 @@
7
7
 
8
8
  import fs from 'fs/promises';
9
9
  import path from 'path';
10
+ import { loadConfig } from '../lib/config.js';
10
11
 
11
12
  /**
12
13
  * Get tool definition for MCP registration
@@ -27,7 +28,7 @@ export function getToolDefinition(config) {
27
28
  description: "Whether to clear existing cache before switching (default: false)"
28
29
  },
29
30
  reindex: {
30
- type: "boolean",
31
+ type: "boolean",
31
32
  description: "Whether to trigger re-indexing after switching (default: true)"
32
33
  }
33
34
  },
@@ -69,10 +70,33 @@ export class WorkspaceManager {
69
70
  }
70
71
 
71
72
  const oldPath = this.config.searchDirectory;
72
-
73
- // Update config
73
+
74
+ // Reload config for new workspace (re-detects project types & rebuilds excludePatterns)
75
+ const newConfig = await loadConfig(newPath);
76
+
77
+ // Preserve runtime overrides (env vars, embedding settings, etc.)
78
+ const preserveKeys = [
79
+ 'embeddingProvider', 'embeddingModel', 'embeddingDimension',
80
+ 'geminiApiKey', 'geminiModel', 'geminiBaseURL', 'geminiDimensions',
81
+ 'geminiBatchSize', 'geminiBatchFlushMs', 'geminiMaxRetries',
82
+ 'embeddingApiKey', 'embeddingBaseURL',
83
+ 'vertexProject', 'vertexLocation',
84
+ 'vectorStoreProvider', 'milvusAddress', 'milvusToken',
85
+ 'milvusDatabase', 'milvusCollection',
86
+ 'workerThreads', 'maxCpuPercent', 'batchDelay', 'maxWorkers',
87
+ 'verbose'
88
+ ];
89
+ const runtimeOverrides = {};
90
+ for (const key of preserveKeys) {
91
+ if (this.config[key] !== undefined) {
92
+ runtimeOverrides[key] = this.config[key];
93
+ }
94
+ }
95
+
96
+ // Apply new config with runtime overrides
97
+ Object.assign(this.config, newConfig, runtimeOverrides);
74
98
  this.config.searchDirectory = newPath;
75
-
99
+
76
100
  // Update cache directory
77
101
  const newCacheDir = path.join(newPath, '.smart-coding-cache');
78
102
  this.config.cacheDirectory = newCacheDir;
package/lib/config.js CHANGED
@@ -920,22 +920,26 @@ export async function loadConfig(workspaceDir = null) {
920
920
  if (config.smartIndexing !== false) {
921
921
  const detector = new ProjectDetector(config.searchDirectory);
922
922
  const detectedTypes = await detector.detectProjectTypes();
923
-
923
+ const smartPatterns = detector.getSmartIgnorePatterns();
924
+
925
+ // Merge baseline default patterns with smart patterns.
926
+ // Smart patterns always include IGNORE_PATTERNS.common, and add type-specific
927
+ // ignores when project markers are detected.
928
+ // User patterns are appended so users can extend behavior.
929
+ const userPatterns = userConfig.excludePatterns || [];
930
+ config.excludePatterns = [
931
+ ...DEFAULT_CONFIG.excludePatterns,
932
+ ...smartPatterns,
933
+ ...userPatterns
934
+ ];
935
+ config.excludePatterns = [...new Set(config.excludePatterns)];
936
+
924
937
  if (detectedTypes.length > 0) {
925
- const smartPatterns = detector.getSmartIgnorePatterns();
926
-
927
- // Merge smart patterns with user patterns (user patterns take precedence)
928
- const userPatterns = userConfig.excludePatterns || [];
929
- config.excludePatterns = [
930
- ...smartPatterns,
931
- ...userPatterns
932
- ];
933
-
934
938
  console.error(`[Config] Smart indexing: ${detectedTypes.join(', ')}`);
935
- console.error(`[Config] Applied ${smartPatterns.length} smart ignore patterns`);
936
939
  } else {
937
- console.error("[Config] No project markers detected, using default patterns");
940
+ console.error("[Config] No project markers detected, applying common smart patterns");
938
941
  }
942
+ console.error(`[Config] Applied ${smartPatterns.length} smart ignore patterns`);
939
943
  }
940
944
 
941
945
  console.error("[Config] Loaded configuration from config.json");
@@ -166,13 +166,13 @@ export const IGNORE_PATTERNS = {
166
166
  '**/.svn/**',
167
167
  '**/.hg/**',
168
168
  '**/.bzr/**',
169
-
169
+
170
170
  // OS files
171
171
  '**/.DS_Store',
172
172
  '**/Thumbs.db',
173
173
  '**/desktop.ini',
174
174
  '**/$RECYCLE.BIN/**',
175
-
175
+
176
176
  // Backup files
177
177
  '**/*.bak',
178
178
  '**/*.backup',
@@ -182,16 +182,16 @@ export const IGNORE_PATTERNS = {
182
182
  '**/*.swn',
183
183
  '**/#*#',
184
184
  '**/.#*',
185
-
185
+
186
186
  // Lock files (editor/runtime, not package managers)
187
187
  '**/*.lock',
188
188
  '**/.~lock*',
189
-
189
+
190
190
  // Logs
191
191
  '**/*.log',
192
192
  '**/logs/**',
193
193
  '**/*.log.*',
194
-
194
+
195
195
  // IDEs and Editors
196
196
  '**/.vscode/**',
197
197
  '**/.idea/**',
@@ -207,19 +207,19 @@ export const IGNORE_PATTERNS = {
207
207
  '**/*.tmproj',
208
208
  '**/*.tmproject',
209
209
  '**/tmtags',
210
-
210
+
211
211
  // Vim
212
212
  '**/*~',
213
213
  '**/*.swp',
214
214
  '**/*.swo',
215
215
  '**/.*.sw?',
216
216
  '**/Session.vim',
217
-
217
+
218
218
  // Emacs
219
219
  '**/*~',
220
220
  '**/#*#',
221
221
  '**/.#*',
222
-
222
+
223
223
  // Environment files (secrets)
224
224
  '**/.env',
225
225
  '**/.env.local',
@@ -236,21 +236,21 @@ export const IGNORE_PATTERNS = {
236
236
  '**/*.cer',
237
237
  '**/*.p12',
238
238
  '**/*.pfx',
239
-
239
+
240
240
  // Temporary files
241
241
  '**/tmp/**',
242
242
  '**/temp/**',
243
243
  '**/*.tmp',
244
244
  '**/*.temp',
245
245
  '**/.cache/**',
246
-
246
+
247
247
  // Session & runtime
248
248
  '**/.sass-cache/**',
249
249
  '**/connect.lock',
250
250
  '**/*.pid',
251
251
  '**/*.seed',
252
252
  '**/*.pid.lock',
253
-
253
+
254
254
  // Coverage & test output
255
255
  '**/coverage/**',
256
256
  '**/.nyc_output/**',
@@ -258,16 +258,29 @@ export const IGNORE_PATTERNS = {
258
258
  '**/*.cover',
259
259
  '**/*.coverage',
260
260
  '**/htmlcov/**',
261
-
261
+
262
+ // Test files & directories (reduce search noise)
263
+ '**/test/**',
264
+ '**/tests/**',
265
+ '**/__tests__/**',
266
+ '**/*.test.js',
267
+ '**/*.test.ts',
268
+ '**/*.test.jsx',
269
+ '**/*.test.tsx',
270
+ '**/*.spec.js',
271
+ '**/*.spec.ts',
272
+ '**/*.test.py',
273
+ '**/test_*.py',
274
+ '**/*_test.go',
275
+
262
276
  // Documentation builds
263
277
  '**/docs/_build/**',
264
278
  '**/site/**',
265
-
279
+
266
280
  // Misc
267
281
  '**/*.orig',
268
- '**/core',
269
- '**/*.core',
270
-
282
+ '**/*.core', // Unix core dumps
283
+
271
284
  // ============================================
272
285
  // DATABASE FILES
273
286
  // ============================================
@@ -284,7 +297,7 @@ export const IGNORE_PATTERNS = {
284
297
  '**/*.ndf', // SQL Server secondary data
285
298
  '**/*.dbf', // dBase
286
299
  '**/*.kdbx', // KeePass
287
-
300
+
288
301
  // ============================================
289
302
  // ARCHIVES & COMPRESSED FILES
290
303
  // ============================================
@@ -316,7 +329,7 @@ export const IGNORE_PATTERNS = {
316
329
  '**/*.appimage', // Linux AppImage
317
330
  '**/*.snap', // Snap package
318
331
  '**/*.flatpak', // Flatpak
319
-
332
+
320
333
  // ============================================
321
334
  // IMAGES & GRAPHICS
322
335
  // ============================================
@@ -354,7 +367,7 @@ export const IGNORE_PATTERNS = {
354
367
  '**/*.gltf', // GL Transmission Format
355
368
  '**/*.glb', // Binary GLTF
356
369
  '**/*.usdz', // Apple AR
357
-
370
+
358
371
  // ============================================
359
372
  // FONTS
360
373
  // ============================================
@@ -367,7 +380,7 @@ export const IGNORE_PATTERNS = {
367
380
  '**/*.fnt',
368
381
  '**/*.pfb',
369
382
  '**/*.pfm',
370
-
383
+
371
384
  // ============================================
372
385
  // AUDIO FILES
373
386
  // ============================================
@@ -385,7 +398,7 @@ export const IGNORE_PATTERNS = {
385
398
  '**/*.opus',
386
399
  '**/*.ra',
387
400
  '**/*.ram',
388
-
401
+
389
402
  // ============================================
390
403
  // VIDEO FILES
391
404
  // ============================================
@@ -406,7 +419,7 @@ export const IGNORE_PATTERNS = {
406
419
  '**/*.ts', // Video transport stream (not TypeScript - handled by ext whitelist)
407
420
  '**/*.mts',
408
421
  '**/*.m2ts',
409
-
422
+
410
423
  // ============================================
411
424
  // DOCUMENTS (Non-text)
412
425
  // ============================================
@@ -434,7 +447,7 @@ export const IGNORE_PATTERNS = {
434
447
  '**/*.azw3',
435
448
  '**/*.djvu',
436
449
  '**/*.xps',
437
-
450
+
438
451
  // ============================================
439
452
  // COMPILED BINARIES & EXECUTABLES
440
453
  // ============================================
@@ -458,7 +471,7 @@ export const IGNORE_PATTERNS = {
458
471
  '**/*.pdb', // Debug symbols (Windows)
459
472
  '**/*.dSYM/**', // Debug symbols (macOS)
460
473
  '**/*.sym', // Symbol file
461
-
474
+
462
475
  // ============================================
463
476
  // JAVA/JVM COMPILED
464
477
  // ============================================
@@ -470,13 +483,13 @@ export const IGNORE_PATTERNS = {
470
483
  '**/*.nar',
471
484
  '**/*.hpi', // Jenkins plugin
472
485
  '**/*.jpi',
473
-
486
+
474
487
  // ============================================
475
488
  // .NET COMPILED
476
489
  // ============================================
477
490
  '**/*.nupkg', // NuGet package
478
491
  '**/*.snupkg', // Symbol package
479
-
492
+
480
493
  // ============================================
481
494
  // PYTHON COMPILED
482
495
  // ============================================
@@ -485,7 +498,7 @@ export const IGNORE_PATTERNS = {
485
498
  '**/*.pyd',
486
499
  '**/*.whl', // Wheel package
487
500
  '**/*.egg',
488
-
501
+
489
502
  // ============================================
490
503
  // MOBILE BINARIES
491
504
  // ============================================
@@ -494,7 +507,7 @@ export const IGNORE_PATTERNS = {
494
507
  '**/*.ipa', // iOS
495
508
  '**/*.xapk', // Split APK
496
509
  '**/*.obb', // Android expansion
497
-
510
+
498
511
  // ============================================
499
512
  // GENERATED/MINIFIED FILES
500
513
  // ============================================
@@ -513,13 +526,13 @@ export const IGNORE_PATTERNS = {
513
526
  '**/runtime.js',
514
527
  '**/main.*.js', // Hashed output
515
528
  '**/styles.*.css',
516
-
529
+
517
530
  // ============================================
518
531
  // PACKAGE MANAGER BINARIES
519
532
  // ============================================
520
533
  '**/*.lockb', // Bun lock binary
521
534
  '**/shrinkwrap.yaml', // pnpm
522
-
535
+
523
536
  // ============================================
524
537
  // MACHINE LEARNING & DATA
525
538
  // ============================================
@@ -547,7 +560,7 @@ export const IGNORE_PATTERNS = {
547
560
  '**/*.feather', // Feather format
548
561
  '**/*.csv.gz', // Compressed data
549
562
  '**/*.jsonl.gz',
550
-
563
+
551
564
  // ============================================
552
565
  // GAME DEVELOPMENT
553
566
  // ============================================
@@ -567,7 +580,7 @@ export const IGNORE_PATTERNS = {
567
580
  '**/*.umap',
568
581
  '**/*.upk',
569
582
  '**/Content/**/*.uasset',
570
-
583
+
571
584
  // ============================================
572
585
  // MISC BINARY/NON-CODE
573
586
  // ============================================
@@ -591,7 +604,7 @@ export const IGNORE_PATTERNS = {
591
604
  '**/*.crx', // Chrome extension
592
605
  '**/*.xpi', // Firefox extension
593
606
  '**/*.vsix', // VS Code extension
594
-
607
+
595
608
  // ============================================
596
609
  // CI/CD & DEVOPS
597
610
  // ============================================
@@ -610,7 +623,7 @@ export const IGNORE_PATTERNS = {
610
623
  '**/firebase-debug.log',
611
624
  '**/.firebase/**',
612
625
  '**/firestore-debug.log',
613
-
626
+
614
627
  // ============================================
615
628
  // CONTAINER & ORCHESTRATION
616
629
  // ============================================
@@ -619,7 +632,7 @@ export const IGNORE_PATTERNS = {
619
632
  '**/helm/charts/**/*.tgz',
620
633
  '**/.kube/cache/**',
621
634
  '**/*.dockerignore', // Not code
622
-
635
+
623
636
  // ============================================
624
637
  // VIRTUALIZATION
625
638
  // ============================================
@@ -631,7 +644,7 @@ export const IGNORE_PATTERNS = {
631
644
  '**/*.qcow2',
632
645
  '**/.vagrant/**',
633
646
  '**/Vagrantfile.local',
634
-
647
+
635
648
  // ============================================
636
649
  // ELIXIR/ERLANG
637
650
  // ============================================
@@ -642,7 +655,7 @@ export const IGNORE_PATTERNS = {
642
655
  '**/erl_crash.dump',
643
656
  '**/.fetch',
644
657
  '**/mix.lock', // Elixir lock (consider keeping)
645
-
658
+
646
659
  // ============================================
647
660
  // HASKELL
648
661
  // ============================================
@@ -653,7 +666,7 @@ export const IGNORE_PATTERNS = {
653
666
  '**/*.chs.h',
654
667
  '**/*.dyn_hi',
655
668
  '**/*.dyn_o',
656
-
669
+
657
670
  // ============================================
658
671
  // SCALA/SBT
659
672
  // ============================================
@@ -662,7 +675,7 @@ export const IGNORE_PATTERNS = {
662
675
  '**/.bsp/**',
663
676
  '**/.metals/**',
664
677
  '**/.bloop/**',
665
-
678
+
666
679
  // ============================================
667
680
  // CLOJURE
668
681
  // ============================================
@@ -672,14 +685,14 @@ export const IGNORE_PATTERNS = {
672
685
  '**/.nrepl-port',
673
686
  '**/.cpcache/**',
674
687
  '**/.clj-kondo/.cache/**',
675
-
688
+
676
689
  // ============================================
677
690
  // JULIA
678
691
  // ============================================
679
692
  '**/.julia/**',
680
693
  '**/Manifest.toml', // Julia lock
681
694
  '**/docs/build/**',
682
-
695
+
683
696
  // ============================================
684
697
  // R / RSTUDIO
685
698
  // ============================================
@@ -688,7 +701,7 @@ export const IGNORE_PATTERNS = {
688
701
  '**/.RData',
689
702
  '**/rsconnect/**',
690
703
  '**/*.Rproj',
691
-
704
+
692
705
  // ============================================
693
706
  // LATEX
694
707
  // ============================================
@@ -710,7 +723,7 @@ export const IGNORE_PATTERNS = {
710
723
  '**/*.pdfsync',
711
724
  '**/*.fdb_latexmk',
712
725
  '**/*.run.xml',
713
-
726
+
714
727
  // ============================================
715
728
  // C/C++ BUILD ARTIFACTS
716
729
  // ============================================
@@ -725,7 +738,7 @@ export const IGNORE_PATTERNS = {
725
738
  '**/*.gch', // Precompiled header
726
739
  '**/*.pch',
727
740
  '**/*.d', // Dependency files
728
-
741
+
729
742
  // ============================================
730
743
  // DART/FLUTTER
731
744
  // ============================================
@@ -742,13 +755,13 @@ export const IGNORE_PATTERNS = {
742
755
  '**/windows/flutter/ephemeral/**',
743
756
  '**/macos/Flutter/ephemeral/**',
744
757
  '**/linux/flutter/ephemeral/**',
745
-
758
+
746
759
  // ============================================
747
760
  // KOTLIN MULTIPLATFORM
748
761
  // ============================================
749
762
  '**/kotlin-js-store/**',
750
763
  '**/.kotlin/**',
751
-
764
+
752
765
  // ============================================
753
766
  // REACT NATIVE
754
767
  // ============================================
@@ -757,14 +770,14 @@ export const IGNORE_PATTERNS = {
757
770
  '**/android/app/build/**',
758
771
  '**/.expo/**',
759
772
  '**/web-build/**',
760
-
773
+
761
774
  // ============================================
762
775
  // ELECTRON
763
776
  // ============================================
764
777
  '**/release/**',
765
778
  '**/app-builds/**',
766
779
  '**/*.asar',
767
-
780
+
768
781
  // ============================================
769
782
  // DOCUMENTATION GENERATORS
770
783
  // ============================================
@@ -777,7 +790,7 @@ export const IGNORE_PATTERNS = {
777
790
  '**/.vuepress/dist/**',
778
791
  '**/.vitepress/dist/**',
779
792
  '**/book/**', // mdBook output
780
-
793
+
781
794
  // ============================================
782
795
  // EDITOR/TOOL METADATA
783
796
  // ============================================
@@ -789,7 +802,7 @@ export const IGNORE_PATTERNS = {
789
802
  '**/.worksheet/**',
790
803
  '**/.scalafmt.conf',
791
804
  '**/.scalafix.conf',
792
-
805
+
793
806
  // ============================================
794
807
  // SECURITY/SECRETS (Never index)
795
808
  // ============================================
@@ -811,7 +824,7 @@ export const IGNORE_PATTERNS = {
811
824
  '**/.npmrc',
812
825
  '**/.yarnrc',
813
826
  '**/.pypirc',
814
-
827
+
815
828
  // ============================================
816
829
  // MISC TOOLS & EDGE CASES
817
830
  // ============================================
@@ -846,37 +859,37 @@ export const FILE_TYPE_MAP = {
846
859
  'package-lock.json': 'javascript',
847
860
  'yarn.lock': 'javascript',
848
861
  'pnpm-lock.yaml': 'javascript',
849
-
862
+
850
863
  // Python
851
864
  'requirements.txt': 'python',
852
865
  'Pipfile': 'python',
853
866
  'pyproject.toml': 'python',
854
867
  'setup.py': 'python',
855
-
868
+
856
869
  // Android
857
870
  'build.gradle': 'android',
858
871
  'build.gradle.kts': 'android',
859
872
  'settings.gradle': 'android',
860
-
873
+
861
874
  // Java
862
875
  'pom.xml': 'java',
863
-
876
+
864
877
  // iOS
865
878
  'Podfile': 'ios',
866
879
  'Package.swift': 'ios',
867
-
880
+
868
881
  // Go
869
882
  'go.mod': 'go',
870
-
883
+
871
884
  // PHP
872
885
  'composer.json': 'php',
873
-
886
+
874
887
  // Rust
875
888
  'Cargo.toml': 'rust',
876
-
889
+
877
890
  // Ruby
878
891
  'Gemfile': 'ruby',
879
-
892
+
880
893
  // .NET
881
894
  '*.csproj': 'dotnet',
882
895
  '*.sln': 'dotnet'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smart-coding-mcp-gemini-milvus",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Fork of smart-coding-mcp with Gemini embedding + Milvus ANN search. Drop-in MCP server for AI-powered semantic code search.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/reindex.js ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * smart-coding-mcp 리인덱싱 스크립트 (shell 직접 실행용)
4
+ * MCP 서버 없이 직접 인덱싱, 로그 출력
5
+ *
6
+ * 사용법:
7
+ * node reindex.js /path/to/workspace [--force]
8
+ *
9
+ * 환경 변수는 MCP config와 동일하게 설정 필요.
10
+ */
11
+ import { loadConfig } from "./lib/config.js";
12
+ import { createCache } from "./lib/cache-factory.js";
13
+ import { createEmbedder } from "./lib/mrl-embedder.js";
14
+ import { CodebaseIndexer } from "./features/index-codebase.js";
15
+ import { parseArgs } from "util";
16
+
17
+ const { values, positionals } = parseArgs({
18
+ allowPositionals: true,
19
+ options: {
20
+ force: { type: "boolean", short: "f", default: false },
21
+ help: { type: "boolean", short: "h", default: false },
22
+ },
23
+ });
24
+
25
+ if (values.help) {
26
+ console.log(`
27
+ smart-coding-mcp 리인덱싱 (shell 직접 실행)
28
+
29
+ Usage:
30
+ node reindex.js [workspace_path] [--force]
31
+
32
+ Options:
33
+ -f, --force 전체 재인덱싱 (캐시 무시)
34
+ -h, --help 도움말
35
+
36
+ Environment:
37
+ MCP config의 env를 그대로 사용합니다.
38
+ SMART_CODING_EMBEDDING_PROVIDER, SMART_CODING_GEMINI_BATCH_SIZE 등
39
+ `);
40
+ process.exit(0);
41
+ }
42
+
43
+ const workspaceDir = positionals[0] || process.cwd();
44
+ const force = values.force;
45
+
46
+ function log(msg) {
47
+ const ts = new Date().toLocaleTimeString("ko-KR", { hour12: false });
48
+ console.log(`[${ts}] ${msg}`);
49
+ }
50
+
51
+ async function main() {
52
+ log(`🚀 Reindex 시작: ${workspaceDir}`);
53
+ log(` force=${force}`);
54
+
55
+ // 1. 설정 로드
56
+ const config = await loadConfig(workspaceDir);
57
+ log(` searchDirectory: ${config.searchDirectory}`);
58
+ log(` cacheDirectory: ${config.cacheDirectory}`);
59
+ log(` extensions: ${config.fileExtensions?.length || "?"} types`);
60
+ log(` excludePatterns: ${config.excludePatterns?.length || "?"} patterns`);
61
+ console.log();
62
+
63
+ // 2. 임베더 로드
64
+ log("🧠 임베더 로딩...");
65
+ const embedder = await createEmbedder(config);
66
+ log(` model: ${embedder.modelName} (${embedder.dimension}d, device: ${embedder.device})`);
67
+
68
+ // 3. 캐시 로드
69
+ log("💾 캐시 로딩...");
70
+ const cache = createCache(config);
71
+ await cache.load();
72
+
73
+ const statsBefore = cache.getStats?.() || {};
74
+ log(` 캐시 항목: ${statsBefore.totalEntries ?? "?"}`);
75
+
76
+ // 4. 인덱서 생성 & 실행
77
+ log("📁 인덱싱 시작...");
78
+ console.log();
79
+
80
+ const t0 = Date.now();
81
+ const indexer = new CodebaseIndexer(embedder, cache, config);
82
+ const result = await indexer.indexAll(force);
83
+
84
+ const elapsed = ((Date.now() - t0) / 1000).toFixed(1);
85
+
86
+ console.log();
87
+ log("🎉 완료!");
88
+ log(` 파일: ${result.filesProcessed ?? "?"}개`);
89
+ log(` 청크: ${result.chunksProcessed ?? "?"}개`);
90
+ log(` 새로운 파일: ${result.newFiles ?? "?"}개`);
91
+ log(` 업데이트: ${result.updatedFiles ?? "?"}개`);
92
+ log(` 스킵: ${result.skippedFiles ?? "?"}개`);
93
+ log(` 삭제: ${result.deletedFiles ?? "?"}개`);
94
+ log(` 소요: ${elapsed}s`);
95
+
96
+ // 5. 캐시 저장
97
+ if (cache.save) {
98
+ await cache.save();
99
+ log("💾 캐시 저장 완료");
100
+ }
101
+
102
+ process.exit(0);
103
+ }
104
+
105
+ main().catch((err) => {
106
+ console.error(`\n❌ 에러: ${err.message}`);
107
+ console.error(err.stack);
108
+ process.exit(1);
109
+ });