iter(g295): 新增表面阶梯审计并修正悬停底

This commit is contained in:
HIsheR
2026-10-26 23:35:57 +08:00
parent df40eb0073
commit 3533459e00
11 changed files with 105 additions and 23 deletions
+28 -2
View File
@@ -8,6 +8,7 @@ import { visualAudit } from '../lib/visual-audit.mjs';
import { auditContrast, formatReport, PAIRS } from '../lib/contrast-audit.mjs';
import { shellPalette } from '../lib/shell-palette.mjs';
import { auditMotion, formatMotionReport } from '../lib/motion-audit.mjs';
import { auditSurface, formatSurfaceReport, LADDER } from '../lib/surface-audit.mjs';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -1727,6 +1728,28 @@ function cmdAuditMotion(args) {
process.exit(failing === 0 ? 0 : 1);
}
/*** 表面阶梯审计:底色对底色(悬停 / 按下 / 凹陷)差得看不出就是没做(--json 出明细、--list 只看阶梯表) ***/
function cmdAuditSurface(args) {
if (args.includes('--list')) {
for (const s of LADDER) console.log(`${s.label}:--ua-color-${s.from} → --ua-color-${s.to},亮度比阈值 ${s.min}`);
return;
}
let result;
try {
result = auditSurface(ROOT);
} catch (err) {
console.error(`audit:surface 失败:${err.message}`); // 求值不了就红:静默跳过等于默许阶梯糊在一起
process.exit(1);
}
if (args.includes('--json')) {
const steps = result.rows.map((r) => ({ ...r, ratio: Number(r.ratio.toFixed(3)) }));
console.log(JSON.stringify({ ok: result.failures.length === 0, total: steps.length, failing: result.failures.length, steps }, null, 2));
} else {
console.log(formatSurfaceReport(result));
}
process.exit(result.failures.length === 0 ? 0 : 1);
}
/*** 迭代留痕校验:.ua/iterations.log 每行 JSON 字段与格式必须符合 ITERATION.md 规范 ***/
function cmdLintIterations() {
const file = path.join(INDEX_DIR, 'iterations.log');
@@ -1824,7 +1847,7 @@ function cmdDoctor() {
detail: [missingInUsage.length ? `usage 缺 ${missingInUsage.join('/')}` : '', missingInCode.length ? `实现缺 ${missingInCode.join('/')}` : ''].filter(Boolean).join(';'),
});
// 门禁链自检:package.json 的 check 必须跑齐所有门禁步骤(新增门禁忘了接进链等于没加)
const needSteps = ['build', 'demo', 'style', 'typecheck', 'smoke', 'index', 'verify', 'lint-iterations', 'audit:visual', 'audit:contrast', 'audit:motion'];
const needSteps = ['build', 'demo', 'style', 'typecheck', 'smoke', 'index', 'verify', 'lint-iterations', 'audit:visual', 'audit:contrast', 'audit:motion', 'audit:surface'];
const chain = String(JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8')).scripts?.check ?? '');
const lacking = needSteps.filter((step) => !chain.includes(`npm run ${step}`));
checks.push({ name: 'check 链覆盖全部门禁步骤', pass: !lacking.length, detail: lacking.length ? `缺 ${lacking.join(' / ')}` : '' });
@@ -1903,10 +1926,13 @@ switch (cmd) {
case 'audit:motion':
cmdAuditMotion(args);
break;
case 'audit:surface':
cmdAuditSurface(args);
break;
case 'mcp':
cmdMcp();
break;
default:
console.log('usage: ua <index|list|search <kw>|info <name> [--json|--md]|recipes [编号] [--json]|docs|tokens [--json|--unused]|style|sync-counts|verify|doctor|commit-lint|lint-iterations|audit:visual [--json|--baseline]|audit:contrast [--json|--list]|audit:motion [--json]|changelog|mcp>');
console.log('usage: ua <index|list|search <kw>|info <name> [--json|--md]|recipes [编号] [--json]|docs|tokens [--json|--unused]|style|sync-counts|verify|doctor|commit-lint|lint-iterations|audit:visual [--json|--baseline]|audit:contrast [--json|--list]|audit:motion [--json]|audit:surface [--json|--list]|changelog|mcp>');
process.exit(cmd ? 1 : 0);
}