From 2191427605dbeca49a986f15acffe1f1128fe565 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Thu, 2 Apr 2026 22:20:52 -0700 Subject: [PATCH] =?UTF-8?q?fix(cowork-service):=203=20bugs=20=E2=80=94=20f?= =?UTF-8?q?lag=20names,=20IPC=20call=20guard,=20health=20status?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG 1: feature-flags.ts had 3 wrong flag names + missing 3 from seed.ts - Removed: browser_extension_enabled, institutional_knowledge_enabled - Renamed: connectors_enabled → mcp_connectors_enabled - Added: llm_multi_model_enabled, telemetry_enabled, platform_auth_required - Fixed defaults to match seed.ts (marketplace_enabled=true, dispatch_api_enabled=true) - Now 13 flags exactly matching platform-service/src/modules/flags/seed.ts BUG 2: ipc-bridge.ts call() had 'initialize' exemption that allowed null deref - If call('initialize') was invoked externally without start(), the guard passed but this.child!.stdin!.write() would crash with null dereference - During normal start(), child.stdin.writable is true so no exemption needed - Removed the method !== 'initialize' exemption BUG 3: health routes didn't factor IPC bridge into overall health status - allOk only checked platform-service reachability - Now allOk = depsOk && ipcConnected — service reports 503 when bridge is down - IPC bridge disconnection makes health 'degraded' (correct — fallback mode works) 24 tests passing, typecheck clean. --- services/cowork-service/src/lib/feature-flags.ts | 15 +++++++++------ services/cowork-service/src/lib/ipc-bridge.ts | 2 +- .../cowork-service/src/modules/health/routes.ts | 6 ++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/services/cowork-service/src/lib/feature-flags.ts b/services/cowork-service/src/lib/feature-flags.ts index 84374d8d..002b9d7b 100644 --- a/services/cowork-service/src/lib/feature-flags.ts +++ b/services/cowork-service/src/lib/feature-flags.ts @@ -9,18 +9,21 @@ import { config } from './config.js'; const registry = createFlagRegistry({ defaults: { + // ── Product-specific flags (seed.ts clawcowork entry) ── sandbox_enabled: true, plugins_enabled: true, - computer_use_enabled: false, - browser_extension_enabled: false, - connectors_enabled: true, + mcp_connectors_enabled: true, scheduling_enabled: true, + computer_use_enabled: false, parallel_agents_enabled: true, + marketplace_enabled: true, wasm_plugins_enabled: false, - dispatch_api_enabled: false, - marketplace_enabled: false, - institutional_knowledge_enabled: false, + llm_multi_model_enabled: false, audit_logging_enabled: true, + platform_auth_required: false, + dispatch_api_enabled: true, + // ── Common flag (from COMMON_FLAGS in seed.ts) ── + telemetry_enabled: false, }, enabled: config.FEATURE_FLAGS_ENABLED, }); diff --git a/services/cowork-service/src/lib/ipc-bridge.ts b/services/cowork-service/src/lib/ipc-bridge.ts index 5da4e317..0badaeeb 100644 --- a/services/cowork-service/src/lib/ipc-bridge.ts +++ b/services/cowork-service/src/lib/ipc-bridge.ts @@ -109,7 +109,7 @@ export class IpcBridge { /** Send a JSON-RPC call and await the response. */ async call(method: string, params: Record): Promise { - if (!this.child?.stdin?.writable && method !== 'initialize') { + if (!this.child?.stdin?.writable) { throw new Error('IPC bridge not started'); } diff --git a/services/cowork-service/src/modules/health/routes.ts b/services/cowork-service/src/modules/health/routes.ts index 8630e0b0..99b331ca 100644 --- a/services/cowork-service/src/modules/health/routes.ts +++ b/services/cowork-service/src/modules/health/routes.ts @@ -31,13 +31,15 @@ export async function healthRoutes(app: FastifyInstance) { }; } - const allOk = Object.values(checks).every(c => c.status === 'ok'); + const ipcConnected = getIpcBridge().isRunning; + const depsOk = Object.values(checks).every(c => c.status === 'ok'); + const allOk = depsOk && ipcConnected; reply.code(allOk ? 200 : 503); return { status: allOk ? 'ok' : 'degraded', service: config.SERVICE_NAME, productId: PRODUCT_ID, - ipcBridge: getIpcBridge().isRunning ? 'connected' : 'disconnected', + ipcBridge: ipcConnected ? 'connected' : 'disconnected', checks, timestamp: new Date().toISOString(), };