Files
deepseek-harness/.agents/notes/implemented/simplification/2026-07-26-consolidate-gate-scripts-on-existing-deps.zh.md
T
Tianyi Cui c3873464ba refactor(scripts): consolidate gate scripts on mdast fences, parseArgs, and globSync
Implements the gate-consolidation Agent Note from the NIH dependency audit:

- Shared markdownFences helper in scripts/markdown.ts (mdast code-node visit);
  doc-typecheck and verify-type-equiv extract fences through it; md-fences.ts
  and the duplicated extractEquivBlocks regex scanner are deleted;
  markdownProseLines derives fenced lines from parsed code-node positions
  instead of a second fence regex.
- publint-all.ts and verify-built-package-invariants.mjs parse argv with
  node:util parseArgs instead of hand-stepped parseOptions copies.
- Five straggler readdirSync walks become globSync: verify-runtime-closure,
  dev-web discoverPluginDirs, verify-package-paths realPackageNames,
  verify-client-domain-graph listSources, publint-all addPath. The
  dirent-diagnostic walks in check-workspace-constraints.ts and clean.ts stay.

Behavior parity verified: pnpm run doc-sync and every rewritten gate produce
byte-identical output before and after on this tree.

Moves the owning Agent Note proposed -> implemented and re-records its pair.
2026-07-26 23:14:28 +08:00

5.1 KiB
Raw Blame History

Agent Note: 把门禁脚本统一到已有依赖与内置模块上

Status: implemented

English | 中文

问题

scripts/ 下的门禁大多已经在用正确的工具(15 个以上的门禁使用 node:fsglobSyncmarkdown 门禁使用 mdast/micromark),但少数几个掉队的脚本仍在手写同类门禁早已用既有依赖或内置模块完成的事情:

  • 重复的围栏扫描器。scripts/md-fences.ts(约 55 行,由 doc-typecheck.ts 消费)和 scripts/verify-type-equiv.ts 中的 extractEquivBlocks(约 39 行)是同一个围栏代码块正则行扫描器的两份拷贝,而 scripts/verify-mermaid.ts 已经通过访问 mdast code 节点来提取代码围栏;scripts/markdown.ts 自己的 markdownProseLines 也是先解析成 mdast,再用第二个正则手工跟踪围栏状态。这两个正则扫描器只识别第 0 列的反引号围栏,因此在波浪线围栏和缩进围栏上与基于 mdast 的门禁悄悄不一致。
  • 手写的 argv 解析。scripts/publint-all.ts 中的 parseOptionsscripts/verify-built-package-invariants.mjs 中与之几乎相同的拷贝(约 26 行)手工推进 argv 下标,而同类脚本(verify-runtime-closure.tsbuild-exe-for-python-sdk.tspackages/sdk/scripts/src/args.ts)已经在使用 node:util 的内置 parseArgs
  • **手写的目录遍历。**五处代码各自重写了 globSync 已覆盖的嵌套 readdirSync 遍历:verify-runtime-closure.ts 对 packages 与 vendor manifest(元数据清单)的扫描、dev-web.tsdiscoverPluginDirsverify-package-paths.tsrealPackageNamesverify-client-domain-graph.tslistSources,以及 publint-all.tsaddPath(合计约 5565 行)。scripts/package-invariants.ts 展示了一行式的 globSync 模板。

所有替换都不需要引入新依赖;每一处替换用的都是既有的 devDependency 或 Node 内置模块。

决策

  • scripts/markdown.ts 中的共享 mdast 围栏辅助函数 markdownFences 访问 code 节点,读取语言、完整 info string、块体以及以 1 起始的开围栏行号;doc-typecheck.tsverify-type-equiv.ts 通过它提取代码围栏。md-fences.ts 和重复的 extractEquivBlocks 扫描器已删除,markdownProseLines 也改为从解析出的 code 节点位置推导围栏内的行,而不再用第二个正则。
  • 两个 CLI 都改用 parseArgs 解析 argv;未知选项和缺失取值仍然大声失败,只是错误文案换成了 parseArgs 自带的文本,而非原先手写的用法字符串。
  • 那五处掉队的目录遍历改用 globSynccheck-workspace-constraints.tsclean.ts 中的遍历保留:它们需要 dirent 级别的细节来诊断结构异常的目录树,按模式匹配的 glob 报告不了这些信息。

曾考虑的替代方案

  • **新的 glob/目录遍历依赖(tinyglobbyfdir)。**不予采纳:内置模块已在全仓库范围内胜出;这几处只是掉队者,不是能力缺口。
  • **用 p-map 替换 publint-all.ts 中约 19 行的有序 worker 池。**刻意未纳入:为一次小删除引入一个新 devDependency,正处在依赖策略门槛的边缘,而且该池的需求(worker 数量有界、确定性顺序、环境变量覆盖)已记录在并行 pre-push 门禁决策记录中。仅当 p-map 赢得第二个消费方时再顺带纳入。
  • **保留这两个围栏扫描器。**不予采纳:在第三个正确实现旁边放着两份逐渐漂移的解析器拷贝,正是共享的 markdown.ts 辅助函数要防止的那种重复;「只认第 0 列反引号」的限制也是同类门禁之间的潜在不一致。

后果

  • 只剩一个围栏解析器:所有 markdown 门禁现在都经由 mdast 归类代码围栏,因此波浪线围栏、缩进围栏和四反引号容器围栏在各处的行为完全一致。文档树中不存在正则扫描器处理有误的围栏形态,所以在落地这次替换的代码树上门禁结果不变:pnpm run doc-sync 及每个被改写的门禁在改动前后各跑一遍,输出逐字节相同(doc-typecheck 的块数/opt-out 计数、verify-type-equiv 的匹配计数、publintverify-built-package-invariantsverify-runtime-closureverify-package-pathsverify-client-domain-graph,以及两个包 README 散文门禁)。
  • verify-type-equiv 不再对未闭合的围栏报专门的错误:mdast 会在文件末尾闭合未闭合的代码块,这样的块会进入 manifest 检查,并在那里以孤儿或漂移的形式照样失败,而不是触发专门的扫描器错误。doc-typecheck 的扫描器本来就没有这条错误路径。
  • parseArgs 对重复出现的选项保留最后一个值而不报错,还会把下一个以 -- 开头的 token 当作值消费;这两种情况都是测试未固定的开发工具边缘用例,作为删除两份手写解析器的交换被接受。