diff --git a/src/core/files.ts b/src/core/files.ts new file mode 100644 index 0000000..9026180 --- /dev/null +++ b/src/core/files.ts @@ -0,0 +1,38 @@ +import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync } from 'fs'; +import { dirname, join } from 'path'; +import YAML from 'yaml'; + +export interface EntityFile { + frontmatter: Record; + body: string; +} + +export function writeEntity(filePath: string, frontmatter: Record, body: string): void { + mkdirSync(dirname(filePath), { recursive: true }); + const yaml = YAML.stringify(frontmatter, { lineWidth: 0 }); + const content = `---\n${yaml}---\n${body}\n`; + writeFileSync(filePath, content, 'utf-8'); +} + +export function readEntity(filePath: string): EntityFile { + if (!existsSync(filePath)) { + throw new Error(`File not found: ${filePath}`); + } + const content = readFileSync(filePath, 'utf-8'); + const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/); + + if (!match) { + throw new Error(`Invalid entity format in ${filePath}`); + } + + const frontmatter = YAML.parse(match[1]) as Record; + const body = match[2].trim(); + + return { frontmatter, body }; +} + +export function listEntities(dir: string): string[] { + if (!existsSync(dir)) return []; + const entries = readdirSync(dir); + return entries.filter((f) => f.endsWith('.md')).map((f) => join(dir, f)); +} diff --git a/tests/files.test.ts b/tests/files.test.ts new file mode 100644 index 0000000..103aa1f --- /dev/null +++ b/tests/files.test.ts @@ -0,0 +1,30 @@ +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { mkdtempSync, rmSync, existsSync } from 'fs'; +import { tmpdir } from 'os'; +import { join } from 'path'; +import { writeEntity, readEntity } from '../src/core/files.js'; + +describe('files', () => { + let cwd: string; + + beforeEach(() => { + cwd = mkdtempSync(join(tmpdir(), 'agenthub-')); + }); + + afterEach(() => { + rmSync(cwd, { recursive: true, force: true }); + }); + + it('writes and reads a markdown entity', () => { + const filePath = join(cwd, 'test.md'); + const frontmatter = { id: 'TSK-0001', title: 'Test' }; + const body = '# Test\n\nHello'; + + writeEntity(filePath, frontmatter, body); + const result = readEntity(filePath); + + expect(result.frontmatter.id).toBe('TSK-0001'); + expect(result.body.trim()).toBe('# Test\n\nHello'); + expect(existsSync(filePath)).toBe(true); + }); +});