iter(g186): 固化视觉回归抽查清单
This commit is contained in:
@@ -1235,6 +1235,52 @@ function checkPropsDoc(pkg, comps) {
|
||||
return issues;
|
||||
}
|
||||
|
||||
/*** 视觉回归抽查清单校验:ITERATION.md 的清单必须六个高频组件齐全、每条带合法维度标签、条目数达标 ***/
|
||||
function checkVisualChecklist() {
|
||||
const DIMS = ['边框', '阴影', '过渡', '焦点环', '暗色']; // 五个必覆盖维度
|
||||
const REQUIRED = ['button', 'textField', 'select', 'modal', 'dataTable', 'toast']; // 六个代表组件
|
||||
const MIN_PER_GROUP = 3; // 每个组件至少三条可勾选要点
|
||||
const MIN_TOTAL = 18; // 清单总条目下限
|
||||
const file = path.join(ROOT, 'ITERATION.md');
|
||||
if (!fs.existsSync(file)) return ['视觉回归抽查清单:找不到 ITERATION.md'];
|
||||
const lines = fs.readFileSync(file, 'utf8').replace(/\r\n/g, '\n').split('\n');
|
||||
const start = lines.findIndex((l) => /^##\s+视觉回归抽查清单/.test(l));
|
||||
if (start === -1) return ['视觉回归抽查清单:ITERATION.md 缺少《视觉回归抽查清单》章节'];
|
||||
const rest = lines.slice(start + 1);
|
||||
const stop = rest.findIndex((l) => /^##\s+/.test(l)); // 下一个二级标题即章节结束
|
||||
const body = stop === -1 ? rest : rest.slice(0, stop);
|
||||
const issues = [];
|
||||
const groups = new Map(); // 组件 id → 该段的维度标签列表
|
||||
let current = null;
|
||||
for (const line of body) {
|
||||
const head = line.match(/^###\s+(\S+)/);
|
||||
if (head) {
|
||||
current = head[1];
|
||||
if (!groups.has(current)) groups.set(current, []);
|
||||
continue;
|
||||
}
|
||||
const item = line.match(/^-\s+\[[ x]\]\s+【([^】]+)】/);
|
||||
if (!item) continue;
|
||||
if (!current) {
|
||||
issues.push(`视觉回归抽查清单:条目「${line.trim().slice(0, 24)}」没有归到任何 ### 组件段下`);
|
||||
continue;
|
||||
}
|
||||
if (!DIMS.includes(item[1])) issues.push(`视觉回归抽查清单:${current} 的条目维度「${item[1]}」不在五类之内(${DIMS.join(' / ')})`);
|
||||
groups.get(current).push(item[1]);
|
||||
}
|
||||
for (const id of REQUIRED) {
|
||||
const items = groups.get(id);
|
||||
if (!items) issues.push(`视觉回归抽查清单:缺少 ### ${id} 段`);
|
||||
else if (items.length < MIN_PER_GROUP) issues.push(`视觉回归抽查清单:${id} 只有 ${items.length} 条要点,至少 ${MIN_PER_GROUP} 条`);
|
||||
}
|
||||
const total = [...groups.values()].reduce((sum, items) => sum + items.length, 0);
|
||||
if (total < MIN_TOTAL) issues.push(`视觉回归抽查清单:合计 ${total} 条要点,至少 ${MIN_TOTAL} 条`);
|
||||
const covered = new Set([...groups.values()].flat());
|
||||
const missed = DIMS.filter((d) => !covered.has(d));
|
||||
if (missed.length) issues.push(`视觉回归抽查清单:维度未覆盖 ${missed.join(' / ')}(五类都要有)`);
|
||||
return issues;
|
||||
}
|
||||
|
||||
/*** 清单一致性校验:组件文档块的 id / props 说明 / demo 锚点必须与代码和演示产物对齐 ***/
|
||||
function cmdVerify() {
|
||||
const issues = [];
|
||||
@@ -1290,13 +1336,14 @@ function cmdVerify() {
|
||||
checkDarkTokens(issues);
|
||||
checkLlmsFull(pkgs, issues);
|
||||
issues.push(...checkIterations());
|
||||
issues.push(...checkVisualChecklist());
|
||||
|
||||
if (issues.length) {
|
||||
for (const it of issues) console.error('verify: ' + it);
|
||||
console.error(`${issues.length} violation(s)`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('verify OK (manifest ↔ docs ↔ demo 一致,文档 props ↔ 入参接口双向一致,皮肤无硬编码颜色与未定义令牌、暗色令牌齐全,README 组件清单与分组同步,backlog ↔ 留痕一致(编号严格递增、无重复 id、留痕时间线单调且带 +08:00),组合配方结构完整,MCP 工具清单三处一致)');
|
||||
console.log('verify OK (manifest ↔ docs ↔ demo 一致,文档 props ↔ 入参接口双向一致,皮肤无硬编码颜色与未定义令牌、暗色令牌齐全,README 组件清单与分组同步,backlog ↔ 留痕一致(编号严格递增、无重复 id、留痕时间线单调且带 +08:00),组合配方结构完整,MCP 工具清单三处一致,视觉回归抽查清单六组件 × 五维度齐全)');
|
||||
}
|
||||
|
||||
/*** 校验 git 提交信息是否符合 COMMITTING.md 规范(参数为 message 文件路径或直接 message 文本),违规退出码 1 ***/
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"ua info <包名|组件id>:包名返回摘要,组件 id 返回 props 表 + 步骤 + 示例;--json 输出原始清单",
|
||||
"ua docs:生成人类文档站 apps/docs/index.html + demo.html 与 Agent 全量文档 llms-full.txt",
|
||||
"ua style:注释规范门禁(导出必须 /*** ***/、接口字段行尾注释、行注释中文),违规退出码 1",
|
||||
"ua verify:清单一致性门禁(id 唯一 / exports 对应 / props 必带 n t d / steps≥3 / demo 锚点存在)",
|
||||
"ua verify:清单一致性门禁(id 唯一 / exports 对应 / props 必带 n t d / steps≥3 / demo 锚点存在 / 视觉回归抽查清单六组件各 ≥3 条且五维度齐全)",
|
||||
"ua commit-lint <文件|message>:提交信息门禁(type 枚举 / scope 规则 / subject 中文祈使 ≤50 字符),规范见 COMMITTING.md,违规退出码 1",
|
||||
"ua audit:visual [--json|--baseline]:视觉漂移门禁,统计皮肤包里各类硬编码视觉字面量(字号/动效时长/阴影/圆角/焦点环/内距/控件高度/字重/行高/层级/边框色)并与 .ua/visual-baseline.json 棘轮比对,超基线退出码 1;--baseline 重写基线,--json 出机器可读计数",
|
||||
"ua mcp:零依赖 stdio MCP server,暴露 list_components / get_component / search_components / get_tokens / list_recipes / get_recipe"
|
||||
|
||||
Reference in New Issue
Block a user