import "dotenv/config"; import { existsSync } from "node:fs"; import { fileURLToPath } from "node:url"; import { and, eq, or } from "drizzle-orm"; import { type Persona, type PublishedRegistryRow, type RegistryEntry, type Template, assertNoReferencedRegistryDeletions, buildRegistrySeedPlan, loadPersonaFiles, loadTemplateFiles, } from "../packages/core/src/index.js"; import { createDbClient } from "../packages/db/src/client.js"; import { agentPersonas, runBindings, runs, workflowTemplates, } from "../packages/db/src/schema/index.js"; const databaseUrl = process.env.DATABASE_URL; if (!databaseUrl) { throw new Error("DATABASE_URL is required to seed registries"); } const personasDirectory = fileURLToPath(new URL("../docs/schemas/personas", import.meta.url)); const templatesDirectory = fileURLToPath(new URL("../docs/schemas/templates", import.meta.url)); const client = createDbClient(databaseUrl); try { const personas = loadRegistryDirectory(personasDirectory, loadPersonaFiles); const templates = loadRegistryDirectory(templatesDirectory, loadTemplateFiles); const result = { personas: await seedPersonas(personas), templates: await seedTemplates(templates), }; console.log(JSON.stringify(result, null, 2)); } finally { await client.close(); } function loadRegistryDirectory( directory: string, load: (directory: string) => RegistryEntry[], ) { if (!existsSync(directory)) { throw new Error(`Registry directory does not exist: ${directory}`); } return load(directory); } async function seedPersonas(entries: RegistryEntry[]) { const existing = await client.db .select({ id: agentPersonas.id, name: agentPersonas.name, version: agentPersonas.version, hash: agentPersonas.hash, }) .from(agentPersonas); const publishedRows: PublishedRegistryRow[] = []; for (const row of existing) { const reference = await client.db .select({ id: runBindings.id }) .from(runBindings) .where(or(eq(runBindings.personaId, row.id), eq(runBindings.personaHash, row.hash))) .limit(1); publishedRows.push({ ...row, referencedByRun: reference.length > 0 }); } const plan = buildRegistrySeedPlan(entries, publishedRows); assertNoReferencedRegistryDeletions("persona", plan); await deleteUnreferencedPersonas(plan.missingUnreferenced); for (const entry of plan.inserts) { await client.db.insert(agentPersonas).values({ name: entry.name, version: entry.version, hash: entry.hash, definition: entry.definition, }); } return summarizePlan(plan); } async function seedTemplates(entries: RegistryEntry