From 6f3e3516f7c13242f80007d655182e223ba4f68c Mon Sep 17 00:00:00 2001 From: Tabish Bidiwale Date: Sat, 20 Dec 2025 22:55:35 +1100 Subject: [PATCH] fix(global-config): respect XDG_CONFIG_HOME on all platforms Prioritize XDG_CONFIG_HOME on Windows to fix test environment overrides. Previously, Windows would always use APPDATA regardless of XDG_CONFIG_HOME, causing tests to fail. Now XDG_CONFIG_HOME is checked first on all platforms before falling back to platform-specific defaults. Also update the Windows APPDATA test to explicitly clear XDG_CONFIG_HOME when testing the fallback behavior. --- src/core/global-config.ts | 18 ++++++++++-------- test/core/global-config.test.ts | 3 ++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/core/global-config.ts b/src/core/global-config.ts index 65c6a8d5..b690113a 100644 --- a/src/core/global-config.ts +++ b/src/core/global-config.ts @@ -18,10 +18,17 @@ const DEFAULT_CONFIG: GlobalConfig = { /** * Gets the global configuration directory path following XDG Base Directory Specification. * - * - Unix/macOS: $XDG_CONFIG_HOME/openspec/ or ~/.config/openspec/ - * - Windows: %APPDATA%/openspec/ + * - All platforms: $XDG_CONFIG_HOME/openspec/ if XDG_CONFIG_HOME is set + * - Unix/macOS fallback: ~/.config/openspec/ + * - Windows fallback: %APPDATA%/openspec/ */ export function getGlobalConfigDir(): string { + // XDG_CONFIG_HOME takes precedence on all platforms when explicitly set + const xdgConfigHome = process.env.XDG_CONFIG_HOME; + if (xdgConfigHome) { + return path.join(xdgConfigHome, GLOBAL_CONFIG_DIR_NAME); + } + const platform = os.platform(); if (platform === 'win32') { @@ -34,12 +41,7 @@ export function getGlobalConfigDir(): string { return path.join(os.homedir(), 'AppData', 'Roaming', GLOBAL_CONFIG_DIR_NAME); } - // Unix/macOS: use XDG_CONFIG_HOME or fallback to ~/.config - const xdgConfigHome = process.env.XDG_CONFIG_HOME; - if (xdgConfigHome) { - return path.join(xdgConfigHome, GLOBAL_CONFIG_DIR_NAME); - } - + // Unix/macOS fallback: ~/.config return path.join(os.homedir(), '.config', GLOBAL_CONFIG_DIR_NAME); } diff --git a/test/core/global-config.test.ts b/test/core/global-config.test.ts index cdf75f0a..052d3201 100644 --- a/test/core/global-config.test.ts +++ b/test/core/global-config.test.ts @@ -70,10 +70,11 @@ describe('global-config', () => { } }); - it('should use APPDATA on Windows', () => { + it('should use APPDATA on Windows when XDG_CONFIG_HOME is not set', () => { // This test only makes sense conceptually - we can't change os.platform() // But we can verify the APPDATA logic by checking the code path if (os.platform() === 'win32') { + delete process.env.XDG_CONFIG_HOME; const appData = process.env.APPDATA; if (appData) { const result = getGlobalConfigDir();