gitnexus 1.6.4-rc.67 → 1.6.4-rc.69

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.
@@ -36,6 +36,30 @@ export function resolveWorkerPoolOptions(options = {}) {
36
36
  timeoutBackoffFactor: positiveInteger(options.timeoutBackoffFactor) ?? DEFAULT_TIMEOUT_BACKOFF_FACTOR,
37
37
  };
38
38
  }
39
+ function waitForWorkerOnline(worker) {
40
+ return new Promise((resolve, reject) => {
41
+ const cleanup = () => {
42
+ worker.removeListener('online', onOnline);
43
+ worker.removeListener('error', onError);
44
+ worker.removeListener('exit', onExit);
45
+ };
46
+ const onOnline = () => {
47
+ cleanup();
48
+ resolve();
49
+ };
50
+ const onError = (err) => {
51
+ cleanup();
52
+ reject(err);
53
+ };
54
+ const onExit = (code) => {
55
+ cleanup();
56
+ reject(new Error(`Replacement worker exited with code ${code} before coming online`));
57
+ };
58
+ worker.once('online', onOnline);
59
+ worker.once('error', onError);
60
+ worker.once('exit', onExit);
61
+ });
62
+ }
39
63
  function estimateItemBytes(item) {
40
64
  if (typeof item !== 'object' || item === null)
41
65
  return 0;
@@ -128,8 +152,21 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
128
152
  const replaceWorker = async (workerIndex) => {
129
153
  const worker = workers[workerIndex];
130
154
  await worker?.terminate().catch(() => undefined);
131
- if (!stopped)
132
- workers[workerIndex] = new Worker(workerUrl);
155
+ if (stopped)
156
+ return;
157
+ const replacement = new Worker(workerUrl);
158
+ try {
159
+ await waitForWorkerOnline(replacement);
160
+ }
161
+ catch (err) {
162
+ await replacement.terminate().catch(() => undefined);
163
+ throw new Error(`Replacement worker ${workerIndex} failed to start: ${err instanceof Error ? err.message : String(err)}`);
164
+ }
165
+ if (stopped) {
166
+ await replacement.terminate().catch(() => undefined);
167
+ return;
168
+ }
169
+ workers[workerIndex] = replacement;
133
170
  };
134
171
  const fail = async (err) => {
135
172
  poolBroken = true;
@@ -245,7 +282,7 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
245
282
  await replaceWorker(workerIndex);
246
283
  }
247
284
  catch (err) {
248
- void fail(err instanceof Error ? err : new Error(`Worker replacement failed: ${err}`));
285
+ void fail(err instanceof Error ? err : new Error(String(err)));
249
286
  return;
250
287
  }
251
288
  finally {
@@ -155,6 +155,7 @@ a.ext:hover{text-decoration:underline}
155
155
  <div class="section-title">Endpoints</div>
156
156
  <p class="endpoint"><a href="/api/info">/api/info</a> <span style="color:#5a5a70">— Server version &amp; context</span></p>
157
157
  <p class="endpoint"><a href="/api/repos">/api/repos</a> <span style="color:#5a5a70">— Indexed repositories</span></p>
158
+ <p class="endpoint"><code>/api/health</code> <span style="color:#5a5a70">— Docker/orchestrator healthcheck</span></p>
158
159
  <p class="endpoint"><code>/api/heartbeat</code> <span style="color:#5a5a70">— SSE heartbeat</span></p>
159
160
  <p class="endpoint"><code>/api/graph</code> <code>/api/query</code> <code>/api/search</code> <span style="color:#5a5a70">— Data</span></p>
160
161
  <p class="endpoint"><code>/api/mcp</code> <span style="color:#5a5a70">— MCP over StreamableHTTP</span></p>
@@ -669,6 +670,12 @@ export const createServer = async (port, host = '127.0.0.1') => {
669
670
  }
670
671
  return found;
671
672
  };
673
+ // Lightweight healthcheck for Docker/orchestrator probes (#1147).
674
+ // Returns immediately so container managers do not confuse a long-lived
675
+ // SSE stream with an unhealthy server.
676
+ app.get('/api/health', (_req, res) => {
677
+ res.json({ status: 'ok' });
678
+ });
672
679
  // SSE heartbeat — clients connect to detect server liveness instantly.
673
680
  // When the server shuts down, the TCP connection drops and the client's
674
681
  // EventSource fires onerror immediately (no polling delay).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.4-rc.67",
3
+ "version": "1.6.4-rc.69",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",