← Files DataARCHIVED FILE

scripts/prebuilt/build.mjs

40.9 KB · Sep 30, 2026 · 23:19 UTC

↓ Download file

import assert from "node:assert/strict";
import { deflateRawSync, inflateRawSync } from "node:zlib";
import { spawnSync } from "node:child_process";
import { mkdir, mkdtemp, readFile, readdir, realpath, rename, rm, writeFile } from "node:fs/promises";
import { createRequire } from "node:module";
import { tmpdir } from "node:os";
import { basename, dirname, join, relative, resolve, sep } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { isDeepStrictEqual } from "node:util";
import { Script } from "node:vm";

import {
  assertReplacementSafe,
  MAX_INLINE_FRAGMENT_BYTES,
  normalizeInlineChartInput,
} from "../../skills/visualize-data/scripts/inline-chart-input.mjs";
import {
  assembleInlineFragment,
  loadInlineTheme,
} from "../../skills/visualize-data/scripts/render-inline-chart.mjs";
import { makeReplacementSafe } from "../../skills/visualize-data/scripts/replacement-safe-javascript.mjs";
import { normalizeInlineSourcesInput } from "../../skills/visualize-data/scripts/inline-sources-input.mjs";
import {
  API_VERSION,
  ARTIFACT_PATHS,
  INLINE_CANONICAL_MODULES,
  RECEIPT_CANONICAL_MODULES,
  PLUGIN_ROOT,
  RUNTIME_MODULE_SPECIFIERS,
  isInside,
  jsonBytes,
  makeManifest,
  readRegularFile,
  readSourceState,
  sha256,
  validateRuntimeModuleExports,
  verifyAssets,
} from "./manifest.mjs";
import { validateReleaseLock } from "./release-lock.mjs";
import { inlineChartFamilies, inlineFamilyArtifacts } from "../../templates/data-app/inline/chart-families.mjs";

const DEFAULT_OUTPUT = join(PLUGIN_ROOT, "assets/data-app-runtime");
const POSIX = (value) => value.split(sep).join("/");
const LICENSE_FILE = /^(?:licen[cs]e|copying|copyright|notice)(?:[._-].*)?$/iu;
// Inline charts, Sources receipts, and their shared controls keep the canonical
// Icon component, but cannot reach the remaining full-app icon assets.
export const INLINE_ICON_NAMES = Object.freeze([
  "arrowUpRight", "check", "chevronDown", "chevronLeft", "chevronRight", "copy",
  "cross", "database", "edit", "info", "link", "monitor", "more", "plus", "search", "undo",
]);
const INLINE_ICON_GLOB = `import.meta.glob("./icons/dashboard-icon-*.svg", {
  eager: true,
  import: "default",
  query: "?url",
})`;

// Charts retain their shared editor; receipts do not mount it. Neither target
// mounts the app shell or canvas. Prune only CSS families unreachable by each target.
export function inlineChartStyles(code, transformCss, { editor = false } = {}) {
  const appOnly = /^(?:typeahead(?:-|$)|filter-typeahead|filters$|comparison$|date-preset|block-resize|chart-pinned|notes$|dialog$|dashboard-(?:topbar|tabs|tab-|header-|schedule-|publish-|ask-|edit-|convert-|freshness-|save-|refresh-|verification|toast|chrome-)|topbar-mode-|theme-(?:drawer|card|preview|appearance)|chart-export-|chart-editor-|chart-explorer|explorer-|sortable-|block-drag-|data-(?:metric-|section|app-format-)|component-(?:loading-|skeleton|data-state|section-filter)|markdown-|report-|rich-|notes-|task-|history-|freshness-|date-calendar|date-range|metric-|dialog-|text-editor|editor-|filter-bar|filter-control|filter-chip|scenario-|showcase|smooth-card-surface|block-(?:add|menu)|dashboard-(?:root|shell|main|workspace|exploration-context))/u;
  const unused = new Set();
  const editorClass = /^(?:chart-editor-|chart-explorer|explorer-|dialog$|dialog-|editor-|history-)/u;
  const appStylesheets = new Set([
    "./components/executive-summary.css", "./components/segmented-control.css",
    "./components/slider.css", "./components/switch.css", "./components/section-navigator.css",
    "./components/chart-export.css", "./components/publish-review.css", "./components/data-app-loading.css",
  ]);
  if (editor) {
    appStylesheets.delete("./components/segmented-control.css");
    appStylesheets.delete("./components/switch.css");
  }
  const input = { filename: "styles.css", code: Buffer.from(code) };
  transformCss({ ...input, visitor: { Selector(parts) {
    walkAst(parts, part => {
      if (part.type === "class" && appOnly.test(part.name) && !(editor && editorClass.test(part.name))) unused.add(part.name);
    });
  } } });
  return transformCss({ ...input, minify: true, unusedSymbols: [...unused], visitor: {
    Rule: { import(rule) { if (appStylesheets.has(rule.value.url)) return []; } },
  } }).code.toString();
}

export function inlineIconAssetsPlugin(base) {
  const canonicalIcon = POSIX(join(base, "src/components/Icon.jsx"));
  return {
    name: "data-inline-icon-assets",
    enforce: "pre",
    transform(code, id) {
      if (POSIX(id).split("?")[0] !== canonicalIcon) return null;
      assert.equal(code.split(INLINE_ICON_GLOB).length, 2,
        "Review the changed canonical Icon glob before rebuilding the inline icon inventory");
      return {
        code: code.replace(INLINE_ICON_GLOB, INLINE_ICON_GLOB.replace(
          '"./icons/dashboard-icon-*.svg"',
          JSON.stringify(INLINE_ICON_NAMES.map((name) => `./icons/dashboard-icon-${name}.svg`)),
        )),
        map: null,
      };
    },
  };
}

export function assertInlineIconInventory(chunk) {
  const names = normalizedModules(chunk).flatMap((name) => {
    const match = name.match(/\/src\/components\/icons\/dashboard-icon-([^/]+)\.svg$/u);
    return match ? [match[1]] : [];
  });
  assert.deepEqual([...new Set(names)].sort(), [...INLINE_ICON_NAMES].sort(),
    "Inline runtime must contain exactly its reviewed reachable icon assets");
}

export function inlineCapacityInput(rowCount) {
  return {
    schemaVersion: 1,
    id: "inline-capacity",
    title: "Daily active users by plan",
    chart: { type: "line", x: "date", y: "activeUsers", series: "plan", showXAxisLabel: false },
    rows: Array.from({ length: rowCount }, (_, index) => ({
      date: new Date(Date.UTC(2026, 0, 1 + Math.floor(index / 2))).toISOString().slice(0, 10),
      plan: index % 2 ? "Team" : "Pro",
      activeUsers: 10_000 + index * 17,
    })),
    source: {
      label: "Illustrative release-capacity fixture",
      files: [{ label: "Synthetic daily plan observations" }],
      metricDefinitions: [
        { label: "Active users", field: "activeUsers", definition: "Illustrative daily active-user count by plan." },
        { label: "Date", field: "date", definition: "UTC observation date." },
        { label: "Plan", field: "plan", definition: "Mutually exclusive illustrative subscription plan." },
      ],
      caveats: ["Synthetic capacity check; no external source was queried."],
    },
    theme: "codex-classic",
  };
}

export async function assertInlineFragmentCapacity(runtimeCode, { pluginRoot = PLUGIN_ROOT, rowCounts = [100, 200], family } = {}) {
  const [template, theme] = await Promise.all([
    readRegularFile(pluginRoot, "skills/visualize-data/assets/inline-chart-fragment.html"),
    loadInlineTheme("codex-classic", { pluginRoot }),
  ]);
  return rowCounts.map((rowCount) => {
    const input = inlineCapacityInput(rowCount);
    if (family === "cartesian") input.chart.type = "bar";
    if (family === "categorical") input.chart.type = "heatmap";
    if (family === "flow") input.chart = { type: "sankey", y: "activeUsers", stages: ["date", "plan"] };
    const normalized = normalizeInlineChartInput(input);
    const { bytes } = assembleInlineFragment({ normalized, theme, runtimeCode, template: template.toString("utf8") });
    return { rowCount, bytes };
  });
}

export async function assertReceiptFragmentCapacity(runtimeCode, { pluginRoot = PLUGIN_ROOT } = {}) {
  const [template, example, theme] = await Promise.all([
    readRegularFile(pluginRoot, "skills/visualize-data/assets/inline-sources-fragment.html"),
    readRegularFile(pluginRoot, "skills/visualize-data/assets/inline-sources-example.json"),
    loadInlineTheme("codex-classic", { pluginRoot }),
  ]);
  const input = JSON.parse(example);
  const query = input.items[0].queries[0];
  query.rows = Array.from({ length: 2_000 }, (_, index) => ({ week: "2026-08-03", activated: index, eligible: 2_000 }));
  return assembleInlineFragment({ normalized: normalizeInlineSourcesInput(input), theme, runtimeCode, template: template.toString("utf8") }).bytes;
}

// Compact targets omit app chrome; only charts retain editor controls. Keep all
// chart, annotation, source-inspector, and theme styles from the canonical sheet.
const INLINE_UNUSED_CSS = [
  "data-app-format-toolbar", "data-app-format-button", "data-app-format-style",
  "data-app-format-link", "data-app-format-menu", "data-app-format-heading-1", "data-app-format-shortcut",
  "dashboard-topbar", "dashboard-topbar-build-status", "dashboard-build-status-spin",
  "dashboard-tabs-collapse", "dashboard-tabs-collapse-inner", "dashboard-tabs-row",
  "dashboard-tabs-inner", "dashboard-tabs", "dashboard-tab", "dashboard-tab-item", "dashboard-tab-label",
  "dashboard-tab-drag-preview", "dashboard-ask-anchor", "dashboard-ask-panel", "dashboard-ask-view",
  "dashboard-ask-menu", "dashboard-ask-shared-prompt", "dashboard-ask-menu-prompt", "dashboard-ask-compose",
  "dashboard-ask-zero-state", "dashboard-ask-zero-state-copy", "dashboard-ask-discard", "dashboard-ask-submit",
  "dashboard-ask-submit-label", "dashboard-ask-primary", "dashboard-ask-selected-region",
  "dashboard-ask-selected-mark", "dashboard-ask-button", "dashboard-ask-trigger-morphing", "explorer-controls",
  // These closing animations belong to the app-only Ask composer, never an inline chart.
  "dashboard-ask-header-return-anchor", "dashboard-ask-header-unmorph",
  "publish-review-dialog", "publish-review-body", "publish-review-section", "publish-review-audience",
  "publish-review-option", "publish-review-option-detail", "publish-review-existing",
  "publish-review-permissions", "publish-review-facts",
  "publish-review-footer", "dashboard-publish-confirm",
  "data-app-handoff-dialog", "data-app-handoff-backdrop", "data-app-handoff-question", "data-app-handoff-choices",
  "data-app-handoff-remember", "data-app-handoff-footer",
  "topbar-mode-switcher", "topbar-mode-indicator", "topbar-mode-tooltip",
  "chart-editor-backdrop", "chart-editor-dialog", "chart-editor-history", "chart-editor-icon",
  "chart-editor-redo-icon", "chart-editor-save", "chart-editor-cancel", "chart-editor-reset",
  "sortable-region", "sortable-row-header", "sortable-item", "sortable-region--canvas", "sortable-canvas-row",
  "sortable-canvas-row--empty", "sortable-row-insertion-zone", "sortable-row-insertion-zone--last",
  "block-resize-boundary", "sortable-announcement",
];

function walkAst(value, visit) {
  if (!value || typeof value !== "object") return;
  if (typeof value.type === "string") visit(value);
  for (const child of Object.values(value)) {
    if (Array.isArray(child)) child.forEach((item) => walkAst(item, visit));
    else if (child && typeof child === "object") walkAst(child, visit);
  }
}

export function assertNoExternalImports(code, parse, sourceType, name) {
  const ast = parse(code, { sourceType, ecmaVersion: "latest" });
  walkAst(ast, (node) => {
    if (
      node.type === "ImportDeclaration" ||
      node.type === "ImportExpression" ||
      ((node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") && node.source) ||
      (node.type === "CallExpression" && node.callee?.type === "Identifier" && node.callee.name === "require")
    )
      throw new Error(`${name} contains an external module reference.`);
  });
  return ast;
}

export function singleChunk(result, name) {
  const output = (Array.isArray(result) ? result : [result]).flatMap((item) => item.output ?? []);
  const chunks = output.filter((item) => item.type === "chunk");
  assert.equal(chunks.length, 1, `${name} must be exactly one JavaScript chunk`);
  assert.equal(output.filter((item) => item.type === "asset").length, 0, `${name} must not need external assets`);
  assert.deepEqual(chunks[0].imports, [], `${name} has external imports`);
  assert.deepEqual(chunks[0].dynamicImports, [], `${name} has dynamic imports`);
  return chunks[0];
}

function normalizedModules(chunk) {
  return Object.entries(chunk.modules ?? {})
    .filter(([, value]) => value.renderedLength !== 0)
    .map(([name]) => name.replaceAll("\\", "/").replace(/^\0/u, "").split("?")[0]);
}

export function assertDataFreeChunk(chunk, name, { inline = false, receipt = false } = {}) {
  const modules = normalizedModules(chunk);
  assert.ok(
    !modules.some((file) => /\/src\/(?:data\.json|content\/)/u.test(file)),
    `${name} embeds authored data or content`,
  );
  if (inline || receipt) {
    assert.ok(
      !modules.some((file) => /\/src\/(?:DataAppShell\.jsx|DataAppRuntime\.jsx|theme-runtime\.js)/u.test(file)),
      "Inline runtime embeds the full Data app or global theme runtime",
    );
    assert.ok(
      !modules.some((file) => /\/src\/components\/(?:DataAppChrome|DashboardTabs|RichMarkdown|RichTextFormatToolbar|PublishReviewDialog)\.jsx$/u.test(file)),
      "Inline CSS pruning requires unreachable app chrome",
    );
    if (receipt) assert.ok(
      !modules.some((file) => /\/src\/components\/(?:ChartEditor|ChartExplorer)\.jsx$/u.test(file)),
      "Receipt CSS pruning requires unreachable chart editor controls",
    );
    const ask = Object.entries(chunk.modules ?? {})
      .find(([file]) => file.replaceAll("\\", "/").endsWith("/src/components/DashboardAsk.jsx"))?.[1];
    assert.ok(!ask?.renderedLength || (Array.isArray(ask.renderedExports)
      && ask.renderedExports.every((name) => name === "useDashboardAsk")),
    "Inline Ask CSS pruning requires only the inert context hook");
    const sortable = Object.entries(chunk.modules ?? {})
      .find(([file]) => file.replaceAll("\\", "/").endsWith("/src/components/SortableRegion.jsx"))?.[1];
    assert.ok(!sortable?.renderedLength || (Array.isArray(sortable.renderedExports)
      && sortable.renderedExports.every((name) => name === "useOptionalSortableBlock")),
    "Inline layout CSS pruning requires unreachable sortable controls");
    for (const name of receipt ? RECEIPT_CANONICAL_MODULES : INLINE_CANONICAL_MODULES) {
      assert.ok(
        Object.keys(chunk.modules).some((file) => file.replaceAll("\\", "/").endsWith(`/${name}`)),
        `Inline runtime is missing its canonical module: ${name}`,
      );
    }
  }
}

/** Inspect only publisher-built, data-free code; customers consume the verified inventory. */
export function captureAppMetadata(code) {
  const context = {
    document: {
      createElement() {
        return {};
      },
    },
  };
  new Script(code, { filename: "app.js" }).runInNewContext(context, { timeout: 10_000 });
  const runtime = context.CodexDataAppRuntime;
  assert.equal(runtime?.apiVersion, API_VERSION, "App runtime has the wrong browser API version");
  assert.equal(typeof runtime.mount, "function", "App runtime does not expose mount");
  assert.ok(
    runtime.modules && typeof runtime.modules === "object" && Object.isFrozen(runtime.modules),
    "App runtime must expose a frozen module registry",
  );
  assert.deepEqual(
    Object.getOwnPropertyNames(runtime.modules).sort(),
    RUNTIME_MODULE_SPECIFIERS,
    "App runtime exposes unexpected module specifiers",
  );
  const moduleExports = Object.fromEntries(
    RUNTIME_MODULE_SPECIFIERS.map((specifier) => {
      const module = runtime.modules[specifier];
      assert.ok(
        module && ["object", "function"].includes(typeof module) && Object.isFrozen(module),
        `App runtime module must be a frozen namespace: ${specifier}`,
      );
      return [specifier, Object.getOwnPropertyNames(module).sort()];
    }),
  );
  return { moduleExports: validateRuntimeModuleExports(moduleExports) };
}

async function releaseMetadata(pluginRoot) {
  const readJson = async (name) => JSON.parse(await readRegularFile(pluginRoot, name));
  const [sourcePackage, sourceLock, packageJson, lock] = await Promise.all([
    readJson("templates/data-app/base/package.json"),
    readJson("templates/data-app/base/package-lock.json"),
    readJson("scripts/prebuilt/package.json"),
    readJson("scripts/prebuilt/package-lock.json"),
  ]);
  validateReleaseLock(sourcePackage, sourceLock, packageJson, lock);
  return { sourcePackage, sourceLock, packageJson, lock };
}

async function loadReleaseTools(dependencies, pluginRoot) {
  dependencies = await realpath(resolve(dependencies));
  const metadata = await releaseMetadata(pluginRoot);
  for (const filename of ["package.json", "package-lock.json"]) {
    assert.deepEqual(
      await readFile(join(dependencies, filename)),
      await readRegularFile(pluginRoot, `scripts/prebuilt/${filename}`),
      `Publisher workspace has a different frozen ${filename}`,
    );
  }
  const require = createRequire(join(dependencies, "package.json"));
  const installedLock = JSON.parse(await readFile(join(dependencies, "node_modules/.package-lock.json"), "utf8"));
  for (const [name, expected] of Object.entries(metadata.packageJson.dependencies)) {
    const installed = JSON.parse(await readFile(join(dependencies, "node_modules", name, "package.json"), "utf8"));
    assert.equal(installed.version, expected, `Publisher dependency drift: ${name}`);
    assert.equal(
      installedLock.packages?.[`node_modules/${name}`]?.integrity,
      metadata.lock.packages[`node_modules/${name}`].integrity,
      `Publisher dependency integrity drift: ${name}`,
    );
  }
  const { rolldown } = await import(pathToFileURL(require.resolve("rolldown")).href);
  return { dependencies, pluginRoot, require, rolldown, installedLock, ...metadata };
}

async function prepareReleaseWorkspace(pluginRoot, { offline = false } = {}) {
  const directory = await mkdtemp(join(tmpdir(), "data-prebuilt-release-"));
  try {
    for (const filename of ["package.json", "package-lock.json"]) {
      await writeFile(join(directory, filename), await readRegularFile(pluginRoot, `scripts/prebuilt/${filename}`));
    }
    const npm = process.platform === "win32" ? "npm.cmd" : "npm";
    const result = spawnSync(
      npm,
      [
        "ci",
        "--ignore-scripts",
        "--no-audit",
        "--no-fund",
        "--include=dev",
        "--include=optional",
        "--install-strategy=hoisted",
        "--workspaces=false",
        ...(offline ? ["--offline"] : []),
      ],
      { cwd: directory, stdio: "inherit", shell: process.platform === "win32" },
    );
    if (result.error) throw result.error;
    if (result.status !== 0) throw new Error(`Release-only npm ci failed (${result.status}).`);
    return directory;
  } catch (error) {
    await rm(directory, { recursive: true, force: true });
    throw error;
  }
}

async function rollupChunk(tools, input, output) {
  const bundle = await tools.rolldown({
    input,
    platform: "neutral",
    resolve: { mainFields: ["module", "main"] },
    external: () => false,
    treeshake: true,
    onwarn(warning) {
      if (warning.code === "UNRESOLVED_IMPORT") throw new Error(warning.message);
    },
  });
  try {
    return singleChunk(
      await bundle.generate({ codeSplitting: false, comments: { legal: true }, ...output }),
      basename(input),
    );
  } finally {
    await bundle.close();
  }
}

export function loadStandaloneCompiler(code) {
  const module = { exports: {} };
  const deniedRequire = (name) => {
    throw new Error(`Standalone compiler tried to load ${name}.`);
  };
  const factory = new Script(`(function(module,exports,require){\n${code}\n})`, {
    filename: "compiler.cjs",
  }).runInThisContext();
  factory(module, module.exports, deniedRequire);
  const compiler = module.exports;
  assert.equal(compiler.apiVersion, API_VERSION);
  for (const name of [
    "rollup",
    "transform",
    "parseJavaScript",
    "parseCss",
    "walkCss",
    "generateCss",
    "decodeCssIdentifier",
  ]) {
    assert.equal(typeof compiler[name], "function", `Compiler is missing ${name}`);
  }
  const transformed = compiler.transform("export const view = <span>{value as number}</span>;", {
    filePath: "proof.tsx",
  });
  new Script(`(function(module,exports,require){${transformed}\n})`);
  compiler.parseJavaScript(compiler.transform("export const view = <span />;", { commonjs: false }));
  const css = compiler.parseCss(":root{--color:var(--other,#fff)}");
  assert.match(compiler.generateCss(css), /--color/u);
  assert.equal(compiler.decodeCssIdentifier("u\\72 l"), "url");
  assertNoExternalImports(code, compiler.parseJavaScript, "script", "compiler.cjs");
  return compiler;
}

async function assertStandaloneLinker(compiler) {
  const sources = {
    "\0entry": "export { value, bump } from 'counter';",
    counter: "export let value = 1; export function bump(){ value += 1; }",
  };
  const bundle = await compiler.rollup({
    input: "\0entry",
    plugins: [
      {
        name: "closed-release-smoke",
        resolveId(id) {
          if (!Object.hasOwn(sources, id)) throw new Error(`Standalone linker attempted to load ${id}.`);
          return id;
        },
        load(id) {
          return sources[id];
        },
      },
    ],
  });
  try {
    const chunk = singleChunk(
      await bundle.generate({ format: "iife", name: "ReleaseProof", exports: "named" }),
      "standalone linker",
    );
    assertNoExternalImports(chunk.code, compiler.parseJavaScript, "script", "standalone linker output");
    const context = {};
    new Script(chunk.code).runInNewContext(context);
    assert.equal(context.ReleaseProof.value, 1);
    context.ReleaseProof.bump();
    assert.equal(context.ReleaseProof.value, 2);
  } finally {
    await bundle.close();
  }
}

async function buildCompiler(tools, snapshotRoot) {
  const chunk = await rollupChunk(tools, join(snapshotRoot, "scripts/prebuilt/compiler-entry.mjs"), {
    format: "cjs",
    minify: true,
  });
  const compiler = loadStandaloneCompiler(chunk.code);
  await assertStandaloneLinker(compiler);
  return { code: chunk.code, chunk, compiler };
}

async function buildBrowserRuntime(tools, snapshotRoot, { inline = false, receipt = false, family } = {}) {
  const { build } = await import(pathToFileURL(tools.require.resolve("vite")).href);
  const base = join(snapshotRoot, "templates/data-app/base");
  const compact = inline || receipt;
  const entry = receipt ? join(snapshotRoot, "templates/data-app/inline/sources.jsx") : inline
    ? join(snapshotRoot, "templates/data-app/inline/index.jsx")
    : join(base, "src/prebuilt-runtime-entry.jsx");
  const name = receipt ? "CodexDataSourcesReceipt" : inline ? "CodexDataInlineChart" : "CodexDataAppRuntime";
  const unusedSymbols = inline
    ? INLINE_UNUSED_CSS.filter(name => name !== "explorer-controls" && !name.startsWith("chart-editor-"))
    : INLINE_UNUSED_CSS;
  const result = await build({
    root: base,
    configFile: false,
    cacheDir: join(snapshotRoot, ".vite"),
    logLevel: "silent",
    plugins: compact ? [inlineIconAssetsPlugin(base), ...(inline ? [{
      name: "data-inline-compressed-styles", enforce: "post",
      transform(code, id) {
        const resource = POSIX(id);
        const stylesheet = resource === `${POSIX(join(base, "src/styles.css"))}?inline`
          || resource === `${POSIX(join(snapshotRoot, "templates/data-app/inline/inline.css"))}?inline`;
        const icon = resource.startsWith(`${POSIX(join(base, "src/components/icons"))}/dashboard-icon-`) && resource.endsWith(".svg?url");
        if (!stylesheet && !icon) return null;
        const ast = tools.require("acorn").parse(code, { ecmaVersion: "latest", sourceType: "module" });
        const declaration = ast.body.find(node => node.type === "ExportDefaultDeclaration")?.declaration;
        assert.equal(declaration?.type, "Literal", "Inline stylesheet must remain a literal CSS module");
        assert.equal(typeof declaration.value, "string");
        const compressed = deflateRawSync(Buffer.from(declaration.value), { level: 9 });
        assert.equal(inflateRawSync(compressed).toString(), declaration.value, "Inline CSS compression must be lossless");
        return { code: `import { decodeBundledResource } from ${JSON.stringify(join(snapshotRoot, "templates/data-app/inline/resources.js"))}; export default decodeBundledResource(${JSON.stringify(compressed.toString("base64"))});`, map: null };
      },
    }] : []), {
      name: "data-inline-styles", enforce: "pre",
      transform(code, id) {
        if (["styles.css", "styles-foundation.css"].some((file) => POSIX(id).split("?")[0] === POSIX(join(base, `src/${file}`))))
          return { code: inlineChartStyles(code, tools.require("lightningcss").transform, { editor: inline }), map: null };
        return null;
      },
    }] : [],
    ...(compact ? { css: { lightningcss: { unusedSymbols } } } : {}),
    define: { "process.env.NODE_ENV": JSON.stringify("production"), __DATA_APP_PROJECT_ROOT__: JSON.stringify(""),
      __DATA_SOURCE_RECEIPTS__: JSON.stringify(!inline),
      __DATA_INLINE_CHART__: JSON.stringify(inline),
      ...(family ? { __DATA_INLINE_CHART_FAMILY__: JSON.stringify(family) } : {}) },
    resolve: {
      dedupe: ["react", "react-dom"],
      alias: [
        { find: /^react$/u, replacement: tools.require.resolve("react") },
        { find: /^react\/jsx-runtime$/u, replacement: tools.require.resolve("react/jsx-runtime") },
        { find: /^react\/jsx-dev-runtime$/u, replacement: tools.require.resolve("react/jsx-dev-runtime") },
        { find: /^react-dom$/u, replacement: tools.require.resolve("react-dom") },
        { find: /^react-dom\/client$/u, replacement: tools.require.resolve("react-dom/client") },
      ],
    },
    build: {
      write: false,
      target: "chrome120",
      minify: true,
      cssMinify: "lightningcss",
      assetsInlineLimit: Number.MAX_SAFE_INTEGER,
      lib: { entry, name, formats: ["iife"], fileName: () => (receipt ? "receipt.js" : inline ? "inline.js" : "app.js") },
    },
  });
  const chunk = singleChunk(result, name);
  assertDataFreeChunk(chunk, name, { inline, receipt });
  if (compact) assertInlineIconInventory(chunk);
  return chunk;
}

async function buildWorker(tools, snapshotRoot, compiler) {
  const chunk = await rollupChunk(tools, join(snapshotRoot, "templates/data-app/base/src/data-app-worker.js"), {
    format: "es",
    minify: { compress: false, mangle: false, codegen: true },
  });
  assertDataFreeChunk(chunk, "worker.mjs");
  const ast = assertNoExternalImports(chunk.code, compiler.parseJavaScript, "module", "worker.mjs");
  assert.ok(
    !ast.body.some((node) => node.type === "ExportDefaultDeclaration"),
    "Worker factory must not have a default export",
  );
  assert.ok(
    ast.body.some((node) => {
      const declaration = node.type === "ExportNamedDeclaration" ? node.declaration : node;
      return declaration?.type === "FunctionDeclaration" && declaration.id?.name === "createDataAppWorker";
    }),
    "Worker factory must preserve the local createDataAppWorker binding",
  );
  const config = JSON.stringify({
    html: "<main>offline worker proof</main>",
    seedSnapshot: {},
    initialPresentation: {},
  });
  const combined = `${chunk.code}\nexport default createDataAppWorker(${config});\n`;
  const module = await import(`data:text/javascript;base64,${Buffer.from(combined).toString("base64")}`);
  assert.equal(typeof module.createDataAppWorker, "function");
  assert.equal(typeof module.validatePresentation, "function");
  assert.equal(
    await (await module.default.fetch(new Request("https://example.test/"), {})).text(),
    "<main>offline worker proof</main>",
  );
  return chunk;
}

async function minifyProtectedCss(tools, snapshotRoot, ...names) {
  const { bundleAsync, transform } = tools.require("lightningcss");
  const sourceRoot = join(snapshotRoot, "templates/data-app/base/src");
  const entry = join(sourceRoot, ".prebuilt-styles.css");
  const input = (await Promise.all(names.map(name => readFile(join(sourceRoot, name), "utf8")))).join("\n");
  const bundled = await bundleAsync({
    filename: entry, minify: true, errorRecovery: false, targets: { chrome: 120 << 16 },
    resolver: {
      read: async file => file === entry ? input : (await readRegularFile(sourceRoot, POSIX(relative(sourceRoot, file)))).toString("utf8"),
      resolve(specifier, from) {
        const file = resolve(dirname(from), specifier);
        assert.ok(specifier.startsWith(".") && isInside(sourceRoot, file) && file.endsWith(".css"),
          "Protected CSS imports must stay inside the canonical source tree");
        return file;
      },
    },
  });
  const result = transform({ filename: names[0], code: bundled.code, minify: true,
    errorRecovery: false, analyzeDependencies: true, targets: { chrome: 120 << 16 } });
  assert.deepEqual(result.dependencies, [], `${names.join(", ")} must not fetch external resources`);
  return result.code.toString();
}

async function packageLicenseFiles(directory) {
  const files = [];
  async function visit(prefix = "") {
    const entries = await readdir(join(directory, prefix), { withFileTypes: true });
    for (const entry of entries) {
      const name = prefix ? `${prefix}/${entry.name}` : entry.name;
      if (entry.isSymbolicLink()) throw new Error(`Distributed package contains a symlink: ${name}`);
      if (entry.isDirectory() && entry.name !== "node_modules") await visit(name);
      else if (entry.isFile() && LICENSE_FILE.test(entry.name)) files.push(name);
    }
  }
  await visit();
  return files.sort();
}

export async function collectThirdPartyNotices(chunks, tools) {
  const dependencies = await realpath(tools.dependencies);
  const pluginRoot = tools.pluginRoot ?? PLUGIN_ROOT;
  const overrides = JSON.parse(await readRegularFile(pluginRoot, "scripts/prebuilt/license-overrides.json"));
  const packagePaths = new Set();
  for (const chunk of chunks) {
    for (const modulePath of normalizedModules(chunk)) {
      if (!modulePath.includes("/node_modules/")) continue;
      const match = /^(.*\/node_modules\/(?:@[^/]+\/)?[^/]+)(?:\/|$)/u.exec(modulePath);
      if (!match) throw new Error(`Cannot identify distributed dependency: ${modulePath}`);
      const packageRoot = await realpath(match[1]);
      if (!isInside(join(dependencies, "node_modules"), packageRoot)) {
        throw new Error(`Release build loaded a dependency outside its frozen workspace: ${modulePath}`);
      }
      packagePaths.add(POSIX(relative(dependencies, packageRoot)));
    }
  }
  const notices = [
    "Data app prebuilt runtime — third-party notices",
    "",
    "These packages contribute code to the distributed runtime or local compiler.",
    "",
  ];
  const packages = [];
  for (const packagePath of [...packagePaths].sort()) {
    const directory = join(dependencies, packagePath);
    const manifest = JSON.parse(await readFile(join(directory, "package.json"), "utf8"));
    const locked = tools.lock.packages[packagePath];
    if (
      !locked?.integrity ||
      locked.version !== manifest.version ||
      tools.installedLock.packages?.[packagePath]?.integrity !== locked.integrity
    ) {
      throw new Error(`Distributed dependency differs from the frozen lock: ${packagePath}`);
    }
    const files = await packageLicenseFiles(directory);
    const override = overrides[`${manifest.name}@${manifest.version}`];
    let extraLicense;
    if (override) {
      if (
        override.packageIntegrity !== locked.integrity ||
        !override.path?.startsWith("licenses/") ||
        !/^https:\/\/raw\.githubusercontent\.com\/[^/]+\/[^/]+\/[a-f\d]{40}\//u.test(override.source ?? "")
      )
        throw new Error(`Invalid pinned upstream license for ${manifest.name}@${manifest.version}`);
      extraLicense = await readRegularFile(pluginRoot, `scripts/prebuilt/${override.path}`);
      if (sha256(extraLicense) !== override.sha256)
        throw new Error(`Pinned upstream license changed: ${override.path}`);
    }
    if (!files.length && !extraLicense)
      throw new Error(`Distributed dependency lacks a license/notice file: ${manifest.name}@${manifest.version}`);
    notices.push(
      "=".repeat(72),
      `${manifest.name}@${manifest.version}`,
      `License: ${
        typeof manifest.license === "string" ? manifest.license : JSON.stringify(manifest.license ?? "see below")
      }`,
    );
    for (const filename of files)
      notices.push("", `--- ${filename} ---`, (await readFile(join(directory, filename), "utf8")).trimEnd());
    if (extraLicense)
      notices.push("", `--- Upstream license: ${override.source} ---`, extraLicense.toString("utf8").trimEnd());
    notices.push("");
    packages.push({
      name: manifest.name,
      version: manifest.version,
      integrity: locked.integrity,
      licenseFiles: [...files, ...(extraLicense ? [`upstream:${override.path}`] : [])],
    });
  }
  return { text: `${notices.join("\n")}\n`, packages };
}

async function copySnapshot(state, destination) {
  for (const [name, bytes] of state.files) {
    const target = join(destination, name);
    await mkdir(dirname(target), { recursive: true });
    await writeFile(target, bytes);
  }
}

async function writeArtifacts(outputDir, artifacts, manifest) {
  await mkdir(outputDir, { recursive: true });
  const staging = await mkdtemp(join(outputDir, ".build-"));
  try {
    for (const [name, filename] of Object.entries(ARTIFACT_PATHS))
      await writeFile(join(staging, filename), artifacts[name]);
    await writeFile(join(staging, "manifest.json"), jsonBytes(manifest));
    for (const filename of [...Object.values(ARTIFACT_PATHS), "manifest.json"])
      await rename(join(staging, filename), join(outputDir, filename));
  } finally {
    await rm(staging, { recursive: true, force: true });
  }
}

export async function buildPrebuiltAssets({
  pluginRoot = PLUGIN_ROOT,
  dependencies,
  outputDir = DEFAULT_OUTPUT,
  compilerOnly = false,
  check = false,
  offline = false,
} = {}) {
  pluginRoot = resolve(pluginRoot);
  outputDir = resolve(outputDir);
  const createdDependencies = !dependencies;
  if (!dependencies) dependencies = await prepareReleaseWorkspace(pluginRoot, { offline });
  let scratch;
  try {
    const tools = await loadReleaseTools(dependencies, pluginRoot);
    scratch = await mkdtemp(join(tools.dependencies, ".data-prebuilt-"));
    const snapshotRoot = join(scratch, "plugin");
    if (compilerOnly) {
      const target = join(snapshotRoot, "scripts/prebuilt/compiler-entry.mjs");
      await mkdir(dirname(target), { recursive: true });
      await writeFile(target, await readRegularFile(pluginRoot, "scripts/prebuilt/compiler-entry.mjs"));
      const built = await buildCompiler(tools, snapshotRoot);
      await mkdir(outputDir, { recursive: true });
      const output = join(outputDir, ARTIFACT_PATHS.compiler);
      if (check)
        assert.deepEqual(await readFile(output), Buffer.from(built.code), "Standalone compiler rebuild differs");
      else await writeFile(output, built.code);
      return { compiler: { path: output, bytes: Buffer.byteLength(built.code), sha256: sha256(built.code) } };
    }
    const state = await readSourceState(pluginRoot);
    await copySnapshot(state, snapshotRoot);
    const builtCompiler = await buildCompiler(tools, snapshotRoot);
    const app = await buildBrowserRuntime(tools, snapshotRoot);
    const inline = await buildBrowserRuntime(tools, snapshotRoot, { inline: true });
    // A final publisher-only pass reduces raw inline bytes beyond the bundler's
    // minification. No extra compiler or dependency reaches customer artifacts.
    const { minify } = tools.require("terser");
    const minimizedInline = await minify(inline.code, {
      ecma: 2020, compress: { passes: 3 }, format: { comments: false },
    });
    assert.ok(minimizedInline.code, "Inline minification must produce JavaScript");
    const receipt = await buildBrowserRuntime(tools, snapshotRoot, { receipt: true });
    assertNoExternalImports(app.code, builtCompiler.compiler.parseJavaScript, "script", "app.js");
    const safeInline = makeReplacementSafe(minimizedInline.code, (code) =>
      builtCompiler.compiler.parseJavaScript(code, { sourceType: "script" }),
    );
    const inlineCode = safeInline.code.replace(/<\/script/giu, "<\\/script");
    new Script(inlineCode);
    assertReplacementSafe(inlineCode);
    assert.ok(Buffer.byteLength(inlineCode) < MAX_INLINE_FRAGMENT_BYTES,
      `Shared inline runtime exceeds 1 MB (${Buffer.byteLength(inlineCode)} bytes)`);
    assertNoExternalImports(inlineCode, builtCompiler.compiler.parseJavaScript, "script", "inline.js");
    const inlineCapacity = await assertInlineFragmentCapacity(inlineCode, { pluginRoot: snapshotRoot });
    const familyChunks = [], familyCodes = {}, inlineFamilyMetadata = {};
    for (const family of Object.keys(inlineChartFamilies)) {
      const name = inlineFamilyArtifacts[family];
      const chunk = await buildBrowserRuntime(tools, snapshotRoot, { inline: true, family });
      const minimized = await minify(chunk.code, {
        ecma: 2020, compress: { passes: 3 }, format: { comments: false },
      });
      assert.ok(minimized.code, `${name} minification must produce JavaScript`);
      const safe = makeReplacementSafe(minimized.code, code => builtCompiler.compiler.parseJavaScript(code, { sourceType: "script" }));
      const code = safe.code.replace(/<\/script/giu, "<\\/script");
      new Script(code);
      assertReplacementSafe(code);
      assertNoExternalImports(code, builtCompiler.compiler.parseJavaScript, "script", `${name}.js`);
      inlineCapacity.push(...(await assertInlineFragmentCapacity(code, {
        pluginRoot: snapshotRoot, rowCounts: [500], family,
      })).map(measurement => ({ family, ...measurement })));
      familyChunks.push(chunk);
      familyCodes[name] = code;
      inlineFamilyMetadata[name] = { canonicalModules: [...INLINE_CANONICAL_MODULES],
        externalImports: chunk.imports, dynamicImports: chunk.dynamicImports, encodedTokens: safe.encodedTokens };
    }
    const safeReceipt = makeReplacementSafe(receipt.code, (code) =>
      builtCompiler.compiler.parseJavaScript(code, { sourceType: "script" }));
    const receiptCode = safeReceipt.code.replace(/<\/script/giu, "<\\/script");
    new Script(receiptCode);
    assertReplacementSafe(receiptCode);
    assertNoExternalImports(receiptCode, builtCompiler.compiler.parseJavaScript, "script", "receipt.js");
    const receiptCapacity = await assertReceiptFragmentCapacity(receiptCode, { pluginRoot: snapshotRoot });
    const worker = await buildWorker(tools, snapshotRoot, builtCompiler.compiler);
    const notices = await collectThirdPartyNotices([app, inline, ...familyChunks, receipt, worker, builtCompiler.chunk], {
      ...tools,
      pluginRoot: snapshotRoot,
    });
    const artifacts = {
      app: app.code,
      styles: await minifyProtectedCss(tools, snapshotRoot, "styles.css", "theme-picker.css", "source-preview.css"),
      print: await minifyProtectedCss(tools, snapshotRoot, "print.css"),
      inline: inlineCode,
      ...familyCodes,
      receipt: receiptCode,
      worker: worker.code,
      compiler: builtCompiler.code,
      notices: notices.text,
    };
    const after = await readSourceState(pluginRoot);
    assert.ok(
      isDeepStrictEqual(after.buildInputs, state.buildInputs),
      "Prebuilt inputs changed during the release build; retry",
    );
    const manifest = makeManifest(state, artifacts, {
      appMetadata: captureAppMetadata(app.code),
      inlineFamilyMetadata,
      inlineMetadata: {
        canonicalModules: [...INLINE_CANONICAL_MODULES],
        externalImports: inline.imports,
        dynamicImports: inline.dynamicImports,
        encodedTokens: safeInline.encodedTokens,
      },
      receiptMetadata: {
        canonicalModules: [...RECEIPT_CANONICAL_MODULES],
        externalImports: receipt.imports,
        dynamicImports: receipt.dynamicImports,
        encodedTokens: safeReceipt.encodedTokens,
      },
    });
    if (check) {
      const current = await verifyAssets({ pluginRoot, assetDir: outputDir });
      assert.deepEqual(current, manifest, "Deterministic prebuilt rebuild differs from shipped assets");
    } else {
      await writeArtifacts(outputDir, artifacts, manifest);
      await verifyAssets({ pluginRoot, assetDir: outputDir });
    }
    return { manifest, distributedPackages: notices.packages, inlineEncodedTokens: safeInline.encodedTokens, inlineCapacity, receiptCapacity };
  } finally {
    if (scratch) await rm(scratch, { recursive: true, force: true });
    if (createdDependencies) await rm(dependencies, { recursive: true, force: true });
  }
}

function parseArgs(args) {
  const options = {};
  for (let index = 0; index < args.length; index++) {
    const flag = args[index];
    if (flag === "--compiler-only") options.compilerOnly = true;
    else if (flag === "--check") options.check = true;
    else if (flag === "--offline") options.offline = true;
    else if (["--dependencies", "--output-dir", "--plugin-root"].includes(flag)) {
      const value = args[++index];
      if (!value || value.startsWith("--")) throw new Error(`Missing value for ${flag}`);
      options[{ "--dependencies": "dependencies", "--output-dir": "outputDir", "--plugin-root": "pluginRoot" }[flag]] =
        value;
    } else throw new Error(`Unknown release-build option: ${flag}`);
  }
  return options;
}

if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
  const result = await buildPrebuiltAssets(parseArgs(process.argv.slice(2)));
  const summary = result.manifest
    ? {
        source: result.manifest.source,
        artifacts: result.manifest.artifacts,
        distributedPackageCount: result.distributedPackages.length,
        inlineEncodedTokens: result.inlineEncodedTokens,
        inlineCapacity: result.inlineCapacity,
      }
    : result;
  process.stdout.write(`${JSON.stringify(summary, null, 2)}\n`);
}

SHA-256: a96e1ff9f6726b65c1a0ab89436251ef8b5db4693a1e49ae6401a920be3c1145