init project

This commit is contained in:
root
2026-06-25 19:06:59 -04:00
parent c5dfee6efb
commit 5d017f533a
349 changed files with 31330 additions and 0 deletions
+97
View File
@@ -0,0 +1,97 @@
import { readFile, stat } from 'node:fs/promises';
import path from 'node:path';
import { fail, pass, repositoryRoot, walk } from './lib.mjs';
const inventoryPath = path.join(repositoryRoot, 'docs/phase12/COMPONENT_INVENTORY_v1.0.json');
const inventory = JSON.parse(await readFile(inventoryPath, 'utf8'));
const errors = [];
const allowedStatus = new Set(['implemented', 'partially-implemented', 'blocked', 'excluded']);
const names = new Set();
if (inventory.phase !== 12 || !Array.isArray(inventory.entries)) {
errors.push('Component inventory must identify Phase 12 and contain an entries array.');
}
for (const entry of inventory.entries ?? []) {
if (names.has(entry.name)) errors.push(`Duplicate inventory component: ${entry.name}`);
names.add(entry.name);
if (!allowedStatus.has(entry.status))
errors.push(`${entry.name}: invalid status ${entry.status}`);
for (const field of ['sourceSpecification', 'variants', 'openIssues', 'homepageConsumers']) {
if (!Array.isArray(entry[field])) errors.push(`${entry.name}: ${field} must be an array.`);
}
if (
!entry.tests ||
!['unit', 'interaction', 'accessibility', 'visual'].every(
(key) => typeof entry.tests[key] === 'boolean',
)
) {
errors.push(`${entry.name}: test coverage flags are incomplete.`);
}
if (entry.status === 'blocked' && entry.openIssues.length === 0) {
errors.push(`${entry.name}: blocked components require an issue reference.`);
}
}
for (const required of [
'Button',
'ActionLink',
'FormField',
'Tabs',
'Accordion',
'Dialog',
'Alert',
'Card',
'Workflow',
'Comparison',
'Metric',
'CTA',
'ProductPreview',
]) {
if (!names.has(required)) errors.push(`Required component missing from inventory: ${required}`);
}
const componentFiles = await walk(path.join(repositoryRoot, 'src/components'), (file) =>
/\.(?:ts|tsx|css)$/.test(file),
);
const forbiddenRawToken = /var\(--color-(?:blue|orange|gray|green|amber|red|navy)-/g;
const forbiddenLiteralColor = /(?:#[0-9a-f]{3,8}\b|rgba?\(|hsla?\()/gi;
for (const file of componentFiles) {
const text = await readFile(file, 'utf8');
const relative = path.relative(repositoryRoot, file);
if (file.endsWith('.css') && forbiddenRawToken.test(text))
errors.push(`${relative}: consumes a raw palette token.`);
if (file.endsWith('.css') && forbiddenLiteralColor.test(text))
errors.push(`${relative}: contains a literal color.`);
if (/href=["']#["']/.test(text)) errors.push(`${relative}: contains a placeholder href="#".`);
}
for (const artifact of [
'COMPONENT_SPECIFICATION_TRACEABILITY_v1.0.csv',
'VARIANT_INVENTORY_v1.0.csv',
'ACCESSIBILITY_BEHAVIOR_MATRIX_v1.0.csv',
'RTL_BEHAVIOR_MATRIX_UPDATE_v1.0.csv',
'RESPONSIVE_VALIDATION_MATRIX_v1.0.csv',
'STORY_AND_FIXTURE_INVENTORY_v1.0.csv',
'TEST_COVERAGE_REPORT_v1.0.csv',
'COMPONENT_CATALOG_v1.0.md',
]) {
try {
await stat(path.join(repositoryRoot, 'docs/phase12', artifact));
} catch {
errors.push(`Required Phase 12 artifact missing: ${artifact}`);
}
}
const fixturePage = await readFile(
path.join(repositoryRoot, 'src/app/[locale]/component-lab/page.tsx'),
'utf8',
);
if (!fixturePage.includes("COMPONENT_FIXTURES_ENABLED !== 'true'")) {
errors.push('Component fixture route is not protected by the production environment guard.');
}
if (errors.length > 0) fail(errors);
else
pass(
`${inventory.entries.length} inventory entries and ${componentFiles.length} component source files satisfy Phase 12 static controls.`,
);