diff --git a/.ua/backlog.json b/.ua/backlog.json index 8237c53..b4fb7dd 100644 --- a/.ua/backlog.json +++ b/.ua/backlog.json @@ -402,8 +402,16 @@ "title": "ua verify 增加 llms-full.txt 生成同步校验", "motivation": "llms-full.txt 是手工触发 ua docs 生成的产物,改 manifest 后忘记跑 docs 会产生文档漂移,目前无门禁", "acceptance": "verify 内联重渲染 Agent 文档(时间戳归一化)与根目录 llms-full.txt 比对,不一致即报错提示 npm run docs;npm run check 全绿", - "status": "open", + "status": "done", "notes": "自补:工具链防漂移方向" + }, + { + "id": "g06", + "title": "组件数门禁扩展 README 计数文本", + "motivation": "f01 的计数漂移校验只覆盖 AGENTS/ARCHITECTURE,README 的「N 个 DOM 组件」文本仍可漂移", + "acceptance": "checkCountDocs 扫描列表加入 README.md,漂移即 verify 失败;npm run check 全绿", + "status": "open", + "notes": "自补:f01 收尾" } ] } diff --git a/packages/tools/cli/bin/ua.js b/packages/tools/cli/bin/ua.js index bcc7c66..5224bca 100644 --- a/packages/tools/cli/bin/ua.js +++ b/packages/tools/cli/bin/ua.js @@ -623,6 +623,18 @@ function checkCountDocs(actual) { return issues; } +/*** llms-full.txt 同步校验:内联重渲染 Agent 文档(时间戳归一化)与落盘产物比对,防 manifest 改后忘跑 docs ***/ +function checkLlmsFull(pkgs, issues) { + if (!fs.existsSync(LLMS_FULL)) return; // 卫语句:产物缺失不算漂移(可能是新仓库) + const tokensPath = path.join(ROOT, 'packages', 'design', 'tokens', 'tokens.json'); + const tokens = fs.existsSync(tokensPath) ? JSON.parse(fs.readFileSync(tokensPath, 'utf8')) : null; + const norm = (s) => s.replace(/\r\n/g, '\n').replace(/自动生成于 [^,]*/, '自动生成于 X'); + const expected = renderAgentDocs({ generatedAt: '', packages: pkgs }, tokens); + if (norm(fs.readFileSync(LLMS_FULL, 'utf8')) !== norm(expected)) { + issues.push('llms-full.txt 与清单不一致,请运行 npm run docs 重新生成'); + } +} + /*** 清单一致性校验:组件文档块的 id / props 说明 / demo 锚点必须与代码和演示产物对齐 ***/ function cmdVerify() { const issues = []; @@ -663,6 +675,7 @@ function cmdVerify() { .flatMap((p) => p.docs?.components ?? []).length; issues.push(...checkCountDocs(skinTotal)); issues.push(...checkReadme(pkgs)); + checkLlmsFull(pkgs, issues); if (issues.length) { for (const it of issues) console.error('verify: ' + it);