feat(files): add markdown entity read/write

This commit is contained in:
chahinebrini 2026-06-24 23:32:14 +02:00
parent dd27e8caba
commit 57bb572bf5
2 changed files with 68 additions and 0 deletions

38
src/core/files.ts Normal file
View File

@ -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<string, unknown>;
body: string;
}
export function writeEntity(filePath: string, frontmatter: Record<string, unknown>, 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<string, unknown>;
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));
}

30
tests/files.test.ts Normal file
View File

@ -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);
});
});