diff --git a/src/core/config.ts b/src/core/config.ts new file mode 100644 index 0000000..4fa0e6f --- /dev/null +++ b/src/core/config.ts @@ -0,0 +1,33 @@ +import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs'; +import { dirname } from 'path'; +import { getConfigPath } from './paths.js'; +import { ConfigSchema, type Config } from './schema.js'; + +export function defaultConfig(projectName: string): Config { + return { + version: '1', + projectName, + delegationMode: 'suggest', + roles: { + architect: { preferredAgent: 'claude' }, + implementer: { preferredAgent: 'codex' }, + reviewer: { preferredAgent: 'claude' }, + tester: { preferredAgent: 'codex' }, + }, + }; +} + +export function loadConfig(cwd: string): Config { + const path = getConfigPath(cwd); + if (!existsSync(path)) { + throw new Error('AgentHub not initialized. Run: agenthub init'); + } + const raw = JSON.parse(readFileSync(path, 'utf-8')); + return ConfigSchema.parse(raw); +} + +export function saveConfig(cwd: string, config: Config): void { + const path = getConfigPath(cwd); + mkdirSync(dirname(path), { recursive: true }); + writeFileSync(path, JSON.stringify(config, null, 2), 'utf-8'); +} diff --git a/tests/config.test.ts b/tests/config.test.ts new file mode 100644 index 0000000..c988e56 --- /dev/null +++ b/tests/config.test.ts @@ -0,0 +1,25 @@ +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { mkdtempSync, rmSync } from 'fs'; +import { tmpdir } from 'os'; +import { join } from 'path'; +import { loadConfig, saveConfig, defaultConfig } from '../src/core/config.js'; + +describe('config', () => { + let cwd: string; + + beforeEach(() => { + cwd = mkdtempSync(join(tmpdir(), 'agenthub-')); + }); + + afterEach(() => { + rmSync(cwd, { recursive: true, force: true }); + }); + + it('creates and loads default config', () => { + const cfg = defaultConfig('test-project'); + saveConfig(cwd, cfg); + const loaded = loadConfig(cwd); + expect(loaded.projectName).toBe('test-project'); + expect(loaded.delegationMode).toBe('suggest'); + }); +});