Implement the 031-quality-gates-hygiene feature that strengthens automated quality gates by adding pnpm audit to the check script, v8 coverage thresholds with per-directory auto-ratchet (domain 96%, adapters 71%, persistence 87%), Biome cognitive complexity enforcement (max 15), and keyboard accessibility for the combatant row, while cleaning up all blanket biome-ignore comments, refactoring 5 overly complex functions into smaller helpers, and codifying the early-enforcement principle in the constitution and CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -47,40 +47,34 @@ function matchesForbidden(importPath, forbidden) {
|
||||
return importPath === forbidden || importPath.startsWith(`${forbidden}/`);
|
||||
}
|
||||
|
||||
/** @returns {{ file: string, line: number, importPath: string, forbidden: string }[]} */
|
||||
export function checkLayerBoundaries() {
|
||||
const IMPORT_RE =
|
||||
/(?:import|from)\s+["']([^"']+)["']|require\s*\(\s*["']([^"']+)["']\s*\)/;
|
||||
|
||||
/**
|
||||
* Check a single file for forbidden imports.
|
||||
* @param {string} file
|
||||
* @param {string[]} forbidden
|
||||
* @returns {{ file: string, line: number, importPath: string, forbidden: string }[]}
|
||||
*/
|
||||
function checkFile(file, forbidden) {
|
||||
/** @type {{ file: string, line: number, importPath: string, forbidden: string }[]} */
|
||||
const violations = [];
|
||||
const content = readFileSync(file, "utf-8");
|
||||
const lines = content.split("\n");
|
||||
|
||||
for (const [srcDir, forbidden] of Object.entries(FORBIDDEN)) {
|
||||
const absDir = join(ROOT, srcDir);
|
||||
let files;
|
||||
try {
|
||||
files = collectTsFiles(absDir);
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const match = lines[i].match(IMPORT_RE);
|
||||
if (!match) continue;
|
||||
|
||||
for (const file of files) {
|
||||
const content = readFileSync(file, "utf-8");
|
||||
const lines = content.split("\n");
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
const match = line.match(
|
||||
/(?:import|from)\s+["']([^"']+)["']|require\s*\(\s*["']([^"']+)["']\s*\)/,
|
||||
);
|
||||
if (!match) continue;
|
||||
const importPath = match[1] || match[2];
|
||||
for (const f of forbidden) {
|
||||
if (matchesForbidden(importPath, f)) {
|
||||
violations.push({
|
||||
file: relative(ROOT, file),
|
||||
line: i + 1,
|
||||
importPath,
|
||||
forbidden: f,
|
||||
});
|
||||
}
|
||||
}
|
||||
const importPath = match[1] || match[2];
|
||||
for (const f of forbidden) {
|
||||
if (matchesForbidden(importPath, f)) {
|
||||
violations.push({
|
||||
file: relative(ROOT, file),
|
||||
line: i + 1,
|
||||
importPath,
|
||||
forbidden: f,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,6 +82,30 @@ export function checkLayerBoundaries() {
|
||||
return violations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all files in a layer directory for forbidden imports.
|
||||
* @param {string} srcDir
|
||||
* @param {string[]} forbidden
|
||||
* @returns {{ file: string, line: number, importPath: string, forbidden: string }[]}
|
||||
*/
|
||||
function checkLayer(srcDir, forbidden) {
|
||||
const absDir = join(ROOT, srcDir);
|
||||
let files;
|
||||
try {
|
||||
files = collectTsFiles(absDir);
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
return files.flatMap((file) => checkFile(file, forbidden));
|
||||
}
|
||||
|
||||
/** @returns {{ file: string, line: number, importPath: string, forbidden: string }[]} */
|
||||
export function checkLayerBoundaries() {
|
||||
return Object.entries(FORBIDDEN).flatMap(([srcDir, forbidden]) =>
|
||||
checkLayer(srcDir, forbidden),
|
||||
);
|
||||
}
|
||||
|
||||
// Run as CLI if invoked directly
|
||||
if (
|
||||
process.argv[1] &&
|
||||
|
||||
Reference in New Issue
Block a user