view design_system/test/design_system_policy_test.js @ 279:b3b547563ec7

Add Google connector service and agent wiki Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code. Co-authored-by: Copilot <[email protected]> Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:22:36 -0700
parents 60a876c4587a
children
line wrap: on
line source

const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');

const RUNFILES = process.env.JS_BINARY__RUNFILES;
const WORKSPACE = process.env.JS_BINARY__WORKSPACE;
assert.ok(RUNFILES);
assert.ok(WORKSPACE);

const designRoot = path.join(RUNFILES, WORKSPACE, 'design_system');
const sourceRoot = path.join(designRoot, 'src');
const files = [];

function walk(directory) {
  for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
    const entryPath = path.join(directory, entry.name);
    if (entry.isDirectory()) walk(entryPath);
    else if (/\.(?:css|html|js)$/.test(entry.name)) files.push(entryPath);
  }
}

walk(sourceRoot);
function listMarkdown(directory) {
  const markdown = [];
  for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
    const entryPath = path.join(directory, entry.name);
    if (entry.isDirectory()) markdown.push(...listMarkdown(entryPath));
    else if (entry.name.endsWith('.md')) markdown.push(entryPath);
  }
  return markdown;
}
const documentationFiles = [
  ...fs.readdirSync(designRoot)
    .filter(name => name.endsWith('.md'))
    .map(name => path.join(designRoot, name)),
  ...listMarkdown(path.join(designRoot, 'wiki')),
];
const namingFiles = [
  ...files,
  ...documentationFiles,
  path.join(designRoot, 'main.c'),
];

function validateCallableDocumentation(
  relative,
  source,
  index,
  name,
  parameterSource,
  failures,
) {
  const prefix = source.slice(0, index);
  const comment = prefix.match(/\/\*\*([\s\S]*?)\*\/\s*$/);
  const body = comment?.[1] || '';
  const parameters = parameterSource
    .split(',')
    .map(parameter => parameter.trim()
      .replace(/^\.\.\./, '')
      .split('=')[0].trim())
    .filter(Boolean);
  if (!/@return\s+\{[^}]+\}/.test(body)) {
    failures.push(`${relative} exported callable ${name} lacks @return`);
  }
  const documented = [...body.matchAll(
    /@param\s+\{[^}]+\}\s+([A-Za-z0-9_$]+)/g,
  )].map(parameter => parameter[1]);
  for (const parameter of parameters) {
    if (!documented.includes(parameter)) {
      failures.push(
        `${relative} exported callable ${name} lacks @param for ${parameter}`,
      );
    }
  }
}

const rawColor = new RegExp([
  '#[0-9a-fA-F]{3,8}\\b',
  '\\b(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch)\\s*\\(',
].join('|'), 'gi');
const forbiddenGlyph = /[×←→↑↓+◆◇✓✔✕✖★☆⚠]/gu;
const pictographic = /\p{Extended_Pictographic}/gu;
const borrowedProductName =
  /(?:shadcn|storybook|sonner|radix|tailwind|react)/gi;
const failures = [];

for (const file of files) {
  const relative = path.relative(sourceRoot, file);
  const source = fs.readFileSync(file, 'utf8');

  if (![
    'styles/reference.css',
    'styles/tokens.css',
  ].includes(relative)) {
    for (const match of source.matchAll(rawColor)) {
      failures.push(
        `${relative}:${source.slice(0, match.index).split('\n').length} ` +
        `raw color ${JSON.stringify(match[0])}`,
      );
    }
    if (relative.endsWith('.css')) {
      const css = source.replace(/\/\*[\s\S]*?\*\//g, '');
      const allowedWords = new Set([
        'none',
        'transparent',
        'currentcolor',
        'inherit',
        'initial',
        'unset',
        'revert',
        'solid',
        'dashed',
        'dotted',
        'double',
        'groove',
        'ridge',
        'inset',
        'outset',
        'canvas',
        'canvastext',
        'linktext',
        'visitedtext',
        'activetext',
        'buttonface',
        'buttontext',
        'field',
        'fieldtext',
        'highlight',
        'highlighttext',
        'graytext',
        'mark',
        'marktext',
        'selecteditem',
        'selecteditemtext',
        'accentcolor',
        'accentcolortext',
        'color-mix',
        'in',
        'srgb',
        'linear-gradient',
        'radial-gradient',
        'conic-gradient',
        'to',
        'top',
        'right',
        'bottom',
        'left',
        'at',
        'circle',
        'ellipse',
        'px',
        'rem',
        'em',
        'vh',
        'vw',
        'vi',
        'vb',
        'vmin',
        'vmax',
        'deg',
        'rad',
        'turn',
      ]);
      for (const declaration of css.matchAll(
        /(^|[;{])\s*([-\w]+)\s*:\s*([^;{}]+)/gm,
      )) {
        const property = declaration[2].toLowerCase();
        const value = declaration[3];
        const colorProperty = [
          'accent-color',
          'background',
          'background-color',
          'box-shadow',
          'caret-color',
          'color',
          'fill',
          'outline',
          'outline-color',
          'scrollbar-color',
          'stroke',
          'text-shadow',
        ].includes(property) ||
          (property.startsWith('border') &&
           !/(?:collapse|image|radius|spacing|style|width)/.test(property));
        if (!colorProperty) continue;
        const withoutTokens = value.replace(
          /var\(\s*--(?:zenbu|zen)-[\w-]+\s*\)/g,
          '',
        );
        const words = withoutTokens.toLowerCase()
          .match(/[a-z][a-z-]*/g) || [];
        if (words.some(word => !allowedWords.has(word)) &&
            !/^\s*(?:0|none|transparent|currentColor|inherit)\s*$/i.test(
              value,
            )) {
          failures.push(
            `${relative}:${css.slice(0, declaration.index).split('\n').length} ` +
            `${property} must use a --zenbu-sys-* token`,
          );
        }
      }
    }
  }

  for (const pattern of [forbiddenGlyph, pictographic]) {
    for (const match of source.matchAll(pattern)) {
      failures.push(
        `${relative}:${source.slice(0, match.index).split('\n').length} ` +
        `icon glyph ${JSON.stringify(match[0])}; use <zen-icon>`,
      );
    }
  }
  if (relative !== 'components/icon.js' &&
      /<svg\b|createElementNS\([^)]*["']svg["']/i.test(source)) {
    failures.push(`${relative} defines SVG outside components/icon.js`);
  }
  if (relative.endsWith('.js')) {
    if (/\bimport\s*\/[/*]/.test(source)) {
      failures.push(`${relative} places comments inside import syntax`);
    }
    const importPattern =
      /(?:import\s+(?:[^'"]+\s+from\s+)?|export\s+[^'"]+\s+from\s+)["']([^"']+)["']/g;
    for (const match of source.matchAll(importPattern)) {
      if (!match[1].startsWith('.')) {
        failures.push(
          `${relative} imports external runtime ${JSON.stringify(match[1])}`,
        );
      }
    }
    if (/\bimport\s*\(/.test(source)) {
      failures.push(`${relative} uses forbidden dynamic import()`);
    }
  }
  if (relative.endsWith('.css') &&
      /@font-face|(?:font|font-family)\s*:[^;]*(?:icon|awesome|material)/i.test(
        source,
      )) {
    failures.push(`${relative} declares an icon font`);
  }
  if (relative.endsWith('.css')) {
    for (const match of source.matchAll(
      /@import\s+(?:url\(\s*)?["']?([^"')\s;]+)["']?\s*\)?/g,
    )) {
      if (!match[1].startsWith('.')) {
        failures.push(
          `${relative} imports external stylesheet ${JSON.stringify(match[1])}`,
        );
      }
    }
  }
}

const cssFiles = files.filter(file => file.endsWith('.css'));
const zenbuDeclarations = new Set();
for (const file of cssFiles) {
  const source = fs.readFileSync(file, 'utf8');
  for (const match of source.matchAll(/(--zenbu-[\w-]+)\s*:/g)) {
    zenbuDeclarations.add(match[1]);
  }
}
for (const file of cssFiles) {
  const relative = path.relative(sourceRoot, file);
  const source = fs.readFileSync(file, 'utf8');
  for (const match of source.matchAll(/var\(\s*(--zenbu-[\w-]+)/g)) {
    if (!zenbuDeclarations.has(match[1])) {
      failures.push(`${relative} references unknown token ${match[1]}`);
    }
  }
  if (![
    'styles/reference.css',
    'styles/semantic.css',
    'styles/themes.css',
    'styles/tokens.css',
  ].includes(relative)) {
    for (const match of source.matchAll(
      /var\(\s*(--zenbu-ref-color-[\w-]+)/g,
    )) {
      failures.push(
        `${relative} consumes reference color ${match[1]} directly`,
      );
    }
  }
  if (![
    'styles/themes.css',
    'styles/tokens.css',
  ].includes(relative) && /var\(\s*--zen-/.test(source)) {
    failures.push(`${relative} consumes deprecated --zen-* tokens`);
  }
}

for (const file of namingFiles) {
  const source = fs.readFileSync(file, 'utf8');
  for (const match of source.matchAll(borrowedProductName)) {
    failures.push(
      `${path.relative(designRoot, file)} uses borrowed product name ` +
      JSON.stringify(match[0]),
    );
  }
}

for (const file of files.filter(file =>
  file.endsWith('.js')
)) {
  const relative = path.relative(sourceRoot, file);
  const source = fs.readFileSync(file, 'utf8');
  const declaration =
    /^export\s+(?:default\s+)?(?:async\s+)?(class|const|let|var|function)\s+([A-Za-z0-9_]+)/gm;
  for (const match of source.matchAll(declaration)) {
    const prefix = source.slice(0, match.index);
    const comment = prefix.match(/\/\*\*([\s\S]*?)\*\/\s*$/);
    const line = prefix.split('\n').length;
    if (!comment) {
      failures.push(`${relative}:${line} ${match[2]} lacks Google-style JSDoc`);
      continue;
    }
    const body = comment[1];
    if (match[1] === 'class' && !/@extends\s+\{[^}]+\}/.test(body)) {
      failures.push(`${relative}:${line} ${match[2]} lacks @extends`);
    } else if (['const', 'let', 'var'].includes(match[1]) &&
               !/@(?:const|type)\b/.test(body)) {
      failures.push(`${relative}:${line} ${match[2]} lacks @const/@type`);
    } else if (match[1] === 'function' &&
               (!/@param\s+\{[^}]+\}/.test(body) ||
                !/@return\s+\{[^}]+\}/.test(body))) {
      failures.push(`${relative}:${line} ${match[2]} lacks @param/@return`);
    } else if (match[1] === 'function') {
      const signature = source.slice(match.index).match(
        /^export\s+(?:default\s+)?(?:async\s+)?function\s+[A-Za-z0-9_]+\s*\(([^)]*)\)/,
      );
      const parameters = (signature?.[1] || '')
        .split(',')
        .map(parameter => parameter.trim()
          .replace(/^\.\.\./, '')
          .split('=')[0].trim())
        .filter(Boolean);
      const documented = [...body.matchAll(
        /@param\s+\{[^}]+\}\s+([A-Za-z0-9_$]+)/g,
      )].map(parameter => parameter[1]);
      for (const parameter of parameters) {
        if (!documented.includes(parameter)) {
          failures.push(
            `${relative}:${line} ${match[2]} lacks @param for ${parameter}`,
          );
        }
      }
    }
  }
  for (const match of source.matchAll(
    /^export\s+const\s+([A-Za-z0-9_]+)\s*=\s*(?:async\s*)?(?:\(([^)]*)\)|([A-Za-z0-9_$]+))\s*=>/gm,
  )) {
    validateCallableDocumentation(
      relative,
      source,
      match.index,
      match[1],
      match[2] || match[3] || '',
      failures,
    );
  }
  for (const match of source.matchAll(
    /^export\s+const\s+([A-Za-z0-9_]+)\s*=\s*(?:async\s*)?function(?:\s+[A-Za-z0-9_]+)?\s*\(([^)]*)\)/gm,
  )) {
    validateCallableDocumentation(
      relative,
      source,
      match.index,
      match[1],
      match[2],
      failures,
    );
  }
  for (const match of source.matchAll(
    /export\s*\{[\s\S]*?\}\s*(?!from\b)(?:;|$)/g,
  )) {
    failures.push(
      `${relative}:${source.slice(0, match.index).split('\n').length} ` +
      "uses an undocumented local export list",
    );
  }
}

assert.deepEqual(
  failures,
  [],
  `Design-system policy violations:\n${failures.join('\n')}`,
);