/ src / utils / load-env.js
load-env.js
 1  /**
 2   * Centralised environment loader.
 3   *
 4   * Loads three .env files in order (values set first win):
 5   *   1. .env          — core config (pipeline, browser, dashboard, compliance)
 6   *   2. .env.secrets  — API keys, tokens, passwords
 7   *   3. .env.agents   — agent system, reaper, spawn settings
 8   *
 9   * Usage:  import './utils/load-env.js';          (from src/)
10   *    or:  import '../utils/load-env.js';         (from src/cli/)
11   *    or:  import '../../src/utils/load-env.js';  (from tests/)
12   *
13   * Existing vars (e.g. from shell) are never overwritten.
14   */
15  
16  import { config } from 'dotenv';
17  import { resolve, dirname } from 'path';
18  import { fileURLToPath } from 'url';
19  
20  const __dirname = dirname(fileURLToPath(import.meta.url));
21  const root = resolve(__dirname, '../..');
22  
23  // Load in priority order — dotenv never overwrites existing values
24  // quiet: true suppresses dotenv v17 stdout tip messages (important for scripts that parse stdout)
25  config({ path: resolve(root, '.env'), quiet: true });
26  config({ path: resolve(root, '.env.secrets'), quiet: true });
27  config({ path: resolve(root, '.env.agents'), quiet: true });
28  
29  /**
30   * Parse a comma-separated env var into a Set of non-empty uppercase strings.
31   * Used for country lists, channel blocklists, etc.
32   * @param {string|undefined} value - The raw env var value
33   * @returns {Set<string>}
34   */
35  export function parseEnvSet(value) {
36    return new Set(
37      (value || '').split(',').map(s => s.trim().toUpperCase()).filter(Boolean)
38    );
39  }