import process from "node:process"; import { readFile, writeFile } from "node:fs/promises"; import { resolve } from "node:path"; import { zodToJsonSchema } from "zod-to-json-schema"; import { answerUiCatalog, ANSWER_UI_VERSION } from "../src/features/agent/answer-ui/catalog.ts"; const check = process.argv.includes("--check"); const destination = process.argv.slice(2).find((arg) => arg !== "--check"); const targets = destination ? [resolve(destination)] : [ resolve("../next-tjwater-agent/src/chat/answer-ui-catalog.json"), resolve("../next-tjwater-server/contracts/answer-ui-catalog.json") ]; const contract = { version: ANSWER_UI_VERSION, description: "Generated from supply frontend src/features/agent/answer-ui/catalog.ts. Regenerate after catalog changes.", schema: answerUiCatalog.jsonSchema(), components: answerUiCatalog.componentNames, props: Object.fromEntries( Object.entries(answerUiCatalog.data.components).map(([name, definition]) => [ name, zodToJsonSchema(definition.props, { $refStrategy: "none" }) ]) ) }; const content = `${JSON.stringify(contract, null, 2)}\n`; for (const target of targets) { if (check) { if (await readFile(target, "utf8") !== content) throw new Error(`Answer UI contract differs: ${target}`); } else { await writeFile(target, content); } process.stdout.write(`${check ? "Checked" : "Exported"} ${contract.components.length} components ${check ? "in" : "to"} ${target}\n`); }