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)
This commit is contained in:
William Valentin
2026-02-09 20:57:12 -08:00
parent c2cc052694
commit 29bc18502f
+16 -2
View File
@@ -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);