@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 CHANGED
@@ -242,7 +242,17 @@ function formatCrashDetail(detail) {
242
242
  }
243
243
 
244
244
  function isBrokenPipeError(detail) {
245
- return Boolean(detail && typeof detail === 'object' && detail.code === 'EPIPE');
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
- process.on('beforeExit', (code) => {
264
- const reason = getShutdownReason() || 'natural';
265
- console.info(`[Server] Process beforeExit (code=${code}, reason=${reason}).`);
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
- process.on('exit', (code) => {
269
- const reason = getShutdownReason() || 'natural';
270
- console.info(`[Server] Process exit (code=${code}, reason=${reason}).`);
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);
@@ -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
- return Boolean(error && typeof error === 'object' && error.code === 'EPIPE');
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.6",
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",
@@ -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
 
@@ -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
  }