Compare commits

...

2 Commits

Author SHA1 Message Date
HIsheR 35c9f00e26 chore(backlog): 记录 f05 完成 2026-10-23 18:52:13 +08:00
HIsheR 265060fdb3 iter(f05): index 幂等化防时间戳弄脏工作区 2026-10-23 18:52:09 +08:00
3 changed files with 16 additions and 4 deletions
+1 -1
View File
@@ -354,7 +354,7 @@
"title": "ua index 幂等化:generatedAt 仅内容变化时更新",
"motivation": "ua index 每次重写 .ua/index.json 的 generatedAt,npm run check 必然弄脏工作区,与「提交前 check」工作流冲突",
"acceptance": "index 命令改为:若除 generatedAt 外内容与现有文件一致则不写入(或 generatedAt 改为内容哈希派生);连续两次 npm run check 后 git status 必须干净",
"status": "open",
"status": "done",
"notes": "来源:审计应修 #5"
},
{
+1
View File
@@ -43,3 +43,4 @@
{"ts":"2026-10-23T18:44:08+08:00","id":"f02","result":"done","commit":"f2fc286","summary":"AGENTS.md 与 ITERATION.md 的 npm run check 描述补上 verify,与实际六步链一致"}
{"ts":"2026-10-23T18:46:55+08:00","id":"f03","result":"done","commit":"f57da4c","summary":"ua 新增 lint-iterations 子命令校验留痕格式并并入 check 链,36 条历史违规行按 git author date 回填修复"}
{"ts":"2026-10-23T18:48:36+08:00","id":"f04","result":"done","commit":"99ce0cd","summary":"commit-lint 收严:非 iter type 必须带 scope,裸 chore:/docs:/iter: 反向用例全部拒绝,COMMITTING.md 同步"}
{"ts":"2026-10-23T18:52:12+08:00","id":"f05","result":"done","commit":"265060f","summary":"ua index 幂等化:剔除 generatedAt 比对且行尾归一化,内容无变化跳写,连续两次 check 后工作区干净"}
+14 -3
View File
@@ -56,6 +56,13 @@ function collectManifests() {
return out;
}
/*** 内容无变化则跳过写入(幂等,行尾归一化防 CRLF 误判),避免时间戳刷新弄脏工作区 ***/
function writeIfChanged(file, content) {
if (fs.existsSync(file) && fs.readFileSync(file, 'utf8').replace(/\r\n/g, '\n') === content) return false;
fs.writeFileSync(file, content);
return true;
}
/*** 聚合清单,生成 .ua/index.json 与 llms.txt ***/
function cmdIndex() {
const packages = collectManifests();
@@ -66,7 +73,11 @@ function cmdIndex() {
repoRoot: '.',
packages,
};
fs.writeFileSync(INDEX_FILE, JSON.stringify(index, null, 2) + '\n');
// 幂等:剔除 generatedAt 后内容一致即不写入,连续 check 不弄脏工作区
const json = JSON.stringify(index, null, 2) + '\n';
const stripTs = (s) => s.replace(/"generatedAt": "[^"]*"/, '"generatedAt": ""');
const changed = !fs.existsSync(INDEX_FILE) || stripTs(fs.readFileSync(INDEX_FILE, 'utf8').replace(/\r\n/g, '\n')) !== stripTs(json);
if (changed) fs.writeFileSync(INDEX_FILE, json);
const lines = [
'# @ui-arch 私人组件库索引',
@@ -87,8 +98,8 @@ function cmdIndex() {
for (const c of p.conventions ?? []) lines.push(`- 约定: ${c}`);
lines.push('');
}
fs.writeFileSync(LLMS_FILE, lines.join('\n'));
console.log(`indexed ${packages.length} package(s) -> .ua/index.json, llms.txt`);
writeIfChanged(LLMS_FILE, lines.join('\n'));
console.log(`indexed ${packages.length} package(s) -> .ua/index.json, llms.txt${changed ? '' : ' (unchanged, skip)'}`);
}
/*** 读取注册表索引;缺失则报错退出 ***/