mcpField
G
greploop

greploop

github.com/greptileaiテスト・品質4282.7k 回インストール2 日前に更新
リポジトリ

greploop について

Greploopは、PR、MR、またはPerforce changelistに対するGreptileのレビュー指摘を、最大5回の反復で解消するスキルです。プラットフォームを判定し、レビュー結果の取得、対応可能な指摘の修正、最終状況の報告を行います。

主な機能

  1. 01GitHub、GitLab、Perforceの判定
  2. 02レビュー対象の変更の特定
  3. 03Greptileレビューの実行と確認
  4. 04対応可能なレビュー指摘の修正
  5. 05対応済みディスカッションの解決
  6. 06信頼度と未解決指摘の報告

活用シーン

  1. 01GitHub PRのレビュー指摘への対応
  2. 02GitLab MRのGreptile指摘への対応
  3. 03Perforce changelistレビューの反復
  4. 04未解決指摘とレビュー信頼度の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/greptileai/skills --skill greploop

インストール後、Claude Code で/greploopを入力して読み込まれたか確認します。

同梱ファイルreferences/gitlab-api.mdreferences/graphql-queries.md

詳細

Greploop

Greptile のレビューで完璧な評価(信頼度 5/5、未解決コメントゼロ)が得られるまで、PR/MR/CL を繰り返し修正します。

入力

  • PR/MR/CL 番号(任意):指定されていない場合は、現在のブランチの PR/MR、または p4 のデフォルトの保留中チェンジリストを検出します。

手順

0. プラットフォームを検出する

まず Perforce を確認し、該当しない場合は git のリモート検出に切り替えます。

# 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 にはネイティブのチェック実行機能がありません。p4 shelve で起動する Webhook を介して Greptile が統合されている場合は、処理が完了するまで待ちます。レビューのステータスは、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 の一般コメント(Issue コメント):

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)のようなパターン。
  • コメント数:要約に記載されたインラインレビューコメントの数。

スコアが最も最近更新された情報源を使用してください。GitHub では、編集された Greptile の要約と古いレビューエントリーを比較する際、Issue コメントの updated_at を優先してください。

未解決のインラインコメントもすべて取得します。

GitHub:

gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments

インラインコメントのエンドポイントから未解決のコメントが 0 件返された場合でも、最新の Greptile の一般的な PR コメントから、特に「Prompt to fix all with AI」セクションの対応項目を引き継いでください。

GitLab:

glab api "projects/:fullpath/merge_requests/<MR_IID>/discussions"

最新のコミットに紐づき、まだ解決されていない("resolved": false)Greptile の DiffNote 型のディスカッション(notes[0].type == "DiffNote")に絞り込みます。

Perforce: Swarm を使用している場合:

CL に関連付けられたレビューのインライン差分コメントを取得

GET /api/v11/comments?topic=reviews/<REVIEW_ID>

Greptile ボットユーザーによるもので、解決済み/対応済みとマークされていないコメントに絞り込みます。

C. 終了条件を確認する

次のいずれかに該当する場合、ループを停止します。

  • 信頼度スコアが 5/5 で、未解決のコメントが 0 件
  • 最大反復回数に達した場合(現在の状態を報告)
D. 対応が必要なコメントを修正する

未解決の Greptile コメントごとに、次の手順を実行します。

  1. ファイルを読み、コメントの文脈を把握します。
  2. 対応が必要か(コード変更が必要か)、それとも情報提供のみかを判断します。
  3. 対応が必要な場合は修正します。
  4. 情報提供のみの場合や誤検出の場合は、その旨を記録したうえでスレッドを解決します。
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 には一括解決機能がないため、1 件ずつ処理します。)

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

コメント