@softerist/heuristic-mcp 2.1.47 → 3.0.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 (109) hide show
  1. package/.agent/workflows/code-review.md +60 -0
  2. package/.prettierrc +7 -0
  3. package/ARCHITECTURE.md +105 -170
  4. package/CONTRIBUTING.md +32 -113
  5. package/GEMINI.md +73 -0
  6. package/LICENSE +21 -21
  7. package/README.md +161 -54
  8. package/config.json +876 -75
  9. package/debug-pids.js +27 -0
  10. package/eslint.config.js +36 -0
  11. package/features/ann-config.js +37 -26
  12. package/features/clear-cache.js +28 -19
  13. package/features/find-similar-code.js +142 -66
  14. package/features/hybrid-search.js +253 -93
  15. package/features/index-codebase.js +1455 -394
  16. package/features/lifecycle.js +813 -180
  17. package/features/register.js +58 -52
  18. package/index.js +450 -306
  19. package/lib/cache-ops.js +22 -0
  20. package/lib/cache-utils.js +68 -0
  21. package/lib/cache.js +1392 -587
  22. package/lib/call-graph.js +165 -50
  23. package/lib/cli.js +154 -0
  24. package/lib/config.js +462 -121
  25. package/lib/embedding-process.js +77 -0
  26. package/lib/embedding-worker.js +545 -30
  27. package/lib/ignore-patterns.js +61 -59
  28. package/lib/json-worker.js +14 -0
  29. package/lib/json-writer.js +344 -0
  30. package/lib/logging.js +88 -0
  31. package/lib/memory-logger.js +13 -0
  32. package/lib/project-detector.js +13 -17
  33. package/lib/server-lifecycle.js +38 -0
  34. package/lib/settings-editor.js +645 -0
  35. package/lib/tokenizer.js +207 -104
  36. package/lib/utils.js +273 -198
  37. package/lib/vector-store-binary.js +592 -0
  38. package/mcp_config.example.json +13 -0
  39. package/package.json +13 -2
  40. package/scripts/clear-cache.js +6 -17
  41. package/scripts/download-model.js +14 -9
  42. package/scripts/postinstall.js +5 -5
  43. package/search-configs.js +36 -0
  44. package/test/ann-config.test.js +179 -0
  45. package/test/ann-fallback.test.js +6 -6
  46. package/test/binary-store.test.js +69 -0
  47. package/test/cache-branches.test.js +120 -0
  48. package/test/cache-errors.test.js +264 -0
  49. package/test/cache-extra.test.js +300 -0
  50. package/test/cache-helpers.test.js +205 -0
  51. package/test/cache-hnsw-failure.test.js +40 -0
  52. package/test/cache-json-worker.test.js +190 -0
  53. package/test/cache-worker.test.js +102 -0
  54. package/test/cache.test.js +443 -0
  55. package/test/call-graph.test.js +103 -4
  56. package/test/clear-cache.test.js +69 -68
  57. package/test/code-review-workflow.test.js +50 -0
  58. package/test/config.test.js +418 -0
  59. package/test/coverage-gap.test.js +497 -0
  60. package/test/coverage-maximizer.test.js +236 -0
  61. package/test/debug-analysis.js +107 -0
  62. package/test/embedding-model.test.js +173 -103
  63. package/test/embedding-worker-extra.test.js +272 -0
  64. package/test/embedding-worker.test.js +158 -0
  65. package/test/features.test.js +139 -0
  66. package/test/final-boost.test.js +271 -0
  67. package/test/final-polish.test.js +183 -0
  68. package/test/final.test.js +95 -0
  69. package/test/find-similar-code.test.js +191 -0
  70. package/test/helpers.js +92 -11
  71. package/test/helpers.test.js +46 -0
  72. package/test/hybrid-search-basic.test.js +62 -0
  73. package/test/hybrid-search-branch.test.js +202 -0
  74. package/test/hybrid-search-callgraph.test.js +229 -0
  75. package/test/hybrid-search-extra.test.js +81 -0
  76. package/test/hybrid-search.test.js +484 -71
  77. package/test/index-cli.test.js +520 -0
  78. package/test/index-codebase-batch.test.js +119 -0
  79. package/test/index-codebase-branches.test.js +585 -0
  80. package/test/index-codebase-core.test.js +1032 -0
  81. package/test/index-codebase-edge-cases.test.js +254 -0
  82. package/test/index-codebase-errors.test.js +132 -0
  83. package/test/index-codebase-gap.test.js +239 -0
  84. package/test/index-codebase-lines.test.js +151 -0
  85. package/test/index-codebase-watcher.test.js +259 -0
  86. package/test/index-codebase-zone.test.js +259 -0
  87. package/test/index-codebase.test.js +371 -69
  88. package/test/index-memory.test.js +220 -0
  89. package/test/indexer-detailed.test.js +176 -0
  90. package/test/integration.test.js +148 -92
  91. package/test/json-worker.test.js +50 -0
  92. package/test/lifecycle.test.js +541 -0
  93. package/test/master.test.js +198 -0
  94. package/test/perfection.test.js +349 -0
  95. package/test/project-detector.test.js +65 -0
  96. package/test/register.test.js +262 -0
  97. package/test/tokenizer.test.js +55 -93
  98. package/test/ultra-maximizer.test.js +116 -0
  99. package/test/utils-branches.test.js +161 -0
  100. package/test/utils-extra.test.js +116 -0
  101. package/test/utils.test.js +131 -0
  102. package/test/verify_fixes.js +76 -0
  103. package/test/worker-errors.test.js +96 -0
  104. package/test/worker-init.test.js +102 -0
  105. package/test/worker_throttling.test.js +93 -0
  106. package/tools/scripts/benchmark-search.js +95 -0
  107. package/tools/scripts/cache-stats.js +71 -0
  108. package/tools/scripts/manual-search.js +34 -0
  109. package/vitest.config.js +19 -9
@@ -0,0 +1,22 @@
1
+ import fs from 'fs/promises';
2
+ import { loadConfig } from './config.js';
3
+ import { clearStaleCaches } from './cache-utils.js';
4
+
5
+ export async function clearCache(workspaceDir) {
6
+ const effectiveWorkspace = workspaceDir || process.cwd();
7
+ const activeConfig = await loadConfig(effectiveWorkspace);
8
+
9
+ if (!activeConfig.enableCache) {
10
+ console.info('[Cache] Cache disabled (enableCache=false); nothing to clear.');
11
+ return;
12
+ }
13
+
14
+ try {
15
+ await fs.rm(activeConfig.cacheDirectory, { recursive: true, force: true });
16
+ console.info(`[Cache] Cleared cache directory: ${activeConfig.cacheDirectory}`);
17
+ await clearStaleCaches();
18
+ } catch (err) {
19
+ console.error(`[Cache] Failed to clear cache: ${err.message}`);
20
+ process.exit(1);
21
+ }
22
+ }
@@ -0,0 +1,68 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { getGlobalCacheDir } from './config.js';
4
+
5
+ export async function clearStaleCaches({ maxAgeMs = 6 * 60 * 60 * 1000, logger = console } = {}) {
6
+ const globalCacheRoot = path.join(getGlobalCacheDir(), 'heuristic-mcp');
7
+ const cacheDirs = await fs.readdir(globalCacheRoot).catch(() => []);
8
+ if (cacheDirs.length === 0) return 0;
9
+
10
+ const now = Date.now();
11
+ let removed = 0;
12
+
13
+ for (const dir of cacheDirs) {
14
+ const cacheDir = path.join(globalCacheRoot, dir);
15
+ const metaFile = path.join(cacheDir, 'meta.json');
16
+ try {
17
+ await fs.access(metaFile);
18
+ continue; // valid cache with metadata
19
+ } catch (err) {
20
+ if (err.code !== 'ENOENT') continue;
21
+ try {
22
+ const stats = await fs.stat(cacheDir);
23
+ const ageMs = now - stats.mtimeMs;
24
+ if (ageMs < maxAgeMs) {
25
+ continue; // likely indexing in progress
26
+ }
27
+
28
+ let progressAgeMs = null;
29
+ const progressFile = path.join(cacheDir, 'progress.json');
30
+ try {
31
+ const raw = await fs.readFile(progressFile, 'utf-8');
32
+ const data = JSON.parse(raw);
33
+ const updatedAt = Date.parse(data?.updatedAt);
34
+ if (Number.isFinite(updatedAt)) {
35
+ progressAgeMs = now - updatedAt;
36
+ }
37
+ } catch {
38
+ // ignore progress read errors
39
+ }
40
+ if (progressAgeMs === null) {
41
+ try {
42
+ const progressStats = await fs.stat(progressFile);
43
+ progressAgeMs = now - progressStats.mtimeMs;
44
+ } catch {
45
+ // no progress file
46
+ }
47
+ }
48
+
49
+ if (progressAgeMs !== null && progressAgeMs < maxAgeMs) {
50
+ continue; // progress updated recently
51
+ }
52
+
53
+ await fs.rm(cacheDir, { recursive: true, force: true });
54
+ removed++;
55
+ } catch {
56
+ // ignore failures per dir
57
+ }
58
+ }
59
+ }
60
+
61
+ if (removed > 0) {
62
+ logger.info(
63
+ `[Cache] Removed ${removed} stale cache director${removed === 1 ? 'y' : 'ies'}.`
64
+ );
65
+ }
66
+
67
+ return removed;
68
+ }