File: C:/Users/fred/.codex/.tmp/plugins/plugins/wix/skills/wix-headless/scripts/emit-design-tokens.mjs
#!/usr/bin/env node
// Generate .wix/design-tokens.css and .wix/site.d.ts deterministically from a
// designTokens JSON payload piped in on stdin. Invoked by the wix-headless
// skill orchestrator immediately after the Phase 2 Design System agent
// returns — the orchestrator pipes designerReturn.data.designTokens directly,
// no site.json round-trip.
//
// Why a script (not agent work): both files are pure projections of the
// designTokens JSON — no judgment, no brand-context dependence. An LLM
// emitting them is wasted tokens AND a drift risk (malformed :root blocks,
// missing token groups, divergent .d.ts skeletons).
//
// Usage:
// echo '<designTokens-json>' | node emit-design-tokens.mjs <project-dir>
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
import { join } from "node:path";
const projectDir = process.argv[2] ?? process.cwd();
if (process.stdin.isTTY) {
console.error("emit-design-tokens: expected designTokens JSON on stdin (pipe in the designer's data.designTokens block)");
process.exit(2);
}
let tokens;
try {
const raw = readFileSync(0, "utf8").trim();
if (!raw) {
console.error("emit-design-tokens: stdin was empty — pass the designTokens JSON object");
process.exit(2);
}
tokens = JSON.parse(raw);
} catch (e) {
console.error(`emit-design-tokens: stdin is not valid JSON (${e.message})`);
process.exit(2);
}
if (!tokens || typeof tokens !== "object" || Array.isArray(tokens) || Object.keys(tokens).length === 0) {
console.error("emit-design-tokens: designTokens payload must be a non-empty JSON object");
process.exit(2);
}
const wixDir = join(projectDir, ".wix");
mkdirSync(wixDir, { recursive: true });
const PREFIX = {
colors: "--color-",
fonts: "--font-",
radii: "--radius-",
spacing: "--spacing-",
containers: "--container-",
};
const cssLines = ["/* Generated by emit-design-tokens.mjs. Do not edit. */", ":root {"];
for (const [group, prefix] of Object.entries(PREFIX)) {
const entries = tokens[group] ?? {};
for (const [key, value] of Object.entries(entries)) {
cssLines.push(` ${prefix}${key}: ${value};`);
}
}
cssLines.push("}", "");
writeFileSync(join(wixDir, "design-tokens.css"), cssLines.join("\n"));
const typeFor = (group) => {
const keys = Object.keys(tokens[group] ?? {});
if (keys.length === 0) return "Record<string, string>";
const literal = keys.map((k) => JSON.stringify(k)).join(" | ");
return `Record<${literal}, string>`;
};
const dts = `// Generated by emit-design-tokens.mjs. Do not edit.
export type DesignTokens = {
colors: ${typeFor("colors")};
fonts: ${typeFor("fonts")};
radii: ${typeFor("radii")};
spacing: ${typeFor("spacing")};
containers: ${typeFor("containers")};
};
`;
writeFileSync(join(wixDir, "site.d.ts"), dts);
console.log(`emit-design-tokens: wrote ${join(wixDir, "design-tokens.css")} and ${join(wixDir, "site.d.ts")}`);