关于 greploop
Greploop 是用于反复处理 PR、MR 或 Perforce changelist 中 Greptile 审查反馈的技能,最多运行五轮。它会识别平台、获取审查结果、修复可执行的问题并报告最终状态。
主要功能
- 01识别 GitHub、GitLab 或 Perforce
- 02定位待审查的变更
- 03触发并轮询 Greptile 审查
- 04处理可执行的审查意见
- 05解决已处理的讨论线程
- 06报告置信度和未解决意见
适用场景
- 01处理 GitHub PR 的审查反馈
- 02处理 GitLab MR 上的 Greptile 意见
- 03迭代修改 Perforce changelist
- 04检查未解决意见和审查置信度
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ greptileai/ skills --skill greploop安装后在 Claude Code 中输入/greploop确认已加载。
附带文件references/gitlab-api.mdreferences/graphql-queries.md
详细介绍
Greploop
迭代修复 PR/MR/CL,直到 Greptile 给出完美评审:置信度为 5/5,且没有未解决的评论。
输入
- PR/MR/CL 编号(可选):如果未提供,则检测当前分支对应的 PR/MR,或 p4 中默认的待处理变更列表。
说明
0. 检测平台
先检查 Perforce,再回退到通过 git remote 检测:
# Check for Perforce environment
if p4 info >/dev/null 2>&1; then
VCS="perforce"
else
REMOTE_URL=$(git remote get-url origin)
if echo "$REMOTE_URL" | grep -qi "gitlab"; then
VCS="gitlab"
else
VCS="github"
fi
fi
对于主机名中不含“gitlab”的自托管 GitLab 实例,用户可以传入 --vcs gitlab 作为输入来覆盖默认设置。对于 Perforce,传入 --vcs perforce。
1. 确定 PR/MR/CL
GitHub:
gh pr view --json number,headRefName -q '{number: .number, branch: .headRefName}'
GitLab:
glab mr view --output json | jq '{iid: .iid, branch: .source_branch}'
如果当前不在 PR/MR 分支上,则切换到该分支。
Perforce:
# List pending changelists for current user/client
p4 changes -s pending -u $P4USER -c $P4CLIENT
# Describe a specific CL
p4 describe -s <CL_NUMBER>
继续操作前,请确保已设置正确的工作区(p4 client)。
主要字段差异:
- GitHub:
number、headRefName、headRefOid - GitLab:
iid、source_branch、sha - Perforce:变更列表编号、
P4CLIENT、已搁置的文件
2. 循环
重复以下周期。最多迭代 5 次,以避免无限循环。
A. 触发 Greptile 评审
推送/搁置最新更改(如果有):
GitHub/GitLab:
git push
Perforce:
# Re-shelve to update the shelved files for review
p4 shelve -f -c <CL_NUMBER>
推送/搁置后,等待检查开始:
sleep 5
GitHub — 发布新的触发评论前,检查 Greptile 是否已在运行:
GREPTILE_STATE=$(gh pr checks <PR_NUMBER> --json name,state | jq -r '.[] | select(.name | test("greptile"; "i")) | .state')
如果 Greptile 尚未运行(状态为 PENDING 或 IN_PROGRESS),则请求新的评审:
if [ "$GREPTILE_STATE" != "PENDING" ] && [ "$GREPTILE_STATE" != "IN_PROGRESS" ]; then
gh pr comment <PR_NUMBER> --body "@greptile review"
fi
然后轮询 Greptile 检查运行,直到完成:
HEAD_SHA=$(gh pr view <PR_NUMBER> --json headRefOid -q .headRefOid)
ATTEMPTS=0
MAX_ATTEMPTS=60
POLL_INTERVAL_SECONDS=10
while true; do
ATTEMPTS=$((ATTEMPTS + 1))
if [ "$ATTEMPTS" -gt "$MAX_ATTEMPTS" ]; then
echo "Timed out waiting for the Greptile check run after approximately 10 minutes." >&2
exit 1
fi
GREPTILE_CHECK=$(gh api "repos/{owner}/{repo}/commits/$HEAD_SHA/check-runs" \
--jq '.check_runs[] | select(.name | test("greptile"; "i"))' 2>/dev/null)
if [ -z "$GREPTILE_CHECK" ]; then
echo "Waiting for Greptile check to appear..."
sleep "$POLL_INTERVAL_SECONDS"
continue
fi
STATUS=$(echo "$GREPTILE_CHECK" | jq -r '.status // "completed"')
CONCLUSION=$(echo "$GREPTILE_CHECK" | jq -r '.conclusion // "pending"')
if [ "$STATUS" = "completed" ]; then
if [ "$CONCLUSION" = "success" ]; then
echo "Greptile check passed!"
else
echo "Greptile check completed with: $CONCLUSION"
fi
break
fi
echo "Waiting for Greptile... (status: $STATUS)"
sleep "$POLL_INTERVAL_SECONDS"
done
如果轮询超时,则停止 greploop 工作流并报告超时。不要继续使用过期或缺失的评审结果。
GitLab — 发布触发评论前,检查 Greptile 是否已在运行:
PIPELINES=$(glab api "projects/:fullpath/merge_requests/<MR_IID>/pipelines")
GREPTILE_RUNNING=$(echo "$PIPELINES" | jq '[.[] | select(.status == "running" or .status == "pending")] | length')
如果没有正在运行的流水线,则发布触发评论:
if [ "$GREPTILE_RUNNING" = "0" ]; then
glab mr note <MR_IID> --message "@greptile review"
fi
Perforce — Perforce 没有原生的检查运行。如果 Greptile 通过 p4 shelve 触发的 webhook 集成,请等待其处理。检查 Greptile 安装的 webhook 端点或仪表板,查看评审状态。通过重新获取 CL 上的 Greptile 评审评论进行轮询,直到出现评分。
然后轮询 Greptile 流水线作业,直到完成(参见 GitLab API 参考):
HEAD_SHA=$(glab mr view <MR_IID> --output json | jq -r '.sha')
ATTEMPTS=0
MAX_ATTEMPTS=60
POLL_INTERVAL_SECONDS=10
while true; do
ATTEMPTS=$((ATTEMPTS + 1))
if [ "$ATTEMPTS" -gt "$MAX_ATTEMPTS" ]; then
echo "Timed out waiting for the Greptile pipeline job after approximately 10 minutes." >&2
exit 1
fi
PIPELINES=$(glab api "projects/:fullpath/merge_requests/<MR_IID>/pipelines")
# Find the most recent pipeline for this SHA
PIPELINE_ID=$(echo "$PIPELINES" | jq -r --arg sha "$HEAD_SHA" \
'[.[] | select(.sha == $sha)] | sort_by(.id) | last | .id // empty')
if [ -z "$PIPELINE_ID" ]; then
echo "Waiting for Greptile pipeline to appear..."
sleep "$POLL_INTERVAL_SECONDS"
continue
fi
JOBS=$(glab api "projects/:fullpath/pipelines/$PIPELINE_ID/jobs")
GREPTILE_JOB=$(echo "$JOBS" | jq '.[] | select(.name | test("greptile"; "i"))')
if [ -z "$GREPTILE_JOB" ]; then
echo "Waiting for Greptile job to appear..."
sleep "$POLL_INTERVAL_SECONDS"
continue
fi
JOB_STATUS=$(echo "$GREPTILE_JOB" | jq -r '.status')
if [ "$JOB_STATUS" = "success" ] || [ "$JOB_STATUS" = "failed" ] || [ "$JOB_STATUS" = "canceled" ]; then
echo "Greptile job completed with: $JOB_STATUS"
break
fi
echo "Waiting for Greptile... (status: $JOB_STATUS)"
sleep "$POLL_INTERVAL_SECONDS"
done
如果轮询超时,则停止 greploop 工作流并报告超时。不要继续使用过期或缺失的评审结果。
B. 获取 Greptile 审查结果
Greptile 可能会在多个位置显示评分——请检查所有相关来源:
GitHub:
1. PR 描述(正文):
gh pr view <PR_NUMBER> --json body -q '.body'
2. 常规 PR 评论(议题评论):
gh api --paginate "repos/{owner}/{repo}/issues/<PR_NUMBER>/comments?per_page=100"
筛选 Greptile 撰写的评论,并使用最近更新的评论(updated_at)正文,而不是最近创建的评论。Greptile 可能会在每轮审查时编辑同一条常规 PR 评论;在确定没有剩余问题之前,请解析当前正文,包括“Prompt to fix all with AI”部分。
3. PR 审查:
gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/reviews
查找来自 greptile-apps[bot] 或 greptile-apps-staging[bot] 的最新条目。
GitLab:
1. MR 描述(正文):
glab mr view <MR_IID> --output json | jq -r '.description'
2. MR 备注(评论):
glab api "projects/:fullpath/merge_requests/<MR_IID>/notes"
筛选来自 Greptile 机器人用户的备注(检查 author.username 字段——确切用户名可能因安装而异;首次运行时请确认)。
Perforce:
1. CL 描述:
p4 describe -s <CL_NUMBER>
检查描述字段中是否有 Greptile 附加的评分块。
2. CL 评论/审查备注: 如果你的安装使用 Helix Swarm 等审查工具,请通过其 API 获取评论。
示例(Swarm API): GET /api/v11/comments?topic=reviews/<REVIEW_ID>
通常需要关注的响应字段包括:
- user(作者用户名)
- body(评论文本)
- 表示评论是否已解决的 flags/state
筛选由 Greptile 机器人撰写的评论:
- 如果知道确切用户名,优先使用精确匹配
- 否则,使用启发式方法:作者名称包含“greptile”(不区分大小写)
对于所有平台,请解析文本以获取:
- 置信度评分:类似
3/5或5/5(或Confidence: 3/5)的模式。 - 评论数:摘要中提到的行内审查评论数量。
使用最近更新的评分来源。在比较经过编辑的 Greptile 摘要与较早的审查条目时,GitHub 优先使用议题评论中的 updated_at。
同时获取所有未解决的行内评论:
GitHub:
gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments
即使行内评论端点返回零条未解决评论,也要保留最新 Greptile 常规 PR 评论中的可执行事项,尤其是“Prompt to fix all with AI”部分。
GitLab:
glab api "projects/:fullpath/merge_requests/<MR_IID>/discussions"
筛选来自 Greptile、属于 DiffNote 类型讨论(notes[0].type == "DiffNote")、位于最新提交上且尚未解决("resolved": false)的讨论。
Perforce: 如果使用 Swarm:
获取与 CL 关联的审查中的行内差异评论
GET /api/v11/comments?topic=reviews/<REVIEW_ID>
筛选来自 Greptile 机器人用户且尚未标记为已解决/已处理的评论。
C. 检查退出条件
满足以下任一条件时,停止循环:
- 置信度评分为 5/5 且没有未解决评论
- 达到最大迭代次数(报告当前状态)
D. 修复可执行评论
对于每条未解决的 Greptile 评论:
- 阅读文件并结合上下文理解评论。
- 判断评论是否可执行(需要更改代码)还是仅提供信息。
- 如果可执行,则进行修复。
- 如果仅提供信息或属于误报,请记录下来,但仍要解决该讨论串。
E. 解决讨论串
GitHub — 获取未解决的审查讨论串,并解决所有已处理的讨论串(参见 GraphQL 参考):
gh api graphql -f query='
query($cursor: String) {
repository(owner: "OWNER", name: "REPO") {
pullRequest(number: PR_NUMBER) {
reviewThreads(first: 100, after: $cursor) {
pageInfo { hasNextPage endCursor }
nodes {
id
isResolved
comments(first: 1) {
nodes { body path author { login } }
}
}
}
}
}
}'
解决已处理的讨论串:
gh api graphql -f query='
mutation {
t1: resolveReviewThread(input: {threadId: "ID1"}) { thread { isResolved } }
t2: resolveReviewThread(input: {threadId: "ID2"}) { thread { isResolved } }
}'
GitLab — 获取未解决的讨论,并逐一解决(参见 GitLab API 参考):
glab api "projects/:fullpath/merge_requests/<MR_IID>/discussions?per_page=100"
筛选 "resolved": false 的讨论。然后通过各自的 id 逐一解决:
glab api --method PUT \
"projects/:fullpath/merge_requests/<MR_IID>/discussions/<DISCUSSION_ID>" \
--field resolved=true
对每个未解决的讨论 ID 重复此操作。(GitLab 不支持批量解决——请逐一处理。)
F. 提交并推送/重新搁置
GitHub/GitLab:
git add -A
git commit -m "address greptile review feedback (greploop iteration N)"
git push
Perforce:
# Stage changes back into the CL and re-shelve for the next review round
p4 shelve -f -c <CL_NUMBER>
推送/搁置后,等待检查开始运行:
sleep 5
然后返回步骤 A。
3. 报告
退出循环后,汇总:
| 字段 | 值 |
|---|---|
| 平台 | GitHub / GitLab / Perforce |
| 迭代次数 | N |
| 最终信心度 | X/5 |
| 已解决的评论 | N |
| 剩余评论 | N(如有) |
如果因达到最大迭代次数而退出循环,请列出尚未解决的评论,并建议后续步骤。
输出格式
Greploop complete.
Platform: GitHub
Iterations: 2
Confidence: 5/5
Resolved: 7 comments
Remaining: 0
如果未完全解决:
Greploop stopped after 5 iterations.
Platform: GitLab
Confidence: 4/5
Resolved: 12 comments
Remaining: 2
Remaining issues:
- src/auth.ts:45 — "Consider rate limiting this endpoint"
- src/db.ts:112 — "Missing index on user_id column"
Perforce 示例:
Greploop complete.
Platform: Perforce
Changelist: 12345
Iterations: 3
Confidence: 5/5
Resolved: 9 comments
Remaining: 0