import { readdir, readFile } from "node:fs/promises"; import { join } from "node:path"; import { type Db, researchTemplates } from "@autoscholar/db"; import { eq } from "drizzle-orm"; const TEMPLATE_META: Record = { general: { name: "General research brief", mode: "empirical", description: "Discipline-agnostic starter covering every section a good research instruction needs.", }, empirical: { name: "Empirical study", mode: "empirical", description: "Data-driven analysis with provenance, executed code, identification limits and robustness.", }, theoretical: { name: "Theoretical result", mode: "theoretical", description: "Definitions, propositions, derivations, counterexample search and optional formal proof.", }, computational: { name: "Computational / AI study", mode: "computational", description: "Executable benchmark with baselines, seeds, ablations and resource budgets.", }, review: { name: "Literature review", mode: "review", description: "Systematic or narrative synthesis with search protocol, screening and verified references.", }, }; /** Loads research/templates//CLAUDE.md into the DB (idempotent; bumps version when content changes). */ export async function syncTemplates(db: Db, templatesDir: string): Promise { const synced: string[] = []; let dirs: string[] = []; try { dirs = (await readdir(templatesDir, { withFileTypes: true })) .filter((d) => d.isDirectory() && TEMPLATE_META[d.name]) .map((d) => d.name); } catch { return synced; } for (const slug of dirs) { let content: string; try { content = await readFile(join(templatesDir, slug, "CLAUDE.md"), "utf8"); } catch { continue; } const meta = TEMPLATE_META[slug]!; const [existing] = await db .select() .from(researchTemplates) .where(eq(researchTemplates.slug, slug)) .limit(1); if (!existing) { await db .insert(researchTemplates) .values({ slug, name: meta.name, mode: meta.mode, description: meta.description, content }); synced.push(slug); } else if (existing.content !== content) { await db .update(researchTemplates) .set({ content, version: existing.version + 1, updatedAt: new Date(), name: meta.name, description: meta.description, mode: meta.mode, }) .where(eq(researchTemplates.id, existing.id)); synced.push(slug); } } return synced; } export async function listTemplates(db: Db) { return db.select().from(researchTemplates).orderBy(researchTemplates.slug); }