HEX
Server: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/8.4.25
System: Windows NT DESKTOP-4TAV2RJ 10.0 build 19045 (Windows 10) AMD64
User: fred (0)
PHP: 8.4.25
Disabled: NONE
Upload Files
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")}`);