关于 cc-pr-review-ci
cc-pr-review-ci 是单 Agent 技能,按 12 个领域审查 PR 并生成结构化发现结果。它将审查与发布 GitHub 行内评论分开,默认不会在 CI 中发布评论。
主要功能
- 01按顺序覆盖 12 个审查领域
- 02读取并过滤已撤销的发现
- 03将发现写入 review.json
- 04由独立脚本发布 GitHub 行内评论
- 05本地模式与 origin/main 比较
适用场景
- 01在 CI 中运行结构化 PR 审查
- 02将本地改动与 origin/main 比较审查
- 03代码未变化时避免重复已撤销发现
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ adrianbrowning/ agent-skills --skill cc-pr-review-ci安装后在 Claude Code 中输入/cc-pr-review-ci确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
post-review.jsreferences/bug.mdcomments.mddevops.mdduplication.mdformat.mdholistic.mdperformance.mdreact-ts.mdscope.mdsecurity.mdtest-validity.mdtesting.mdthermo.md详细介绍
PR 审查(单 Agent,适用于 CI)
依次从 12 个领域审查一个 PR,然后写入 review.json。另一个发布脚本会将 JSON 转换为 GitHub 行内审查评论。
如果未提供 PR 编号,则与 origin/main 比较差异,并将 JSON 输出到 stdout。
步骤 0 — 加载先前的驳回记录(仅限 PR 运行)
如果未提供 PR 编号,则跳过。
获取此 PR 上所有现有的机器人审查:
gh api repos/{owner}/{repo}/pulls/$PR_NUMBER/reviews \
--jq '[.[] | select(.body | test(""; "i")) | {id: .id, commit_id: .commit_id, submitted_at: .submitted_at}]'
对于找到的每条机器人审查,获取其行内评论:
gh api repos/{owner}/{repo}/pulls/$PR_NUMBER/reviews/$REVIEW_ID/comments \
--jq '[.[] | {id: .id, body: .body, path: .path, line: (.line // .original_line), reactions: .reactions}]'
同时获取这些行内评论中的所有回复线程:
gh api repos/{owner}/{repo}/pulls/$PR_NUMBER/comments \
--jq '[.[] | select(.in_reply_to_id != null) | {id: .id, in_reply_to_id: .in_reply_to_id, body: .body}]'
构建 SUPPRESSED_FINDINGS:每条被驳回的发现对应一个条目,格式为 { id, path, line, commit_id },其中 commit_id 是发布先前审查时对应的提交。
如果先前的行内评论满足以下任一条件,则该发现视为已驳回:
- 有一个 👎 表情回应(
.reactions["-1"] > 0),或 - 人类回复中包含表示驳回的措辞:"intentional"、"by design"、"won't fix"、"false positive"、"ignore"、"not applicable"、"expected"
从先前评论的正文中提取发现的 id — 脚本发布的每条行内评论都会在第一行包含一个 HTML 注释 ``。
例外处理 — 如果代码在驳回后发生变化,则重新评估。 PR 差异始终包含 PR 中所有已更改的行,因此应与先前审查所针对的提交进行比较:
HEAD_SHA=$(gh pr view $PR_NUMBER --json headRefOid --jq .headRefOid)
gh api repos/{owner}/{repo}/compare/$COMMIT_ID...$HEAD_SHA \
--jq '[.files[] | {filename: .filename, previous_filename: .previous_filename, patch: .patch}]'
对于每个不同的 commit_id 执行一次。如果某个条目的 path 与文件的 filename 或 previous_filename 匹配,且满足以下任一条件,则从 SUPPRESSED_FINDINGS 中移除该条目:
- 某个代码块与该发现重叠。对于每个代码块标头
@@ -start,count +...,旧侧区间为start到start + max(count, 1) - 1(若省略count,则取 1)。如果该区间与line - 5到line + 5相交,则视为重叠。检查整个区间,而不只是start:即使代码块起始位置远早于该发现,也可能涵盖该发现。 - 条目没有
line(文件级发现)。 - 文件没有
patch(二进制文件或文件过大,无法生成差异)。
如果针对某个 commit_id 的比较调用失败(例如,该提交因强制推送而不存在),则移除该 commit_id 对应的所有条目。
如果没有先前的审查或没有驳回记录,则 SUPPRESSED_FINDINGS 为空。
步骤 1 — 获取差异和 PR 元数据
- 提供了 PR 编号 →
gh pr view $PR_NUMBER(标题和正文,供范围领域使用)以及gh pr diff $PR_NUMBER - 未提供 PR 编号 →
git diff origin/main(无元数据;范围领域跳过 PR 规范检查)
步骤 2 — 依次执行 12 个领域的审查
阅读每个领域的参考文件,然后分析差异。记录发现的准确文件路径和行号。
记录任何发现之前:如果其计算出的 id({domain}-{kebab-title})仍在步骤 0 生成的 SUPPRESSED_FINDINGS 中,则静默跳过。
- 安全性 —
Read .claude/skills/cc-pr-review-ci/references/security.md - 性能 —
Read .claude/skills/cc-pr-review-ci/references/performance.md - React/TypeScript —
Read .claude/skills/cc-pr-review-ci/references/react-ts.md - 测试 —
Read .claude/skills/cc-pr-review-ci/references/testing.md - 测试有效性 —
Read .claude/skills/cc-pr-review-ci/references/test-validity.md - DevOps/CI —
Read .claude/skills/cc-pr-review-ci/references/devops.md - 整体审查 —
Read .claude/skills/cc-pr-review-ci/references/holistic.md - 重复代码 —
Read .claude/skills/cc-pr-review-ci/references/duplication.md - 漏洞排查 —
Read .claude/skills/cc-pr-review-ci/references/bug.md - 范围/规范 —
Read .claude/skills/cc-pr-review-ci/references/scope.md - 可维护性 —
Read .claude/skills/cc-pr-review-ci/references/thermo.md - 注释 —
Read .claude/skills/cc-pr-review-ci/references/comments.md
步骤 3 — 编写 review.json
-
阅读
.claude/skills/cc-pr-review-ci/references/format.md,了解确切的架构。 -
将所有领域的发现合并到一个
findings数组中。按照{domain}-{kebab-title}约定为每项发现分配一个稳定的id。 -
确定 verdict:
- 存在任何
critical→CHANGES_REQUESTED - 仅有
high→APPROVED_WITH_SUGGESTIONS - 仅有
observations或没有发现 →APPROVED
- 存在任何
-
写入 JSON:
- PR 运行:写入
$REVIEW_OUTPUT_PATH(默认值为/tmp/review.json) - 本地运行(无 PR 编号):打印到标准输出
- PR 运行:写入
不要调用 gh 发布任何内容。 工作流中的 post-review.js 步骤会负责所有 GitHub 写入操作。