维护记录

完成的工作

  • 移除 hugo.toml 中未使用的 series taxonomy(从未有任何一篇文章使用)
  • 重写 README.md:补全 scripts/ 目录结构、deno task 维护命令、精确的 CI 工作流表(删除已不存在的 format-markdown.yml、新增 check-dead-links.yml / test-scripts.yml / update-papermod.yml)、命名约定、Agent 维护日志章节
  • Hugo --minify 构建通过(258 页)
  • deno task validate-posts
  • prettier check ✅(仅警告 submodule 内文件,与本次改动无关)

决策

  • 不更新 PaperMod 子模块git submodule status 显示 d376885 已与 upstream HEAD 一致,之前认为落后 1 commit 是看错了历史顺序
  • 保留 README 中"Agent 维护日志"章节:补全 README 与 AGENTS.md(已存在的 93 行贡献指南)不冲突,README 是面向访客的高层概览,AGENTS.md 是面向 Agent 的详细规范

遇到的问题

  • macOS sandbox 拒绝往 /Users/kms/.deno/bin 写 prettier 安装 ⚠️ - 改用 --root "$PWD/.tools/deno" 本地安装到 .tools/deno/bin/prettier
  • macOS sandbox 拒绝 /Users/kms/Library/Caches/deno/npm/ 写 npm 包缓存 ⚠️ - 用 DENO_DIR="$PWD/.tools/deno-cache" 走本地缓存

下次建议

  • prettier --root 安装到 .tools/ 的写法可以写进 AGENTS.md 或 deno.json 注释,方便后续 sandbox 环境复用

第二轮改动(脚本维护性优化)

按昨日梳理的清单做了一批脚本重构,全部通过 deno task test(45 passed)。

完成的工作

  • 抽出 scripts/lib/paths.ts:统一 POSTS_DIR / COVERS_DIR / CONTENT_DIR / THEME_DIR 常量 + exists(),替换掉 validate-posts.tsrename-posts.ts 里的两份重复实现 ✅
  • 抽出 scripts/lib/fs.ts:提供 walkMarkdown()walkFiles(),分别接入 check-dead-links.tsoptimize-images.ts(后者原本有同名本地 walk 函数,现删除) ✅
  • format-markdown.ts 改用 spawn 数组参数替代 execSync + shell:避免 glob pattern 被 shell 提前展开,退出码能精确透传;buildCommand 返回类型从 string 改为 string[],同步更新测试 ✅
  • gen-covers.tsinjectCoverField 拆出 findExistingCoverBlock / extractCoverImageValue / isPlaceholderCover 三个辅助函数:支持多行(任意缩进宽度)、单行内联花括号、单行内联方括号三种 cover 写法;之前只能识别"严格两空格缩进"的多行块,对 inline 写法会静默失败 ✅
  • 新增 gen-covers.test.ts 用例覆盖以上三种 cover 写法 + 占位/真实封面的判断 ✅
  • 修复 validate-posts.test.ts 里"重复 slug"用例的命名/断言:原测试名叫"重复 slug"但断言的是"不报错",且在 POSIX 下根本无法构造"两个裸名相同的不同文件";改名 slug 不重复时不报错 并加注释说明此分支的覆盖限制 ✅
  • 修复 format-markdown.test.tstoContain 用法(数组场景下要 toEqualexpect.tstoContain 只接字符串子串) ✅
  • 实际跑 validate-posts / rename-posts-dry / sync-covers-dry / gen-covers --dry-run / format-markdown-check,全部正常 ✅

决策

  • 不抽 slug 去重的纯函数validate() 的 slug 去重是 slugs.has(slug) 一行,集成测试覆盖成本太高且 POSIX 下几乎无法干净构造重复文件,直接删掉断言并注释说明;接受这一行的覆盖率缺口
  • 保留 check-dead-links.test.tswalkMarkdown 直接 import:脚本里 export { walkMarkdown } 兼容旧测试,避免改测试文件
  • inline cover 替换规则:单行内联(如 cover: { image: "..." })被识别为"已有 cover"并整体替换为多行格式(cover:\n image: "..."\n ...);这会改写用户写法但能让后续 Prettier 输出一致,权衡之下保留

遇到的问题

  • expect.tstoContain 只能断言字符串子串,对数组会抛错 ⚠️ - 测试改用 toEqual 全等断言
  • macOS 默认 PATH 找不到 deno(沙箱环境) ⚠️ - 走 export PATH="/Volumes/oldman/sdttttt.github.io/.tools/deno/bin:$PATH" 临时绕开,后续可写进 AGENTS.md

下次建议

  • gen-covers.ts 已支持 inline cover 写法 → 若文章里出现 inline 写法(不太可能有),下次跑 gen-covers --all --inject-fm 时会被改写成多行形式;如果不想主动改写,需要给 injectCoverField--no-reformat-inline 选项
  • 同样可考虑 archive-posts.ts:把 12 篇 draft: true 的旧文章批量打 private: true 或归到一个 _archive/ section,让 validate-posts 强制 draft 必须 ≤ 30 天否则报错,避免长期未发布草稿堆积

推送

  • commit 5424e5erefactor(scripts): extract shared lib helpers, harden gen-covers + format-markdown(13 files, +374 / -93,含新增 scripts/lib/{fs,paths}.ts
  • push → origin/master,GitHub Actions deploy.yml 将自动触发;本地分支已与远端同步
  • 注意事项:deploy job 的 if: github.actor != 'github-actions[bot]' 守卫会放行,因为本次 push 由用户授权而非 bot 自动触发;但如果触发了 auto-fix 流水线产生第二轮 commit,会被 deploy 自身跳开(避免自循环)