Skip to content

refactor(multi-review): replace hand-written YAML parser with js-yaml#111

Merged
Svtter merged 1 commit into
mainfrom
worktree-replace-yaml-parser
May 25, 2026
Merged

refactor(multi-review): replace hand-written YAML parser with js-yaml#111
Svtter merged 1 commit into
mainfrom
worktree-replace-yaml-parser

Conversation

@Svtter
Copy link
Copy Markdown
Collaborator

@Svtter Svtter commented May 25, 2026

Summary

  • Replace the hand-written parseYAML() in reviewers.ts with js-yaml
  • The old parser only supported flat key: value and key: | formats, failing on lists, nested objects, and edge cases
  • Add js-yaml to noExternal in tsup config so it's bundled into dist/index.cjs

Refs #110

Test plan

  • npm run check passes
  • npm run build succeeds, js-yaml bundled into dist
  • multi-review CI runs successfully with the new bundle

🤖 Generated with Claude Code

The hand-written parseYAML() only supported flat key: value and key: |
formats, failing on lists, nested objects, and edge cases. js-yaml is a
mature parser that handles the full YAML spec.

Closes part of #110.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

决策:可合并

所有 reviewer 一致认为该 PR 方向正确且无阻塞性问题。

阻塞项:无

建议项:

  1. 运行时类型校验(已确认)yaml.load(raw) as PersonaYAML 的类型断言在运行时无安全保障。建议增加 zodyup 或手动类型守卫进行校验(quality、security 均提及)。
  2. Bundle 体积膨胀js-yaml 全量打包导致 dist/index.cjs 新增约 2300 行代码,但实际仅使用 yaml.load() 一种功能。若原解析器的 Bug 可通过修补而非替换解决,可考虑更轻量的替代方案(performance)。
  3. 错误日志yaml.load("") 返回 undefined 会被 catch {} 静默吞掉,建议加日志便于调试(quality)。

📋 各 Reviewer 详细审查结果
quality

可合并

该 PR 将自定义的 parseYAML 手写解析器替换为官方的 js-yaml 库,整体方向正确,无阻塞性问题。

阻塞项:无

建议项:

  1. yaml.load(raw) as PersonaYAML 的类型断言在运行时无安全保障。建议考虑使用 zodyup 等 schema 验证库做运行时校验,或者在 if 条件中增加 typeof parsed.name === 'string' && typeof parsed.prompt === 'string' 的类型守卫。
  2. yaml.load("") 返回 undefined,访问 undefined.name 会抛出 TypeError,当前被 catch {} 静默吞掉,行为与旧代码一致(旧代码返回 {} 不会抛错),不影响正确性但可以考虑加日志便于调试。
security

安全无虞

本次 PR 的核心改动是用 js-yaml v4.1.1 替换了自定义的 parseYAML 函数。从安全角度看:

  • 输入可控:YAML 文件来自 action 自带的 reviewers/ 目录(quality.yamlsecurity.yaml 等),非用户输入,攻击面极小
  • js-yaml v4 默认安全:v4 移除了 safeLoadload() 默认不解析 !!js/ 等危险标签,不会导致任意代码执行或原型污染
  • 依赖可信:js-yaml 是成熟稳定的 YAML 解析库,无已知高危 CVE
  • 异常处理:解析失败时通过 try-catch 静默跳过,与原有行为一致

阻塞项:无

建议项:

  • 可以考虑对 yaml.load() 的结果做运行时类型校验(如用 zodio-ts),确保返回的对象符合 PersonaYAML 结构,防止 YAML 文件异常时类型不匹配导致未定义行为
performance

性能有疑虑

本次 PR 将手写的 parseYAML 函数替换为 js-yaml v4.1.1 库。主要性能影响:

阻塞项:无

建议项:

  1. Bundle 体积显著增大js-yaml + argparse 被内联打包进 dist/index.cjs,新增约 2300 行代码。对于冷启动敏感的 GitHub Action,这增加了下载/加载时间。建议确认原自定义解析器是否存在实际 Bug 导致必须引入完整 YAML 库;若仅需要解析简单的 key-value + literal block scalar,可考虑更轻量的替代方案(如手写修复原解析器、或使用 @iarna/toml 级别的微型解析库)。
  2. 不必要的库容量js-yaml 是完整的 YAML 1.1 解析+序列化库(包含 dump、schema 等),但该 Action 仅使用 yaml.load() 一种功能。使用 tree-shaking 打包工具(如 tsup 的 esbuild)无法消除未使用的导出,因此 dumpSchema 等大量代码被毫无意义地包含在产物中。可考虑使用 yaml 的轻量化替代库或将 load 单独拆包。
architecture

架构合理

本次 PR 将 multi-review/src/reviewers.ts 中的手写 parseYAML 函数替换为经过实战检验的 js-yaml 库。这是一次合理的重构,理由如下:

  • 耦合度降低:自定义 parser 的正确性、边界情况处理和安全问题全部由 js-yaml 接管,无需自行维护脆弱解析器。
  • 模块放置正确js-yaml 仅在 reviewers.ts 中使用,导入位置符合单一职责。
  • 分层清晰:移除了 reviewer 模块中混入的 YAML 解析细节,yaml.load(raw) 调用将格式解析与业务逻辑解耦。
  • 无霰弹式修改:改动集中在 src/reviewers.ts(核心替换)、package.json / package-lock.json(依赖声明)和 tsup.config.ts(bundling 配置),所有变更都是必要且局部的。
  • 与现有架构一致noExternal 模式与已有的 @opencode-ai/sdk 打包策略一致。

阻塞项:无

建议项:无

@github-actions
Copy link
Copy Markdown

发现遗漏

摘要

PR 声称将手写 YAML 解析器替换为 js-yaml(issue #110 第 1 项),该核心功能已完成,但审查发现一项遗漏和一项回归。


MEDIUM

loadReviewers()configPath 形参仍是幽灵参数

issue #110 高优先级第 2 项明确要求「移除 loadReviewers() 未使用的 configPathteam 参数」。本次 PR 修改了 reviewers.tsteam 参数已在第 42 行被使用(opts.team || env(...)),但 configPath 在第 37 行 loadReviewers 接口中仍然声明,函数体内完全未引用。

建议:从 loadReviewers opts 类型中移除 configPath?: stringmulti-review/src/reviewers.ts:37)。


LOW

静默异常处理未改进(issue #110 高优先级第 4 项)— 第 29 行 catch { /* skip missing files */ } 仍然静默忽略所有异常,未输出任何调试日志。不归入 CRITICAL 因为旧行为也是如此,无退化。

超时逻辑余量(第 3 项)和 默认 model 名称不一致(第 5 项)未被本次 PR 涉及,不视为 gaps,仅为 issue 中待其他 PR 处理的独立事项。

New%20session%20-%202026-05-25T02%3A44%3A23.827Z
opencode session  |  github run

@Svtter Svtter merged commit 18db76a into main May 25, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant