mcpField
C
codeant-resolve-pr-comments

codeant-resolve-pr-comments

github.com/codeant-ai测试与质量347 次安装9 周前更新
代码仓库

关于 codeant-resolve-pr-comments

Resolve CodeAnt PR Comments 是用于查找和处理 PR 中未解决 CodeAnt 行内建议的 Agent 技能。它通过已配置的源代码管理服务工作,编辑前需获批,验证修复后才解决讨论串,并避免发送 CodeAnt 遥测数据。

主要功能

  1. 01支持 GitHub、GitLab、Bitbucket 和 Azure DevOps
  2. 02获取并筛选未解决的行内建议
  3. 03验证并分类问题
  4. 04编辑前征求批准
  5. 05验证修复后解决讨论串

适用场景

  1. 01查找 PR 中未解决的 CodeAnt 建议
  2. 02先审阅问题,再执行获批的修改
  3. 03验证修复并解决对应讨论串
  4. 04通过已配置的服务访问处理 PR 评论

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/codeant-ai/skills --skill codeant-resolve-pr-comments

安装后在 Claude Code 中输入/codeant-resolve-pr-comments确认已加载。

详细介绍

解决 CodeAnt PR 评论

使用源代码管理提供商作为 PR 元数据、审查评论和线程状态的唯一可信来源。绝不安装、更新、调用或回退到 codeant-cli。绝不发送 CodeAnt 遥测数据。

工作流

  1. 运行预检。
  2. 仅选择一个提供商适配器,并获取所有结果页。
  3. 仅保留未解决的 CodeAnt 行内线程。
  4. 验证并分类每条发现。
  5. 提出计划,并在编辑前获得批准。
  6. 应用已批准的修复并运行相关验证。
  7. 仅解决已应用修复并通过验证的线程。
  8. 报告结果,并提出提交和推送。
  9. 完成所有 PR 工作后,执行一次请求的技能更新检查。

1. 预检

检查仓库,不作任何修改:

git status --short
git branch --show-current
git remote -v

保留所有现有更改。根据远程主机检测提供商:

  • github.com 或 GitHub Enterprise:GitHub。
  • gitlab.com 或自托管 GitLab:GitLab。
  • bitbucket.org:Bitbucket Cloud。
  • 其他 Bitbucket Server/Data Center 主机:Bitbucket Data Center。
  • dev.azure.com、ssh.dev.azure.com 或 *.visualstudio.com:Azure DevOps。

如果无法明确判断,请询问 PR 托管在哪个提供商上。如果用户提供了 PR/MR URL 或编号,请使用它。否则,查找源分支与当前分支完全一致的开放 PR。如果当前位于默认分支,则必须提供 PR 编号或 URL。如果不存在匹配项,或存在多个完全匹配项,请停止并请用户指定 PR。

使用已配置的提供商身份验证。预检期间不要探测多种身份验证方法;遵循所选提供商适配器的身份验证优先级。不要安装 CLI、泄露令牌、打印包含凭据的请求头,或在生成的文件中放入机密。如果缺少身份验证,请说明所需的提供商登录方式或令牌,并停止。

筛选 CodeAnt 建议

获取 PR 审查评论后,仅保留由 CodeAnt 生成且尚未解决的行内建议。符合以下任一条件时,将行内评论视为由 CodeAnt 生成:

  • 作者登录名、用户名、昵称或显示名称(不区分大小写)与 codeant-ai、codeant-ai[bot]、codeant-bot 或 CodeAnt AI 完全一致。
  • 评论正文包含以 https://app.codeant.ai/fix-in-ide 或 https://app.codeant.ai/feedback 开头的 CodeAnt 操作 URL。

使用正文特征,因为 GitLab 和 Azure DevOps 可能会将 CodeAnt 评论归属到已连接的人类账号。正文特征匹配时,不要要求评论作者是机器人,也不要单独进行身份发现或确认步骤。仅凭 CodeAnt 一词不要将评论归类为 CodeAnt 评论;必须匹配确切的服务账号名称或 CodeAnt 操作 URL。

跳过常规 PR 评论、摘要、质量门报告、系统消息、已删除的评论、草稿,以及并非行内发现起始内容的回复。如果没有符合条件的建议,请报告该 PR 没有未解决的 CodeAnt 行内建议,然后停止。否则直接继续验证。

2. 提供商适配器

仅选择匹配的适配器。将每个可执行项规范化为:

thread_id, comment_id, author_id, body, path, line, url,
resolved, outdated_or_stale, provider

保留提供商原生 ID 的原样,因为解决评论时需要这些 ID。

GitHub

要求已通过身份验证的 gh。确定 PR 和仓库:

gh auth status
gh pr view <number-or-url> --json number,title,url,state,headRefName,baseRefName
gh repo view --json nameWithOwner --jq .nameWithOwner

如果没有提供 PR 编号,请在当前分支上尝试运行 gh pr view。必要时,列出完全匹配的分支:

gh pr list --head "<branch>" --state open \
  --json number,title,url,state,headRefName,baseRefName

使用 GitHub GraphQL 获取并分页审查线程。使用 --paginate --slurp;分页变量必须命名为 $endCursor:

gh api graphql --paginate --slurp \
  -f owner='<owner>' \
  -f name='<repository>' \
  -F number=<pr-number> \
  -f query='query($owner: String!, $name: String!, $number: Int!, $endCursor: String) {
    repository(owner: $owner, name: $name) {
      pullRequest(number: $number) {
        number title url
        reviewThreads(first: 100, after: $endCursor) {
          nodes {
            id isResolved isOutdated
            comments(first: 100) {
              nodes {
                databaseId
                author { login }
                body path line originalLine createdAt url
              }
            }
          }
          pageInfo { hasNextPage endCursor }
        }
      }
    }
  }'

对于暂时性 HTTP 429、502、503 或 504 响应,最多重试此只读获取操作三次;如果存在 Retry-After,则遵循其指示。不要对身份验证、授权、架构或验证错误进行重试。

在所有返回的页面中,仅保留符合以下条件的线程:

  • isResolved 为 false。
  • 根评论符合 CodeAnt 作者或正文筛选规则。
  • 根评论的 path 非空;使用 line,仅在定位历史上下文时回退到 originalLine。

在过期验证中保留 isOutdated。成功修复线程后,使用其 GraphQL 线程节点 ID(而非数字评论 ID)解决线程:

gh api graphql \
  -f threadId='<thread-node-id>' \
  -f query='mutation($threadId: ID!) {
    resolveReviewThread(input: {threadId: $threadId}) {
      thread { id isResolved }
    }
  }'

要求响应确认 isResolved: true。

GitLab

要求已通过身份验证的 glab。GitLab 合并请求 IID 是项目级别的;不要将其与全局数据库 ID 混淆。

glab auth status
glab mr view <iid-or-url> --output json
glab repo view --output json

如果没有提供 IID,请查找 source_branch 与当前分支完全匹配的唯一一个开放 MR:

glab mr list --source-branch "<branch>" --state opened --output json

使用 glab repo view 返回的数字项目 ID,避免路径编码错误。获取所有讨论页面:

glab api --paginate \
  "projects/<project-id>/merge_requests/<mr-iid>/discussions?per_page=100"

仅保留符合以下条件的讨论:

  • individual_note 为 false。
  • 根备注符合 CodeAnt 作者或正文筛选规则。GitLab 可能会将关联的人类用户显示为作者,因此应接受正文中包含匹配的 CodeAnt 操作 URL 的备注。
  • CodeAnt 根备注的 resolvable: true 且 resolved: false。
  • 备注具有包含 new_path 或 old_path 的差异 position;优先使用 new_line,否则使用 old_line 作为上下文。

将讨论的 id 作为 thread_id,将根备注的 id 作为 comment_id。成功修复讨论后,解决该讨论:

glab api --method PUT \
  "projects/<project-id>/merge_requests/<mr-iid>/discussions/<discussion-id>" \
  -f resolved=true

要求返回的讨论显示相关的可解决备注已解决。

Bitbucket Cloud

使用 Bitbucket Cloud REST API 2.0,并通过现有 OAuth、访问令牌或 API 令牌进行身份验证。从远程地址或 PR URL 中解析 <workspace>/<repo-slug>。绝不要输出凭据。

如果没有提供 PR 编号,请列出开放的 PR,并选择 source.branch.name 完全匹配的唯一一个 PR。对查询值进行 URL 编码:

GET https://api.bitbucket.org/2.0/repositories/<workspace>/<repo-slug>/pullrequests
    ?state=OPEN&pagelen=100

获取所有评论页面,并持续跟进响应中的 next URL,直到其不存在:

GET https://api.bitbucket.org/2.0/repositories/<workspace>/<repo-slug>/pullrequests/<pr-id>/comments
    ?pagelen=100

仅保留符合以下条件的评论:

  • deleted 不为 true,且 pending 不为 true。
  • 是根评论,而非回复。
  • 存在 inline.path;新文件行使用 inline.to,旧文件行使用 inline.from。
  • resolution 为 null 或不存在。
  • 使用 user.nickname、user.display_name 或 content.raw,并按照 CodeAnt 作者或正文筛选规则匹配评论。

保留根评论的 id。成功修复线程后,解决该线程:

POST https://api.bitbucket.org/2.0/repositories/<workspace>/<repo-slug>/pullrequests/<pr-id>/comments/<comment-id>/resolve
Accept: application/json

要求 HTTP 200 响应,并且返回解决对象。绝不要以删除评论来代替解决评论。

Bitbucket Data Center

使用主机的 /rest/api/latest API,并通过现有的 bearer、个人访问令牌或会话进行身份验证。从远程 URL 或 PR URL 中解析 <base-url>、<project-key> 和 <repo-slug>。

如果未提供 PR ID,则对处于打开状态的 PR 进行分页,并选择其中唯一一个 fromRef.displayId 与当前分支完全匹配的项:

GET <base-url>/rest/api/latest/projects/<project-key>/repos/<repo-slug>/pull-requests
    ?state=OPEN&limit=100&start=<offset>

持续读取 nextPageStart,直到 isLastPage 为 true。以相同方式获取所有评论页:

GET <base-url>/rest/api/latest/projects/<project-key>/repos/<repo-slug>/pull-requests/<pr-id>/comments
    ?limit=100&start=<offset>

保留符合 CodeAnt 作者或正文筛选规则的根评论(使用 author.name、author.slug、author.displayName 或 text),并且其 anchor.path 必须存在、pending 不得为 true、state 必须为 OPEN,且 threadResolved 必须为 false。使用 anchor.line 和完整的锚定路径。

要解决已成功修复的评论线程,先重新获取评论以取得其当前 version,然后使用乐观并发控制更新:

PUT <base-url>/rest/api/latest/projects/<project-key>/repos/<repo-slug>/pull-requests/<pr-id>/comments/<comment-id>
Content-Type: application/json

{
  "id": <comment-id>,
  "version": <current-version>,
  "text": <unchanged-current-text>,
  "state": "OPEN",
  "severity": <unchanged-current-severity>,
  "threadResolved": true
}

保留当前文本、状态、严重性和必需属性。如果收到 HTTP 409,仅当该评论线程仍是同一个未解决的评论时,才重新获取并重试。要求响应显示 threadResolved: true。

Azure DevOps (ADO)

使用 Azure DevOps REST API 7.1。从远程 URL 或 PR URL 中解析组织、项目和仓库。优先使用不可变的仓库 ID 和身份 ID。

首次请求前,按以下优先级进行身份验证:

  1. 检查 AZURE_DEVOPS_PAT 是否非空,且不得打印或以其他方式泄露其值。
  2. 如果存在,则在本地对其进行规范化后再进行身份验证:
    • 默认将原始值视为 PAT。
    • 仅当其符合标准 Base64 规范语法(允许省略结尾填充)、严格解码成功,且解码后重新编码的值在填充规范化后与原值相同时,才将其视为 Base64 编码。
    • 仅当解码后的值是可识别的 Azure DevOps PAT 时才使用该值:可以是旧版 52 字符格式,或在文档规定位置带有固定 AZDO 签名的当前 84 字符格式。如果解码后是 <username>:<PAT> 格式的 HTTP Basic 负载,且第一个冒号后的部分符合其中一种 PAT 格式,也应接受;仅将 PAT 部分用作密码。
    • 否则,保留原始值不变。不得通过试探性 API 请求来判断该值是否经过编码。 立即将所得 PAT 用作 HTTP Basic 身份验证的密码。跳过 Azure CLI、Azure DevOps CLI、凭据管理器及其他身份验证发现。仅在内存中解码和构造授权值;绝不打印 PAT 或包含凭据的请求头,也不得将其写入文件。
  3. 如果经过 PAT 身份验证的请求返回 HTTP 401 或 403,应报告 PAT 无效、已过期、无权访问或权限范围不足,然后停止。不得静默回退到其他身份,因为这可能掩盖 PAT 配置错误,并以非预期用户身份访问资源。
  4. 仅当 AZURE_DEVOPS_PAT 不存在时,才使用已配置的 OAuth 或 Microsoft Entra 令牌。不得启动交互式登录。如果没有现成的非交互式凭据,请指出缺少身份验证凭据并停止。

如果未提供 PR ID,请对完整源引用进行 URL 编码,并选择唯一一个完全匹配且处于活动状态的项:

GET https://dev.azure.com/<organization>/<project>/_apis/git/repositories/<repository-id>/pullrequests
    ?searchCriteria.status=active
    &searchCriteria.sourceRefName=refs/heads/<branch>
    &$top=100
    &api-version=7.1

获取 PR 线程:

GET https://dev.azure.com/<organization>/<project>/_apis/git/repositories/<repository-id>/pullRequests/<pr-id>/threads
    ?api-version=7.1

仅在满足以下条件时保留线程:

  • status 为 active 或 pending。
  • threadContext.filePath 存在;使用 rightFileStart.line,否则使用 leftFileStart.line。
  • 根评论不是系统评论或已删除评论,且其 commentType 为 text。
  • 根评论符合 CodeAnt 作者或正文筛选规则,使用 author.uniqueName、author.displayName 或 content。Azure DevOps 可能会将关联的人类用户显示为作者。

保留数字类型的线程 id 和根评论 id。要标记已成功修复的线程,请将其标记为已修复:

PATCH https://dev.azure.com/<organization>/<project>/_apis/git/repositories/<repository-id>/pullRequests/<pr-id>/threads/<thread-id>
Content-Type: application/json

{"status":"fixed"}

使用 api-version=7.1,并要求返回的线程显示 status: fixed。对于已应用的修复,不得使用 closed、wontFix 或 byDesign。

3. 验证每项发现

按文件对发现进行分组。对每项发现:

  1. 阅读完整评论,以及被引用行上下至少 30 行内容。
  2. 检查相关定义、调用方、测试和仓库指南,以理解所述行为。
  3. 确认缺陷、预期行为、复现路径以及任何围栏代码建议。
  4. 如果提供方将位置标记为已过时、文件已不存在,或当前代码已不再符合所述问题,则标记为 STALE,除非该缺陷在被引用代码中仍明确存在。
  5. 将 Architect Review 和 Logical Review 评论视为可处理项。阅读完整的 Prompt for AI Agent 部分;如果未提供建议,则起草一个局部修复方案。
  6. 验证语法、范围、导入、类型、错误处理、公共接口、边缘情况、并发性,以及与调用方的兼容性。
  7. 优先采用最小且正确的修复。不要为了代码风格重构相邻代码。

必须且只能指定以下一种判定:

  • ACCEPT:缺陷确实存在,且局部修复安全,不会改变公共契约或削弱处理能力。
  • LIKELY ACCEPT:修复方案合理,但行为变更可能影响调用方,或需要有针对性的验证。
  • DO NOT ACCEPT:提议不安全、缺乏依据、依赖不可用的 API,或需要超出可安全提供的局部补丁范围的设计工作。
  • STALE:被引用的代码或缺陷已不存在。

不要仅因 Architect Review 或 Logical Review 未提供现成补丁就拒绝其评论。

4. 编辑前先提交计划

报告提供方、PR 编号、标题、链接以及未解决的 CodeAnt 行内线程数。按判定对所有发现进行分组。每项都包含:

  • 文件和行号。
  • 一句话概述问题。
  • 验证依据。
  • 适用时,说明计划中的修改前后变化。
  • 对于 LIKELY ACCEPT,列出需要验证的确切调用方、测试或行为。

说明 ACCEPT 修复已就绪,并询问是否纳入点名的 LIKELY ACCEPT 修复。未经批准不得编辑。绝不应用 DO NOT ACCEPT 或 STALE 发现的修复。

5. 应用并验证

获得批准后:

  1. 重新检查 git status --short,并保留已有的编辑。
  2. 仅对评论中提及的文件应用已确认的修复,但狭义必需的测试或导入除外。
  3. 检查差异,确认没有意外更改或修复之间的相互影响。
  4. 运行范围最窄且相关的格式化工具、静态检查和测试;如果共享行为发生变化,则扩大验证范围。
  5. 仅修复由这些编辑导致的失败。如果某项修复无法验证,且可安全单独撤销,则仅撤销该修复,将其线程留待处理,并报告情况。

6. 解决线程并报告

解决线程属于外部变更。只有在用户批准对应修复且本地验证通过后,才能逐个解决线程。即使个别解决操作失败,也要继续处理其他线程。

绝不解决 DO NOT ACCEPT、STALE、跳过、部分修复或未经验证的发现。如果提供方响应含糊,则在线程解决后重新获取线程状态。

最终报告:

  • 已应用并验证的修复,包括文件、行号、判定和测试结果。
  • 未应用的发现,包括判定和原因。
  • 已解决的提供方线程 ID,以及任何解决失败。
  • 最终的 git status --short,以及此工作流更改的文件。

询问是否需要提交并推送选定文件。未经明确批准,不得提交或推送。

7. 检查技能更新

仅在所有 PR 工作完成且最终报告已准备好之后、发送报告之前,尽力执行此检查。此检查绝不能延迟、更改或使 PR 工作流失效。

解析当前已加载的 codeant-resolve-pr-comments/SKILL.md 的路径,不要扫描无关目录。如果无法确定其路径或文件不可写,则静默跳过此检查。否则,仅发送一次未经身份验证的 GitHub API 请求,并将原始响应保存到临时文件:

curl --fail --silent --show-error \
  --connect-timeout 2 --max-time 5 \
  -H 'Accept: application/vnd.github.raw+json' \
  -H 'X-GitHub-Api-Version: 2022-11-28' \
  'https://api.github.com/repos/CodeAnt-AI/skills/contents/skills/codeant-resolve-pr-comments/SKILL.md?ref=main' \
  -o '<temporary-file>'

不要发送第二次请求,不要通过 releases、commits、tags 或包管理器继续查找,也不要重试失败的请求。使用响应前,必须确认 HTTP 请求成功,并验证它是合理的技能文件:文件必须以 YAML frontmatter 开头,声明的名称必须恰好为 name: codeant-resolve-pr-comments,包含 # Resolve CodeAnt PR Comments,并且恰好包含一个 `` 标记。

在本地比较远程标记与当前文件的标记。如果远程版本等于或低于当前版本,删除临时文件,并且仅在最终报告中添加 Skill update: already current。如果远程版本较高,则以原子方式仅替换当前技能文件,保留其现有权限,删除临时文件,并在最终报告中添加 Skill update: updated; the new instructions apply next session。绝不要覆盖较新的本地版本。如果验证、比较或替换失败,则尽可能删除临时文件,并添加一条简洁、不会阻塞流程的说明;不要重试。

防护规则

  • 在声称列表完整之前,获取所有分页。
  • 将提供方原生线程状态视为权威信息。
  • 逐条验证建议;绝不要盲目批量应用。
  • 保留无关的用户更改,避免修改无关文件。
  • 指出相互冲突的评论,不要擅自选择。
  • 绝不泄露访问令牌、PAT、Cookie 或详细的身份验证输出。
  • 任何步骤都不得安装、调用或依赖 codeant-cli。

评论

支持 Markdown