* Writes a magic-context.jsonc file inside a fresh temp XDG_CONFIG_HOME tree * and runs loadPluginConfig against it. Returns warnings + parsed config. * * Scope directory is NOT set — we pass a unique directory that does not * contain a project config so only the user config is loaded.
(configText: string, extraEnv: Record<string, string> = {})
| 13 | * contain a project config so only the user config is loaded. |
| 14 | */ |
| 15 | function loadWithUserConfig(configText: string, extraEnv: Record<string, string> = {}) { |
| 16 | const xdg = mkdtempSync(join(tmpdir(), "mc-config-test-")); |
| 17 | // Hard cutover: the loader reads user config from <XDG>/cortexkit/. |
| 18 | const configDir = join(xdg, "cortexkit"); |
| 19 | const fs = require("node:fs") as typeof import("node:fs"); |
| 20 | fs.mkdirSync(configDir, { recursive: true }); |
| 21 | writeFileSync(join(configDir, "magic-context.jsonc"), configText, "utf-8"); |
| 22 | |
| 23 | const origXdg = process.env.XDG_CONFIG_HOME; |
| 24 | const savedEnv: Record<string, string | undefined> = {}; |
| 25 | for (const [k, v] of Object.entries(extraEnv)) { |
| 26 | savedEnv[k] = process.env[k]; |
| 27 | process.env[k] = v; |
| 28 | } |
| 29 | process.env.XDG_CONFIG_HOME = xdg; |
| 30 | |
| 31 | // Use a directory that definitely has no project config so only the |
| 32 | // user config feeds the loader. We use a sibling temp directory. |
| 33 | const projectDir = mkdtempSync(join(tmpdir(), "mc-config-proj-")); |
| 34 | try { |
| 35 | return loadPluginConfig(projectDir); |
| 36 | } finally { |
| 37 | if (origXdg === undefined) { |
| 38 | delete process.env.XDG_CONFIG_HOME; |
| 39 | } else { |
| 40 | process.env.XDG_CONFIG_HOME = origXdg; |
| 41 | } |
| 42 | for (const [k, v] of Object.entries(savedEnv)) { |
| 43 | if (v === undefined) delete process.env[k]; |
| 44 | else process.env[k] = v; |
| 45 | } |
| 46 | try { |
| 47 | rmSync(xdg, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 }); |
| 48 | } catch { |
| 49 | /* Ignore EBUSY on Windows */ |
| 50 | } |
| 51 | try { |
| 52 | rmSync(projectDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 }); |
| 53 | } catch { |
| 54 | /* Ignore EBUSY on Windows */ |
| 55 | } |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | function loadWithUserAndProjectConfig( |
| 60 | userConfigText: string, |
no test coverage detected