研发协作
在 GitHub PR 上逐条回复并解决评审评论的可执行流程
当需要针对当前分支的 PR 评审评论逐条收集用户决策、修改代码、并在用户批准预览后由代理在 GitHub 上发布回复并解决评审线程时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
在 GitHub PR 上逐条回复并解决特定
解决思路
- 先确认用户确实想要在 GitHub 上发布回复或解决线程;如果用户只想获取/展示评论,改用 `pr-comments`;如果只想改代码而不回帖,则不要用本技能。
- 在 PR 分支的仓库检出中工作;除非已加载的上下文缺少评论正文、作者、URL、路径或行号等关键字段,否则不要重新拉取评论;在最终预览获得用户批准前,不要发布 GitHub 回复、提交评审或解决线程。
- 如果上下文中没有 PR 评论,先获取并展示:优先调用内置 `/pr-comments` 工作流;否则用 GitHub CLI 兜底——识别当前 PR,拉取 PR 级评论、评审评论和评审正文,再用 `insert_code_review_comments` 展示;展示后先询问用户是否继续本回复流程。
- 过滤评论,只保留仍需用户处理的可执行评论:跳过 Warp/Oz/代码评审机器人发出的自动化 PR 级概览或状态评论(尤其是无文件位置、只总结评审状态/检查进度/声明无需改代码的评论),以及当前 GitHub 用户已回复过的评论。
- 识别当前 GitHub 用户:`GH_PAGER="" gh api user --jq .login`。对评审线程,利用 `reply_metadata.parent_comment_id`、线程元数据、解决状态和评论顺序:仅当线程已解决或该线程最新相关回复由当前用户发出时才跳过;若评审者在当前用户回复后又追加了新回复,则保留该线程。对无显式线程元数据的 PR 级评论,仅当上下文明确显示当前用户对该评论有回复(直接回复、引用、链接或紧随其后的引用回复)时才跳过。
- 对被跳过的自动化或已回复评论,维护一个简短的内部跳过列表(含评论 URL 和原因);不为跳过评论创建决策记录,不纳入逐条走查,也不纳入最终 GitHub 回复/解决预览,仅在末尾以简短跳过计数汇总。
- 不确定某评论是自动化、已回复还是仍可执行时,保留在走查中而非跳过。
- 本技能中每次 `ask_user_question` 调用都必须包含一个使用工具自由文本字段的 `Other...` 选项,让用户输入自定义模式、回复、理由、发布指令或下一步,而不要为了收集自定义文本而把控制权交回普通聊天。
- 在讨论单条评论前,先用 `ask_user_question` 提出恰好一个模式问题:`Respond one-by-one`、`Collect all decisions, then address in a batch`、`Other...`;后续流程使用所选模式。
- 逐条模式:对每条评论收集用户决策并立即执行所请求的代码修改,再处理下一条;每次修改后记录:所处理的评论、改动的代码或文档、已运行或仍需运行的验证、GitHub 回复草稿以及是否应解决该线程。
- 批量模式:对每条评论交互式收集决策但暂不改代码;批量模式不省略信息收集阶段——用户仍可就任一条评论要求更多上下文、请求解释、查看相关代码或提供自定义方案;所有评论都有决策后再一次性应用代码修改,然后验证并准备最终 GitHub 回复预览。
- 按展示顺序处理评论。对每条评论:1) 简要复述上下文——作者、文件与行号或 PR 级位置、可点击的文件引用(单行用 `path:line`,范围用 `path:start-end`,有位置元数据时)、评论的简明摘要、理解所需的明显代码上下文;2) 若从已加载上下文看不出修复方案,先检查相关文件再给出选项;3) 调用 `ask_user_question`,选项针对该具体评论定制。
- 当评论附在代码上时,提问前先打印文件引用(仓库相对路径,如 `src/lib.rs:42` 或 `src/lib.rs:40-48`),方便用户快速打开;对无文件位置的 PR 级评论,说明没有附带的代码位置。
- 选项始终包含这些含义:应用代理对该评论的推荐修复;先解释该评论含义再决定;确认收到评论但不改代码;`Other...`。用 `Other...` 的自由文本字段输入自定义回复或方案,不要为收集自定义文本而把控制权交回普通聊天。
- 当用户选择“解释”时,给出该评论的简明背景、评审者可能提出它的原因以及涉及的权衡,然后带着更新后的选项再次询问同一条评论,不要跳过决策。该解释循环在逐条模式和批量模式下都适用;批量模式只推迟最终的代码编辑和 GitHub 评论更新,逐条信息收集仍保持交互。
- 当用户选择“确认但不改代码”时,给用户机会补充不改代码的原因,并保留所提供的理由用于最终 GitHub 回复草稿。
- 为每条评论维护内部决策记录,包含:评论标识或 URL;评论类型(评审线程评论、线程回复、PR 级评论或评审正文);所选处置(修复、先解释再修复、确认但不改、自定义或无操作);计划中的代码修改(如有);所需验证;回复草稿正文;是否解决该评审线程。
- 回复草稿要简洁具体,优先说明改了什么或为何有意不处理该评论;每条可能发布到 GitHub 的草稿回复都要以 `[Warp Agent]` 为前缀,让评审者清楚这是代理所写;若回复发布前修复已提交并推送,附上解决该评论的提交链接以便审计。
- 按用户所选模式应用修复:逐条模式下,每条接受的修复先编辑并验证再处理下一条;批量模式下,等所有评论决策收集完再一起做所有接受的编辑。
- 修改时:只做与所选 PR 评论相关的改动;保留无关的本地改动;遵循仓库特定的编码、测试和风格规则;逐条修复后运行最小有用的验证,所有修复完成后运行最终验证;若某请求的修复不安全、含糊或与其他评论冲突,先停下询问用户再编辑。
- 所有接受的修复应用后做最终验证:1) 查看 `git diff` 确认改动与收集的决策一致;2) 根据仓库约定和改动文件运行相关格式化、lint、类型检查、构建或测试;3) 若无法运行验证,在最终总结中说明原因并在预览中带上该注意事项。除非用户明确要求,否则不要提交改动。
- 验证后、发布任何 GitHub 回复或解决评审线程前,询问用户是否要提交改动并推送到 `origin`,以确保评审者先看到推送的代码再看到代理的评论回复。若处理评论没有产生工作区改动,跳过提交/推送问题直接进入 GitHub 回复预览。
- 用 `ask_user_question` 提供类似选项:`Commit and push these changes to origin before posting replies`、`Do not commit or push; continue to the GitHub reply preview`、`Stop before posting GitHub replies`、`Other...`。
- 若用户选择提交并推送:1) 查看 `git status` 和最终 diff,确保只包含预期的评论回复改动;2) 若提交信息尚不明确,询问或提议一条简洁的提交信息,保留 `Other...` 供自定义提交指令;3) 暂存预期改动,用非交互命令提交,并把当前分支推送到 `origin`;4) 在提交信息中包含 `Co-Authored-By: Warp Agent <agent@warp.dev>`(绝不要放在 PR 描述中),若提交已有该行则不要重复添加;5) 若提交或推送失败,停止发布 GitHub 回复并报告失败。
- 提交/推送决策完成后、向 GitHub 发布任何内容前,按评论分组展示预览,每条包含:评论 URL 或短标识;动作(仅回复、仅解决、回复并解决、无 GitHub 动作);回复正文;修复已有推送提交时的提交链接;与该评论相关的验证。
- 然后用 `ask_user_question` 询问是否继续:`Post replies and resolve approved threads`、`Edit the draft responses first`、`Do not post anything`、`Other...`。若用户选择编辑,收集其修改、更新预览并再次请求批准;在用户选择批准选项前不要发布。
- 仅在批准后使用 GitHub CLI,所有 `gh` 命令都清空分页器。运行任何发布回复或 PR 评论的 GitHub CLI 命令前,确认发出的正文以 `[Warp Agent]` 开头;若没有,先加上前缀。
- 对评审评论,用 REST API 端点发布回复。把回复正文写入临时 JSON 文件并用 `--input` 传入,而不是把回复文本直接放在命令行参数中:`REPLY_BODY_FILE="$(mktemp)"; cat > "$REPLY_BODY_FILE"; REPLY_PAYLOAD_FILE="$(mktemp)"; python3 - "$REPLY_BODY_FILE" "$REPLY_PAYLOAD_FILE" <<'PY' ... PY; GH_PAGER="" gh api --method POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies --input "$REPLY_PAYLOAD_FILE"; rm -f "$REPLY_BODY_FILE" "$REPLY_PAYLOAD_FILE"`(该 Python 片段把正文文件读入并写成 `{"body": ...}` 的 JSON 载荷)。
- 对无法直接串接的 PR 级评论或评审正文评论,发布普通 PR 评论并引用或链接原评论:`REPLY_BODY_FILE="$(mktemp)"; cat > "$REPLY_BODY_FILE"; GH_PAGER="" gh pr comment {pull_number} --body-file "$REPLY_BODY_FILE"; rm -f "$REPLY_BODY_FILE"`。
- 解决评审线程用 GraphQL。若线程节点 ID 未知,先查询该 PR 的所有评审线程并把已加载评论 ID 映射到其所属线程;使用分页以便解决第 100 条之后的线程:`GH_PAGER="" gh api graphql --paginate -f owner="{owner}" -f repo="{repo}" -F number={pull_number} -f query='query($owner: String!, $repo: String!, $number: Int!, $endCursor: String) { repository(owner: $owner, name: $repo) { pullRequest(number: $number) { reviewThreads(first: 100, after: $endCursor) { pageInfo { hasNextPage endCursor } nodes { id isResolved comments(first: 100) { nodes { databaseId url } } } } } } }'`。
- 用以下命令解决已批准的线程:`GH_PAGER="" gh api graphql -f threadId="$THREAD_ID" -f query='mutation($threadId: ID!) { resolveReviewThread(input: { threadId: $threadId }) { thread { id isResolved } } }'`。
- 若某评论因可用元数据不足而无法回复或解决,报告该限制并建议手动在 GitHub 操作,而不要猜测。
- 发布已批准的回复并解决已批准的线程后,总结:已处理的评论、改动的文件、验证结果、改动是否已提交并推送到 `origin`、已发布的 GitHub 回复或解决动作、以及留给用户的事项。
适用边界 · 注意事项
- 用户只想获取或展示 PR 评论(应改用 `pr-comments`)。
- 用户只想做底层代码修改,不打算在 GitHub 上发布回复或解决线程。
- 尚未确认用户想要发布回复或解决线程时。