From 5dd3b38f1be927a616adf1104a523329705a3acd Mon Sep 17 00:00:00 2001 From: Gujiassh Date: Fri, 13 Mar 2026 08:11:10 +0900 Subject: [PATCH 1/2] fix: keep worker warnings non-terminal Treat parse-worker warning messages as informational so a warning can be surfaced without short-circuiting the worker result protocol. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .../src/core/ingestion/workers/worker-pool.ts | 3 ++ gitnexus/test/integration/worker-pool.test.ts | 35 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/gitnexus/src/core/ingestion/workers/worker-pool.ts b/gitnexus/src/core/ingestion/workers/worker-pool.ts index bc23f0ea41..9fa77ef399 100644 --- a/gitnexus/src/core/ingestion/workers/worker-pool.ts +++ b/gitnexus/src/core/ingestion/workers/worker-pool.ts @@ -24,6 +24,7 @@ export interface WorkerPool { /** Message shapes sent back by worker threads. */ type WorkerOutgoingMessage = | { type: 'progress'; filesProcessed: number } + | { type: 'warning'; message: string } | { type: 'sub-batch-done' } | { type: 'error'; error: string } | { type: 'result'; data: unknown }; @@ -120,6 +121,8 @@ export const createWorkerPool = (workerUrl: URL, poolSize?: number): WorkerPool const total = workerProgress.reduce((a, b) => a + b, 0); onProgress(total); } + } else if (msg.type === 'warning') { + console.warn(msg.message); } else if (msg.type === 'sub-batch-done') { sendNextSubBatch(); } else if (msg.type === 'error') { diff --git a/gitnexus/test/integration/worker-pool.test.ts b/gitnexus/test/integration/worker-pool.test.ts index 48a7c506ac..b3c90b60b0 100644 --- a/gitnexus/test/integration/worker-pool.test.ts +++ b/gitnexus/test/integration/worker-pool.test.ts @@ -6,11 +6,12 @@ * This is critical for cross-platform CI where vitest runs from src/ * but workers need compiled .js files. */ -import { describe, it, expect, afterEach } from 'vitest'; +import { describe, it, expect, afterEach, vi } from 'vitest'; import { createWorkerPool, WorkerPool } from '../../src/core/ingestion/workers/worker-pool.js'; import { pathToFileURL } from 'node:url'; import path from 'node:path'; import fs from 'node:fs'; +import os from 'node:os'; const DIST_WORKER = path.resolve( __dirname, @@ -185,6 +186,38 @@ describe('worker pool integration', () => { }, ); + it('treats warning messages as non-terminal and still resolves the worker result', async () => { + const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gitnexus-worker-warning-')); + const workerPath = path.join(tempDir, 'warning-worker.js'); + fs.writeFileSync(workerPath, ` + const { parentPort } = require('node:worker_threads'); + parentPort.on('message', (msg) => { + if (msg && msg.type === 'sub-batch') { + parentPort.postMessage({ type: 'warning', message: 'warning before result' }); + parentPort.postMessage({ type: 'sub-batch-done' }); + return; + } + if (msg && msg.type === 'flush') { + parentPort.postMessage({ type: 'result', data: { nodes: [], relationships: [], symbols: [], imports: [], calls: [], heritage: [], routes: [], fileCount: 1 } }); + } + }); + `); + + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined); + const workerUrl = pathToFileURL(workerPath) as URL; + pool = createWorkerPool(workerUrl, 1); + + try { + const results = await pool.dispatch([{ path: 'warning.ts', content: 'const x = 1;' }]); + expect(results).toHaveLength(1); + expect(results[0].fileCount).toBe(1); + expect(warnSpy).toHaveBeenCalledWith('warning before result'); + } finally { + warnSpy.mockRestore(); + fs.rmSync(tempDir, { recursive: true, force: true }); + } + }); + it.skipIf(!hasDistWorker)('createWorkerPool with size 0 creates pool with zero workers', () => { const workerUrl = pathToFileURL(DIST_WORKER) as URL; const zeroPool = createWorkerPool(workerUrl, 0); From 04f8e2a899180b99938504d98d5d5579dcbcffd1 Mon Sep 17 00:00:00 2001 From: gujishh Date: Fri, 17 Apr 2026 10:35:10 +0900 Subject: [PATCH 2/2] style: apply prettier formatting --- gitnexus/test/integration/worker-pool.test.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gitnexus/test/integration/worker-pool.test.ts b/gitnexus/test/integration/worker-pool.test.ts index b3c90b60b0..072d9e24c1 100644 --- a/gitnexus/test/integration/worker-pool.test.ts +++ b/gitnexus/test/integration/worker-pool.test.ts @@ -189,7 +189,9 @@ describe('worker pool integration', () => { it('treats warning messages as non-terminal and still resolves the worker result', async () => { const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gitnexus-worker-warning-')); const workerPath = path.join(tempDir, 'warning-worker.js'); - fs.writeFileSync(workerPath, ` + fs.writeFileSync( + workerPath, + ` const { parentPort } = require('node:worker_threads'); parentPort.on('message', (msg) => { if (msg && msg.type === 'sub-batch') { @@ -201,14 +203,17 @@ describe('worker pool integration', () => { parentPort.postMessage({ type: 'result', data: { nodes: [], relationships: [], symbols: [], imports: [], calls: [], heritage: [], routes: [], fileCount: 1 } }); } }); - `); + `, + ); const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined); const workerUrl = pathToFileURL(workerPath) as URL; pool = createWorkerPool(workerUrl, 1); try { - const results = await pool.dispatch([{ path: 'warning.ts', content: 'const x = 1;' }]); + const results = await pool.dispatch([ + { path: 'warning.ts', content: 'const x = 1;' }, + ]); expect(results).toHaveLength(1); expect(results[0].fileCount).toBe(1); expect(warnSpy).toHaveBeenCalledWith('warning before result');