UNPKG

automagik-genie

Version:

Self-evolving AI agent orchestration framework with Model Context Protocol support

145 lines (144 loc) 5.48 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.recordStartupWarning = recordStartupWarning; exports.getStartupWarnings = getStartupWarnings; exports.clearStartupWarnings = clearStartupWarnings; exports.buildDefaultConfig = buildDefaultConfig; exports.loadConfig = loadConfig; exports.resolvePaths = resolvePaths; exports.prepareDirectories = prepareDirectories; exports.applyDefaults = applyDefaults; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const utils_1 = require("./utils"); const paths_1 = require("./paths"); let YAML = null; try { // eslint-disable-next-line @typescript-eslint/no-var-requires YAML = require('yaml'); } catch (_) { // yaml module optional } const BASE_CONFIG = { defaults: { executor: 'OPENCODE', executorVariant: 'DEFAULT', background: false }, paths: { baseDir: undefined, tasksFile: '.genie/state/tasks.json', logsDir: '.genie/state/agents/logs', backgroundDir: '.genie/state/agents/background' }, forge: { executors: {} }, executionModes: {} }; function resolveConfigPath() { try { const root = (0, paths_1.findWorkspaceRoot)(); const projectConfig = path_1.default.join(root, '.genie', 'config.yaml'); if (fs_1.default.existsSync(projectConfig)) return projectConfig; } catch (_) { } return path_1.default.join(path_1.default.dirname(__dirname), 'config.yaml'); } const CONFIG_PATH = resolveConfigPath(); const startupWarnings = []; function recordStartupWarning(message) { startupWarnings.push(message); } function getStartupWarnings() { return [...startupWarnings]; } function clearStartupWarnings() { startupWarnings.length = 0; } function buildDefaultConfig() { return (0, utils_1.deepClone)(BASE_CONFIG); } function loadConfig() { let config = (0, utils_1.deepClone)(buildDefaultConfig()); const configFilePath = fs_1.default.existsSync(CONFIG_PATH) ? CONFIG_PATH : null; if (configFilePath) { try { const raw = fs_1.default.readFileSync(configFilePath, 'utf8'); if (raw.trim().length) { let parsed = {}; if (YAML) { parsed = YAML.parse(raw) || {}; } else if (raw.trim().startsWith('{')) { try { parsed = JSON.parse(raw); } catch { parsed = {}; } } else { recordStartupWarning('[genie] YAML module unavailable; ignoring config overrides. Install "yaml" to enable parsing.'); parsed = {}; } config = (0, utils_1.mergeDeep)(config, parsed); } } catch (error) { const message = error instanceof Error ? error.message : String(error); throw new Error(`Failed to parse ${configFilePath}: ${message}`); } config.__configPath = configFilePath; } else { config.__configPath = CONFIG_PATH; } // Ensure defaults exist config.defaults = config.defaults || {}; if (!config.defaults.executor) config.defaults.executor = 'OPENCODE'; if (!config.defaults.executorVariant) config.defaults.executorVariant = 'DEFAULT'; config.defaults.background = config.defaults.background ?? false; config.forge = config.forge || { executors: {} }; config.forge.executors = config.forge.executors || {}; config.executionModes = config.executionModes || {}; return config; } function resolvePaths(paths) { const baseDir = paths.baseDir ? path_1.default.resolve(paths.baseDir) : (0, paths_1.findWorkspaceRoot)(); const tasksFile = paths.tasksFile ? path_1.default.resolve(baseDir, paths.tasksFile) : path_1.default.join(baseDir, '.genie/state/tasks.json'); return { baseDir, tasksFile, logsDir: paths.logsDir || path_1.default.join(baseDir, '.genie/state/agents/logs'), backgroundDir: paths.backgroundDir || path_1.default.join(baseDir, '.genie/state/agents/background') }; } function prepareDirectories(paths) { [paths.logsDir, paths.backgroundDir, path_1.default.dirname(paths.tasksFile)].forEach((dir) => { if (!fs_1.default.existsSync(dir)) { fs_1.default.mkdirSync(dir, { recursive: true }); } }); } function applyDefaults(options, defaults) { // Only apply config defaults if user hasn't explicitly set --background or --no-background // The run command defaults to foreground (interactive) mode, so we don't force background: true // Users can still pass --background to enable headless mode if (!options.backgroundExplicit && defaults?.background !== undefined) { // Respect explicit config override, but don't force background: true by default // This allows the run command to default to foreground (interactive) mode options.background = defaults.background; } // Note: if backgroundExplicit is false and defaults.background is undefined, // options.background stays as initialized (false), enabling foreground mode }