@softerist/heuristic-mcp 3.2.6 → 3.2.8
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/index.js +31 -11
- package/lib/embedding-worker.js +0 -1
- package/lib/logging.js +11 -1
- package/package.json +1 -1
- package/scripts/clear-cache.js +0 -2
- package/scripts/download-model.js +0 -5
- package/scripts/postinstall.js +0 -2
package/index.js
CHANGED
|
@@ -242,7 +242,17 @@ function formatCrashDetail(detail) {
|
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
function isBrokenPipeError(detail) {
|
|
245
|
-
|
|
245
|
+
if (!detail) return false;
|
|
246
|
+
if (typeof detail === 'string') {
|
|
247
|
+
return /(?:^|[\s:])EPIPE(?:[\s:]|$)|broken pipe/i.test(detail);
|
|
248
|
+
}
|
|
249
|
+
if (typeof detail === 'object') {
|
|
250
|
+
if (detail.code === 'EPIPE') return true;
|
|
251
|
+
if (typeof detail.message === 'string') {
|
|
252
|
+
return /(?:^|[\s:])EPIPE(?:[\s:]|$)|broken pipe/i.test(detail.message);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return false;
|
|
246
256
|
}
|
|
247
257
|
|
|
248
258
|
function isCrashShutdownReason(reason) {
|
|
@@ -250,6 +260,11 @@ function isCrashShutdownReason(reason) {
|
|
|
250
260
|
return normalized.includes('uncaughtexception') || normalized.includes('unhandledrejection');
|
|
251
261
|
}
|
|
252
262
|
|
|
263
|
+
function shouldLogProcessLifecycle() {
|
|
264
|
+
const value = String(process.env.HEURISTIC_MCP_PROCESS_LIFECYCLE || '').trim().toLowerCase();
|
|
265
|
+
return value === '1' || value === 'true' || value === 'yes' || value === 'on';
|
|
266
|
+
}
|
|
267
|
+
|
|
253
268
|
function getShutdownExitCode(reason) {
|
|
254
269
|
const normalized = String(reason || '').trim().toUpperCase();
|
|
255
270
|
if (normalized === 'SIGINT') return 130;
|
|
@@ -260,15 +275,20 @@ function getShutdownExitCode(reason) {
|
|
|
260
275
|
function registerProcessDiagnostics({ isServerMode, requestShutdown, getShutdownReason }) {
|
|
261
276
|
if (!isServerMode) return;
|
|
262
277
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
278
|
+
if (shouldLogProcessLifecycle()) {
|
|
279
|
+
let beforeExitLogged = false;
|
|
280
|
+
process.on('beforeExit', (code) => {
|
|
281
|
+
if (beforeExitLogged) return;
|
|
282
|
+
beforeExitLogged = true;
|
|
283
|
+
const reason = getShutdownReason() || 'natural';
|
|
284
|
+
console.info(`[Server] Process beforeExit (code=${code}, reason=${reason}).`);
|
|
285
|
+
});
|
|
267
286
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
287
|
+
process.on('exit', (code) => {
|
|
288
|
+
const reason = getShutdownReason() || 'natural';
|
|
289
|
+
console.info(`[Server] Process exit (code=${code}, reason=${reason}).`);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
272
292
|
|
|
273
293
|
let fatalHandled = false;
|
|
274
294
|
const handleFatalError = (reason, detail) => {
|
|
@@ -1590,8 +1610,6 @@ async function gracefulShutdown(signal) {
|
|
|
1590
1610
|
keepAliveTimer = null;
|
|
1591
1611
|
}
|
|
1592
1612
|
|
|
1593
|
-
unregisterStdioShutdownHandlers();
|
|
1594
|
-
|
|
1595
1613
|
const cleanupTasks = [];
|
|
1596
1614
|
|
|
1597
1615
|
if (indexer && indexer.watcher) {
|
|
@@ -1639,6 +1657,8 @@ async function gracefulShutdown(signal) {
|
|
|
1639
1657
|
|
|
1640
1658
|
await Promise.allSettled(cleanupTasks);
|
|
1641
1659
|
console.info('[Server] Goodbye!');
|
|
1660
|
+
|
|
1661
|
+
unregisterStdioShutdownHandlers();
|
|
1642
1662
|
await flushLogsSafely({ close: true, timeoutMs: 1500 });
|
|
1643
1663
|
|
|
1644
1664
|
setTimeout(() => process.exit(exitCode), 100);
|
package/lib/embedding-worker.js
CHANGED
|
@@ -7,7 +7,6 @@ import { configureNativeOnnxBackend } from './onnx-backend.js';
|
|
|
7
7
|
import { smartChunk, hashContent } from './utils.js';
|
|
8
8
|
import { extractCallData } from './call-graph.js';
|
|
9
9
|
|
|
10
|
-
// Helper to get global cache dir (duplicated from config.js to avoid full config load in worker)
|
|
11
10
|
function getGlobalCacheDir() {
|
|
12
11
|
if (process.platform === 'win32') {
|
|
13
12
|
return process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
|
package/lib/logging.js
CHANGED
|
@@ -14,7 +14,17 @@ const originalConsole = {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
function isBrokenPipeError(error) {
|
|
17
|
-
|
|
17
|
+
if (!error) return false;
|
|
18
|
+
if (typeof error === 'string') {
|
|
19
|
+
return /(?:^|[\s:])EPIPE(?:[\s:]|$)|broken pipe/i.test(error);
|
|
20
|
+
}
|
|
21
|
+
if (typeof error === 'object') {
|
|
22
|
+
if (error.code === 'EPIPE') return true;
|
|
23
|
+
if (typeof error.message === 'string') {
|
|
24
|
+
return /(?:^|[\s:])EPIPE(?:[\s:]|$)|broken pipe/i.test(error.message);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
18
28
|
}
|
|
19
29
|
|
|
20
30
|
function writeToOriginalStderr(...args) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softerist/heuristic-mcp",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.8",
|
|
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",
|
package/scripts/clear-cache.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
import fs from 'fs/promises';
|
|
3
2
|
import { loadConfig } from '../lib/config.js';
|
|
4
3
|
|
|
@@ -7,7 +6,6 @@ async function clearCache() {
|
|
|
7
6
|
const config = await loadConfig(process.cwd());
|
|
8
7
|
const cacheDir = config.cacheDirectory;
|
|
9
8
|
|
|
10
|
-
// Remove cache directory
|
|
11
9
|
await fs.rm(cacheDir, { recursive: true, force: true });
|
|
12
10
|
console.info(`Cache cleared successfully: ${cacheDir}`);
|
|
13
11
|
console.info('Next startup will perform a full reindex.');
|
|
@@ -9,15 +9,11 @@ async function downloadModel() {
|
|
|
9
9
|
const transformers = await import('@huggingface/transformers');
|
|
10
10
|
const { pipeline, env } = transformers;
|
|
11
11
|
|
|
12
|
-
// Force cache directory to global location
|
|
13
12
|
env.cacheDir = globalCacheDir;
|
|
14
13
|
|
|
15
14
|
console.info(`[Model Setup] Pre-caching model to: ${globalCacheDir}`);
|
|
16
|
-
// Check if network is available by pinging HF (simple check)
|
|
17
|
-
// Actually, pipeline() will fail fast if network is down
|
|
18
15
|
console.info(`[Model Setup] Downloading 'jinaai/jina-embeddings-v2-base-code'...`);
|
|
19
16
|
|
|
20
|
-
// This will download the model to the cache directory
|
|
21
17
|
await pipeline('feature-extraction', 'jinaai/jina-embeddings-v2-base-code');
|
|
22
18
|
|
|
23
19
|
console.info(`[Model Setup] ✅ Model cached successfully!`);
|
|
@@ -36,7 +32,6 @@ async function downloadModel() {
|
|
|
36
32
|
'[Model Setup] This is okay! The server will attempt to download it when started.'
|
|
37
33
|
);
|
|
38
34
|
console.warn(`[Model Setup] Error details: ${error.message}`);
|
|
39
|
-
// Don't fail the install, just warn
|
|
40
35
|
}
|
|
41
36
|
}
|
|
42
37
|
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { register } from '../features/register.js';
|
|
2
2
|
|
|
3
|
-
// Run the registration process - MUST await to ensure file writes complete
|
|
4
3
|
console.info('[PostInstall] Running Heuristic MCP registration...');
|
|
5
4
|
|
|
6
5
|
try {
|
|
@@ -8,5 +7,4 @@ try {
|
|
|
8
7
|
console.info('[PostInstall] Registration complete.');
|
|
9
8
|
} catch (err) {
|
|
10
9
|
console.error('[PostInstall] Registration failed:', err.message);
|
|
11
|
-
// Don't fail the install if registration fails, just warn
|
|
12
10
|
}
|