From 88be01910b6ebfbfdf2932f6ad9c4d9b3484c49f Mon Sep 17 00:00:00 2001 From: Umut Polat <52835619+umut-polat@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:57:55 +0300 Subject: [PATCH] fix: respect env vars and settings.json for DATA_DIR resolution (#1344) SettingsDefaultsManager.get() returned only the hardcoded default, ignoring both environment variables and settings.json overrides. This meant CLAUDE_MEM_DATA_DIR set via env or settings file had no effect on paths.ts (and other callers using get()). Two changes: - get() now checks process.env before falling back to the default - paths.ts resolves DATA_DIR with full priority: env var > settings.json at the default location > hardcoded default The settings file read uses a synchronous bootstrap pattern to avoid circular dependencies (DATA_DIR is needed to locate the settings file, so we check the default path only). Fixes #1303 Signed-off-by: umut-polat <52835619+umut-polat@users.noreply.github.com> --- src/shared/SettingsDefaultsManager.ts | 9 ++++++-- src/shared/paths.ts | 32 ++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/shared/SettingsDefaultsManager.ts b/src/shared/SettingsDefaultsManager.ts index 037bd904..923520ca 100644 --- a/src/shared/SettingsDefaultsManager.ts +++ b/src/shared/SettingsDefaultsManager.ts @@ -133,10 +133,15 @@ export class SettingsDefaultsManager { } /** - * Get a default value from defaults (no environment variable override) + * Get a setting value with environment variable override. + * Priority: process.env > hardcoded default + * + * For full priority (env > settings file > default), use loadFromFile(). + * This method is safe to call at module-load time (no file I/O) and still + * respects environment variable overrides that were previously ignored. */ static get(key: keyof SettingsDefaults): string { - return this.DEFAULTS[key]; + return process.env[key] ?? this.DEFAULTS[key]; } /** diff --git a/src/shared/paths.ts b/src/shared/paths.ts index 94c18189..24fb7f5d 100644 --- a/src/shared/paths.ts +++ b/src/shared/paths.ts @@ -24,7 +24,37 @@ const _dirname = getDirname(); */ // Base directories -export const DATA_DIR = SettingsDefaultsManager.get('CLAUDE_MEM_DATA_DIR'); +// Resolve DATA_DIR with full priority: env var > settings.json > default. +// SettingsDefaultsManager.get() handles env > default. For settings file +// support, we do a one-time synchronous read of the default settings path +// to check if the user configured a custom DATA_DIR there. +function resolveDataDir(): string { + // 1. Environment variable (highest priority) — already handled by get() + if (process.env.CLAUDE_MEM_DATA_DIR) { + return process.env.CLAUDE_MEM_DATA_DIR; + } + + // 2. Settings file at the default location + const defaultDataDir = join(homedir(), '.claude-mem'); + const settingsPath = join(defaultDataDir, 'settings.json'); + try { + if (existsSync(settingsPath)) { + const { readFileSync } = require('fs'); + const raw = JSON.parse(readFileSync(settingsPath, 'utf-8')); + const settings = raw.env ?? raw; // handle legacy nested schema + if (settings.CLAUDE_MEM_DATA_DIR) { + return settings.CLAUDE_MEM_DATA_DIR; + } + } + } catch { + // settings file missing or corrupt — fall through to default + } + + // 3. Hardcoded default + return defaultDataDir; +} + +export const DATA_DIR = resolveDataDir(); // Note: CLAUDE_CONFIG_DIR is a Claude Code setting, not claude-mem, so leave as env var export const CLAUDE_CONFIG_DIR = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude');