@softerist/heuristic-mcp 2.1.0 → 2.1.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.
package/README.md CHANGED
@@ -148,7 +148,7 @@ Returns: Relevant validation code with file paths and line numbers
148
148
  **find_similar_code** - Find duplicates or patterns
149
149
 
150
150
  ```
151
- Input: A snippet of code or a file path
151
+ Input: A code snippet (paste the code directly)
152
152
  Returns: Other code in the project that looks or functions similarly
153
153
  ```
154
154
 
package/lib/cache.js CHANGED
@@ -164,6 +164,19 @@ export class EmbeddingsCache {
164
164
  this.annIndex = null;
165
165
  this.annMeta = null;
166
166
  }
167
+
168
+ // Load call-graph data if it exists
169
+ const callGraphFile = path.join(this.config.cacheDirectory, "call-graph.json");
170
+ try {
171
+ const callGraphData = await fs.readFile(callGraphFile, "utf8");
172
+ const parsed = JSON.parse(callGraphData);
173
+ this.fileCallData = new Map(Object.entries(parsed));
174
+ if (this.config.verbose) {
175
+ console.error(`[Cache] Loaded call-graph data for ${this.fileCallData.size} files`);
176
+ }
177
+ } catch {
178
+ // Call-graph file doesn't exist yet, that's OK
179
+ }
167
180
  } catch (error) {
168
181
  console.error("[Cache] Failed to load cache:", error.message);
169
182
  }
@@ -189,6 +202,12 @@ export class EmbeddingsCache {
189
202
  fs.writeFile(hashFile, JSON.stringify(Object.fromEntries(this.fileHashes), null, 2)),
190
203
  fs.writeFile(metaFile, JSON.stringify(this.cacheMeta, null, 2))
191
204
  ]);
205
+
206
+ // Save call-graph data
207
+ if (this.fileCallData.size > 0) {
208
+ const callGraphFile = path.join(this.config.cacheDirectory, "call-graph.json");
209
+ await fs.writeFile(callGraphFile, JSON.stringify(Object.fromEntries(this.fileCallData), null, 2));
210
+ }
192
211
  } catch (error) {
193
212
  console.error("[Cache] Failed to save cache:", error.message);
194
213
  } finally {
@@ -220,6 +239,8 @@ export class EmbeddingsCache {
220
239
  removeFileFromStore(file) {
221
240
  this.vectorStore = this.vectorStore.filter(chunk => chunk.file !== file);
222
241
  this.invalidateAnnIndex();
242
+ // Also clear call-graph data for this file
243
+ this.removeFileCallData(file);
223
244
  }
224
245
 
225
246
 
@@ -419,6 +440,9 @@ export class EmbeddingsCache {
419
440
  this.vectorStore = [];
420
441
  this.fileHashes = new Map();
421
442
  this.invalidateAnnIndex();
443
+ // Clear call-graph data
444
+ this.fileCallData.clear();
445
+ this.callGraph = null;
422
446
  console.error(`[Cache] Cache cleared successfully: ${this.config.cacheDirectory}`);
423
447
  } catch (error) {
424
448
  console.error("[Cache] Failed to clear cache:", error.message);
package/lib/call-graph.js CHANGED
@@ -48,20 +48,20 @@ const DEFINITION_PATTERNS = {
48
48
  // Pattern for function calls (language-agnostic, catches most cases)
49
49
  const CALL_PATTERN = /\b([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/g;
50
50
 
51
- // Common built-ins to exclude from call detection
51
+ // Common built-ins to exclude from call detection (all lowercase for case-insensitive matching)
52
52
  const BUILTIN_EXCLUSIONS = new Set([
53
53
  // JavaScript
54
54
  "if", "for", "while", "switch", "catch", "function", "async", "await",
55
55
  "return", "throw", "new", "typeof", "instanceof", "delete", "void",
56
56
  "console", "require", "import", "export", "super", "this",
57
57
  // Common functions that aren't meaningful for call graphs
58
- "parseInt", "parseFloat", "String", "Number", "Boolean", "Array", "Object",
59
- "Map", "Set", "Promise", "Error", "JSON", "Math", "Date", "RegExp",
58
+ "parseint", "parsefloat", "string", "number", "boolean", "array", "object",
59
+ "map", "set", "promise", "error", "json", "math", "date", "regexp",
60
60
  // Python
61
61
  "def", "class", "print", "len", "range", "str", "int", "float", "list", "dict",
62
- "tuple", "set", "bool", "type", "isinstance", "hasattr", "getattr", "setattr",
62
+ "tuple", "bool", "type", "isinstance", "hasattr", "getattr", "setattr",
63
63
  // Go
64
- "func", "make", "append", "len", "cap", "new", "panic", "recover",
64
+ "func", "make", "append", "cap", "panic", "recover",
65
65
  // Control flow that looks like function calls
66
66
  "else", "try", "finally", "with", "assert", "raise", "yield"
67
67
  ]);
@@ -103,7 +103,7 @@ export function extractDefinitions(content, file) {
103
103
  let match;
104
104
  while ((match = pattern.exec(content)) !== null) {
105
105
  const name = match[1];
106
- if (name && name.length > 1 && !BUILTIN_EXCLUSIONS.has(name)) {
106
+ if (name && name.length > 1 && !BUILTIN_EXCLUSIONS.has(name.toLowerCase())) {
107
107
  definitions.add(name);
108
108
  }
109
109
  }
package/lib/config.js CHANGED
@@ -208,6 +208,24 @@ export async function loadConfig(workspaceDir = null) {
208
208
  }
209
209
  }
210
210
 
211
+ if (process.env.SMART_CODING_RECENCY_BOOST !== undefined) {
212
+ const value = parseFloat(process.env.SMART_CODING_RECENCY_BOOST);
213
+ if (!isNaN(value) && value >= 0 && value <= 1) {
214
+ config.recencyBoost = value;
215
+ } else {
216
+ console.error(`[Config] Invalid SMART_CODING_RECENCY_BOOST: ${process.env.SMART_CODING_RECENCY_BOOST}, using default`);
217
+ }
218
+ }
219
+
220
+ if (process.env.SMART_CODING_RECENCY_DECAY_DAYS !== undefined) {
221
+ const value = parseInt(process.env.SMART_CODING_RECENCY_DECAY_DAYS, 10);
222
+ if (!isNaN(value) && value > 0 && value <= 365) {
223
+ config.recencyDecayDays = value;
224
+ } else {
225
+ console.error(`[Config] Invalid SMART_CODING_RECENCY_DECAY_DAYS: ${process.env.SMART_CODING_RECENCY_DECAY_DAYS}, using default`);
226
+ }
227
+ }
228
+
211
229
  if (process.env.SMART_CODING_WATCH_FILES !== undefined) {
212
230
  const value = process.env.SMART_CODING_WATCH_FILES;
213
231
  if (value === 'true' || value === 'false') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softerist/heuristic-mcp",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "An enhanced MCP server providing intelligent semantic code search with find-similar-code, recency ranking, and improved chunking. Fork of smart-coding-mcp.",
5
5
  "type": "module",
6
6
  "main": "index.js",