From 29bc18502fb93fe0ef95136562d8fff1277675bc Mon Sep 17 00:00:00 2001 From: William Valentin Date: Mon, 9 Feb 2026 20:57:12 -0800 Subject: [PATCH] feat(02-01): wire FLYNN_ENV resolution into shared.ts with overlay-aware loadConfigSafe - Add resolveOverlayPath() that maps FLYNN_ENV to {configDir}/{env}.yaml - Update loadConfigSafe to pass overlay path through to loadConfig - All CLI commands using loadConfigSafe() automatically get overlay support - No FLYNN_ENV = exact same behavior as before (backward compatible) - Full test suite passes (1087 tests, zero regressions) --- src/cli/shared.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/cli/shared.ts b/src/cli/shared.ts index 860514b..1ee27a9 100644 --- a/src/cli/shared.ts +++ b/src/cli/shared.ts @@ -1,6 +1,6 @@ import { loadConfig } from '../config/index.js'; import type { Config } from '../config/index.js'; -import { resolve } from 'path'; +import { resolve, dirname, join } from 'path'; import { homedir } from 'os'; /** Get the config file path from env or default location. */ @@ -13,11 +13,25 @@ export function getDataDir(): string { return process.env.FLYNN_DATA_DIR ?? resolve(homedir(), '.local/share/flynn'); } +/** + * Resolve overlay config path from FLYNN_ENV. + * If FLYNN_ENV is set, returns {configDir}/{FLYNN_ENV}.yaml relative to the base config file. + * Returns undefined if FLYNN_ENV is not set. + * Does NOT check if the file exists — caller decides error handling. + */ +export function resolveOverlayPath(basePath: string): string | undefined { + const env = process.env.FLYNN_ENV; + if (!env) return undefined; + const configDir = dirname(basePath); + return join(configDir, `${env}.yaml`); +} + /** Load config without throwing. Returns { config } or { error }. */ export function loadConfigSafe(configPath?: string): { config?: Config; error?: string } { const path = configPath ?? getConfigPath(); try { - const config = loadConfig(path); + const overlayPath = resolveOverlayPath(path); + const config = loadConfig(path, overlayPath); return { config }; } catch (error) { const message = error instanceof Error ? error.message : String(error);