fix: Windows platform improvements — re-enable Chroma, fix DB race, simplify env isolation

1. ProcessManager: Migrate spawnDaemon() from WMIC to PowerShell Start-Process
   - WMIC deprecated in Windows 11, PowerShell inherits env vars properly
   - Use -WindowStyle Hidden to prevent console popups
   - Fix redundant backslash escaping in PowerShell $_ variables

2. ChromaSync: Re-enable vector search on Windows
   - Remove overly defensive platform check that disabled all semantic search
   - Worker daemon starts with -WindowStyle Hidden; child processes inherit
   - MCP SDK's StdioClientTransport uses shell:false, no new console created

3. worker-service: Unified DB-ready gate middleware
   - Replace single-endpoint /api/sessions/init wait with global middleware
   - Hold all DB-dependent requests until database is initialized (30s timeout)
   - Whitelist static assets, /health, and viewer page for immediate response
   - Separate dbReadyPromise (DB only) from initializationComplete (full init)
   - Fixes "Database not initialized" errors on /stream, /summarize, /init

4. EnvManager: Switch from allowlist to blocklist for subprocess env
   - Only strip ANTHROPIC_API_KEY to prevent Issue #733 billing hijack
   - Pass through all other vars (ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, etc.)
   - Simpler, less fragile than maintaining an exhaustive system vars allowlist
This commit is contained in:
xingyu
2026-02-07 16:17:18 +08:00
parent dac989c697
commit e4e1d3fb92
3 changed files with 49 additions and 78 deletions
+7 -21
View File
@@ -85,25 +85,15 @@ export class ChromaSync {
private readonly VECTOR_DB_DIR: string;
private readonly BATCH_SIZE = 100;
// Windows: Chroma disabled due to MCP SDK spawning console popups
// See: https://github.com/anthropics/claude-mem/issues/675
// Will be re-enabled when we migrate to persistent HTTP server
private readonly disabled: boolean;
// Windows popup concern resolved: the worker daemon starts with -WindowStyle Hidden,
// so child processes (uvx/chroma-mcp) inherit the hidden console and don't create new windows.
// MCP SDK's StdioClientTransport uses shell:false and no detached flag, so console is inherited.
private readonly disabled: boolean = false;
constructor(project: string) {
this.project = project;
this.collectionName = `cm__${project}`;
this.VECTOR_DB_DIR = path.join(os.homedir(), '.claude-mem', 'vector-db');
// Disable on Windows to prevent console popups from MCP subprocess spawning
// The MCP SDK's StdioClientTransport spawns Python processes that create visible windows
this.disabled = process.platform === 'win32';
if (this.disabled) {
logger.warn('CHROMA_SYNC', 'Vector search disabled on Windows (prevents console popups)', {
project: this.project,
reason: 'MCP SDK subprocess spawning causes visible console windows'
});
}
}
/**
@@ -203,7 +193,6 @@ export class ChromaSync {
// See: https://github.com/thedotmack/claude-mem/issues/170 (Python 3.14 incompatibility)
const settings = SettingsDefaultsManager.loadFromFile(USER_SETTINGS_PATH);
const pythonVersion = settings.CLAUDE_MEM_PYTHON_VERSION;
const isWindows = process.platform === 'win32';
// Get combined SSL certificate bundle for Zscaler/corporate proxy environments
const combinedCertPath = this.getCombinedCertPath();
@@ -232,12 +221,9 @@ export class ChromaSync {
});
}
// CRITICAL: On Windows, try to hide console window to prevent PowerShell popups
// Note: windowsHide may not be supported by MCP SDK's StdioClientTransport
if (isWindows) {
transportOptions.windowsHide = true;
logger.debug('CHROMA_SYNC', 'Windows detected, attempting to hide console window', { project: this.project });
}
// Note: windowsHide is not needed here because the worker daemon starts with
// -WindowStyle Hidden, so child processes inherit the hidden console.
// The MCP SDK ignores custom windowsHide anyway (overridden internally).
this.transport = new StdioClientTransport(transportOptions);