diff --git a/plugin/hooks/hooks.json b/plugin/hooks/hooks.json index aba9df818..bfc5446b2 100644 --- a/plugin/hooks/hooks.json +++ b/plugin/hooks/hooks.json @@ -13,7 +13,7 @@ { "type": "command", "command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start", - "timeout": 15 + "timeout": 45 }, { "type": "command", @@ -34,7 +34,7 @@ { "type": "command", "command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start", - "timeout": 15 + "timeout": 45 }, { "type": "command", @@ -51,7 +51,7 @@ { "type": "command", "command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start", - "timeout": 15 + "timeout": 45 }, { "type": "command", @@ -67,7 +67,7 @@ { "type": "command", "command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start", - "timeout": 15 + "timeout": 45 }, { "type": "command", diff --git a/src/services/worker-service.ts b/src/services/worker-service.ts index 342d088d9..7acfe3bd3 100644 --- a/src/services/worker-service.ts +++ b/src/services/worker-service.ts @@ -155,7 +155,8 @@ async function waitForHealth(port: number, timeoutMs: number = 30000): Promise { + if (this.coreReady) { + res.status(200).json({ + status: 'ready', + mcpReady: this.mcpReady, + }); + } else { + res.status(503).json({ + status: 'initializing', + message: 'Core services still initializing, please retry', + }); + } + }); + + // Full readiness check endpoint - returns 503 until full initialization completes (including MCP) + // Used for diagnostics and anything that requires MCP to be connected this.app.get('/api/readiness', (_req, res) => { if (this.initializationCompleteFlag) { res.status(200).json({ @@ -687,6 +709,11 @@ export class WorkerService { this.searchRoutes.setupRoutes(this.app); // Setup search routes now that SearchManager is ready logger.info('WORKER', 'SearchManager initialized and search routes registered'); + // Core services are ready - hooks can now work (database + SearchManager) + // MCP connection happens next but hooks don't need it + this.coreReady = true; + logger.info('SYSTEM', 'Core services ready (hooks can now proceed)'); + // Connect to MCP server with timeout guard const mcpServerPath = path.join(__dirname, 'mcp-server.cjs'); const transport = new StdioClientTransport({ diff --git a/src/shared/worker-utils.ts b/src/shared/worker-utils.ts index c09b34468..7075ae728 100644 --- a/src/shared/worker-utils.ts +++ b/src/shared/worker-utils.ts @@ -57,13 +57,14 @@ export function clearPortCache(): void { } /** - * Check if worker is responsive and fully initialized by trying the readiness endpoint - * Changed from /health to /api/readiness to ensure MCP initialization is complete + * Check if worker core services are ready (database + SearchManager) + * Uses /api/core-ready - hooks don't need MCP, only core services + * Full readiness (including MCP) is checked via /api/readiness for diagnostics */ async function isWorkerHealthy(): Promise { const port = getWorkerPort(); // Note: Removed AbortSignal.timeout to avoid Windows Bun cleanup issue (libuv assertion) - const response = await fetch(`http://127.0.0.1:${port}/api/readiness`); + const response = await fetch(`http://127.0.0.1:${port}/api/core-ready`); return response.ok; }