Files
WRNexusJS/scripts/evaluate-design-agents.ts

114 lines
4.2 KiB
TypeScript

/** Reproducible Phase 6 local agent evaluation. No provider calls, routes or deployments. */
import { mkdirSync, writeFileSync } from "node:fs";
import { resolve, join } from "node:path";
import { createFrameworkMcpServer } from "../packages/mcp/src/index.ts";
import { CORE_DESIGN_SYSTEMS } from "../packages/design-system/src/index.ts";
import { compileWrnFile } from "../packages/compiler/src/index.ts";
import { checkDesignConformance } from "../packages/design-studio/src/conformance.ts";
import type { AgentPage } from "../packages/design-studio/src/agent-pages.ts";
const output = resolve("output/design-system-phase-6");
mkdirSync(output, { recursive: true });
const report: Array<Record<string, unknown>> = [];
for (const [name, system] of Object.entries(CORE_DESIGN_SYSTEMS)) {
const directory = join(output, name);
mkdirSync(directory, { recursive: true });
writeFileSync(join(directory, "package.json"), "{}");
const server = createFrameworkMcpServer(directory, { design: true, designWrite: true });
let draft = (await server.call("wrnexus_design_inspect")) as { revision: string };
draft = (await server.call("wrnexus_design_create", {
baseRevision: draft.revision,
source: JSON.stringify(system),
})) as typeof draft;
const context = await server.call("wrnexus_design_context", {
components: ["PageHeader", "Input", "Button", "Alert"],
});
writeFileSync(join(directory, "agent-context.json"), JSON.stringify(context, null, 2));
for (const id of ["account", "support"]) {
const page: AgentPage = {
id,
title: id === "account" ? "Account settings" : "Contact support",
components: [
{
component: "PageHeader",
props: { title: id === "account" ? "Your profile" : "How can we help?" },
},
{
component: "Input",
props: { id: id + "-name", label: "Your name", placeholder: "Enter your name" },
},
{
component: "Input",
props: {
id: id + "-email",
label: "Email",
type: "email",
placeholder: "you@example.com",
},
},
{
component: "Alert",
props: {
title: "Design preview",
description: "This page uses your selected design system.",
},
},
{
component: "Button",
props: { label: id === "account" ? "Save profile" : "Send request", variant: "default" },
},
],
};
draft = (await server.call("wrnexus_design_page", {
baseRevision: draft.revision,
page,
})) as typeof draft;
for (const mode of ["light", "dark"]) {
const preview = (await server.call("wrnexus_design_preview", { pageId: id, mode })) as {
html: string;
};
writeFileSync(join(directory, `${id}-${mode}.html`), preview.html);
}
}
const exported = (await server.call("wrnexus_design_export")) as {
pages: Record<string, string>;
artifacts: Record<string, string>;
};
for (const [filename, source] of Object.entries(exported.pages)) {
writeFileSync(join(directory, filename), source);
const conformance = checkDesignConformance(source);
const compiled = compileWrnFile(source);
if (!conformance.ok || !compiled) throw Error("Agent evaluation failed.");
report.push({
system: name,
page: filename,
compiled: true,
conformance,
modes: ["light", "dark"],
preview: "Trusted shipped SSR components; static CSP-protected HTML.",
});
}
for (const [name, body] of Object.entries(exported.artifacts))
writeFileSync(join(directory, name + ".txt"), body);
}
writeFileSync(
join(output, "report.json"),
JSON.stringify(
{
passed: true,
pages: report.length,
previews: report.length * 2,
evaluations: report,
limits: [
"No LLM call. This exercises the agent tool protocol deterministically.",
"Static checks and SSR previews do not certify all accessibility, dynamic behavior or visual quality.",
"Generated pages and design artifacts require explicit application integration.",
],
},
null,
2,
),
);
console.log(
`Agent evaluation passed: ${report.length} pages and ${report.length * 2} previews. ${output}`,
);