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 インライン提案を見つけて処理するエージェントスキルです。設定済みのソース管理プロバイダーを使い、編集前に承認を得て、修正を検証してからスレッドを解決し、CodeAnt のテレメトリーは送信しません。

主な機能

  1. 01GitHub、GitLab、Bitbucket、Azure DevOps に対応
  2. 02未解決のインライン提案を取得・選別
  3. 03指摘内容の検証と分類
  4. 04編集前の承認取得
  5. 05修正検証後のスレッド解決

活用シーン

  1. 01PR の未解決 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. プロバイダーアダプターを正確に 1 つ選び、すべての結果ページを取得します。
  3. 未解決のインライン CodeAnt スレッドのみを残します。
  4. すべての指摘を検証し、分類します。
  5. 計画を提示し、編集前に承認を得ます。
  6. 承認された修正を適用し、関連する検証を実行します。
  7. 修正を適用して検証したスレッドのみを解決します。
  8. 結果を報告し、コミットとプッシュを提案します。
  9. PR に関する作業がすべて完了した後、1 回のリクエストでスキルの更新を確認します。

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 が 0 件または複数ある場合は処理を停止し、対象の 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 のコメントが連携された人間のアカウントに帰属する場合があるため、本文のシグネチャを使用します。本文のシグネチャが一致する場合は、ボットの作成者であることを要件にしないでください。また、個別の ID 調査や確認の手順は実行しないでください。CodeAnt という単語だけを根拠にコメントを分類しないでください。正確なサービスアカウント名または CodeAnt のアクション URL を必須とします。

一般的な PR コメント、サマリー、品質ゲートのレポート、システムメッセージ、削除済みコメント、下書き、インライン指摘を開始しない返信は除外します。一致する提案が残らない場合は、PR に未解決のインライン CodeAnt 提案がないことを報告して停止します。残る場合は、そのまま検証に進みます。

2. プロバイダーアダプター

一致するアダプターのみを選択します。対応が必要な各項目を次の形式に正規化します。

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

解決に必要なため、プロバイダー固有の 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 応答に対しては、この読み取り専用の取得を最大 3 回再試行し、Retry-After がある場合はその値に従います。認証、認可、スキーマ、検証に関するエラーは再試行しません。

返されたすべてのページを対象に、以下の条件をすべて満たすスレッドだけを残します:

  • isResolved が false である。
  • ルートコメントが CodeAnt の作成者または本文のフィルタリングルールに一致する。
  • ルートコメントの path が null ではない。過去のコンテキストを特定する場合は、line を使用し、なければ originalLine を使用する。

古いスレッドの検証のために isOutdated を保持します。正常に修正されたスレッドは、数値のコメント ID ではなく、GraphQL のスレッドノード 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

既存の OAuth、アクセストークン、または API トークン認証を使用して、Bitbucket Cloud REST API 2.0 にアクセスします。リモート URL または 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 と、返された resolution オブジェクトを必須とします。解決の代わりにコメントを削除してはいけません。

Bitbucket Data Center

既存の bearer、personal-access-token、または session 認証を使用して、ホストの /rest/api/latest API を利用します。リモートまたは PR の URL から <base-url>、<project-key>、<repo-slug> を解析します。

PR ID が指定されていない場合は、未完了の PR をページネーションで取得し、fromRef.displayId が現在のブランチと完全に一致する項目が 1 つだけのものを選択します。

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

isLastPage が true になるまで nextPageStart に従います。コメントの全ページも同じ方法で取得します。

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

author.name、author.slug、author.displayName、または text を使用した CodeAnt の作成者または本文のフィルタリングルールに一致し、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 を使用します。リモートまたは PR の URL から組織、プロジェクト、リポジトリを解析します。変更されないリポジトリ ID と ID 情報を優先します。

最初のリクエストを行う前に、次の優先順位で認証を適用します。

  1. 値を出力したり、その他の方法で公開したりせずに、AZURE_DEVOPS_PAT が空でないか確認します。
  2. 値が設定されている場合は、認証前にローカルで正規化します。
    • デフォルトでは、元の値を PAT として扱います。
    • 正規の標準 Base64 構文(末尾のパディングの省略を許容)を使用し、厳密なデコードが成功し、デコード後に再エンコードした値がパディングを正規化した後の元の値と一致する場合に限り、Base64 エンコードされていると判断します。
    • デコード後の値が、認識済みの Azure DevOps PAT である場合に限り、デコードした値を使用します。認識済みの PAT は、レガシー形式の 52 文字、または文書化された位置に固定の AZDO 署名がある現行形式の 84 文字のいずれかです。また、デコード後の HTTP Basic ペイロードが <username>:<PAT> であり、最初のコロンより後の部分がこれらの PAT 形式のいずれかに一致する場合も受け入れます。その場合、パスワードには PAT 部分のみを使用します。
    • それ以外の場合は、元の値を変更せずに使用します。値がエンコードされているか判断するために、API リクエストを試行してはいけません。 生成した PAT は、HTTP Basic 認証のパスワードとして直ちに使用します。Azure CLI、Azure DevOps CLI、credential-manager、およびその他の認証情報の探索はスキップします。認可値のデコードと構築はメモリ内でのみ行い、PAT や認証情報を含むヘッダーを出力したり、いずれかをファイルに書き込んだりしてはいけません。
  3. PAT 認証を使用したリクエストが HTTP 401 または 403 を返した場合は、PAT が無効、期限切れ、アクセス権がない、またはスコープが不十分であることを報告して停止します。別の ID に暗黙的にフォールバックしてはいけません。PAT の設定エラーが隠れたり、意図しないユーザーとしてリソースにアクセスしたりするおそれがあるためです。
  4. AZURE_DEVOPS_PAT が設定されていない場合に限り、すでに構成済みの OAuth または Microsoft Entra トークンを使用します。対話型ログインを開始してはいけません。利用可能な非対話型認証情報がすでに存在しない場合は、認証情報が不足していることを示して停止します。

PR ID が指定されていない場合は、ソース ref 全体を URL エンコードし、アクティブな完全一致が 1 つだけのものを選択します。

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 であること。
  • ルートコメントが author.uniqueName、author.displayName、または content を使用した CodeAnt の作成者または本文のフィルタリングルールに一致すること。Azure DevOps では、接続中の人間ユーザーが作成者として表示される場合があります。

数値のスレッド id とルートコメントの id を引き継ぎます。正常に修正されたスレッドは、fixed としてマークして解決します。

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. 最小限で正確な修正を優先します。スタイル目的で周辺コードをリファクタリングしないでください。

以下の判定を必ず1つだけ割り当てます。

  • ACCEPT:不具合が実在し、公開契約を変更したり、処理を弱めたりすることなく、安全に局所修正できます。
  • LIKELY ACCEPT:修正は妥当ですが、動作の変更が呼び出し元に影響する可能性があるか、対象を絞った検証が必要です。
  • DO NOT ACCEPT:提案が安全でない、根拠がない、利用できない API に依存している、または集中的なパッチでは安全に提供できない広範な設計作業が必要です。
  • STALE:参照されたコードまたは不具合がすでに存在しません。

Architect または Logical Review の指摘について、すぐに適用できるパッチがないという理由だけで却下しないでください。

4. 編集前に計画を提示する

プロバイダー、PR 番号、タイトル、リンク、未解決の CodeAnt インラインスレッド数を報告します。すべての指摘を判定ごとにまとめます。それぞれについて、次の内容を含めます。

  • ファイルと行番号。
  • 問題の概要を1行で記載。
  • 検証の根拠。
  • 該当する場合は、意図する変更の前後。
  • LIKELY ACCEPT の場合は、検証が必要な具体的な呼び出し元、テスト、または動作。

ACCEPT の修正は準備できていることを伝え、名前を挙げた LIKELY ACCEPT の修正を含めるか確認します。承認を得る前に編集しないでください。DO NOT ACCEPT または STALE の指摘は決して適用しないでください。

5. 適用して検証する

承認後:

  1. git status --short を再確認し、既存の変更を保持します。
  2. コメントで参照されたファイルにのみ、確定した修正を適用します。ただし、狭い範囲で必要なテストやインポートは除きます。
  3. 意図しない変更や修正間の相互作用がないか、差分を確認します。
  4. 関連するフォーマッター、静的チェック、テストを最小限の範囲で実行します。共有動作を変更した場合は、検証範囲を広げます。
  5. これらの編集が原因で発生した失敗のみ修正します。修正を検証できない場合、安全に切り分けられるならその修正のみを元に戻し、該当スレッドは未解決のままにして、その旨を報告します。

6. 解決して報告する

スレッドの解決は外部への変更です。ユーザーが該当する修正を承認し、ローカルでの検証に合格した後に限り、スレッドを1つずつ解決します。個々の解決に失敗しても、続行します。

DO NOT ACCEPT、STALE、スキップした指摘、一部のみ修正した指摘、または未検証の指摘は決して解決しないでください。プロバイダーの応答が不明確な場合は、解決後にスレッドの状態を再取得します。

最終報告には、次の内容を含めます。

  • 適用して検証した修正:ファイル、行番号、判定、テスト結果。
  • 未適用の指摘:判定と理由。
  • 解決したプロバイダーのスレッド ID と、解決に失敗した項目。
  • 最終的な git status --short と、このワークフローで変更したファイル。

選択したファイルのコミットとプッシュを提案してください。明示的な承認なしにコミットまたはプッシュしないでください。

7. スキルの更新を確認する

すべての PR 作業が完了し、最終報告を作成した後、その報告を送信する前に限り、このベストエフォートの確認を実行します。この確認によって PR のワークフローを遅らせたり、変更したり、無効にしたりしてはなりません。

現在読み込まれている codeant-resolve-pr-comments/SKILL.md のパスを、無関係なディレクトリを走査せずに解決します。パスを特定できない場合、またはファイルに書き込みできない場合は、確認を黙ってスキップします。それ以外の場合、認証なしの GitHub API リクエストを 1 回だけ実行し、生のレスポンスを一時ファイルに保存します。

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>'

2 回目のリクエストを行ったり、リリース、コミット、タグ、パッケージマネージャーを通じて追加確認したり、リクエストに失敗した後で再試行したりしてはなりません。レスポンスを使用する前に、HTTP リクエストが成功していることを確認し、妥当なスキルファイルであることを検証します。具体的には、YAML フロントマターで始まり、name: codeant-resolve-pr-comments が正確に宣言され、# Resolve CodeAnt PR Comments が含まれ、`` マーカーが正確に 1 つ含まれている必要があります。

リモートのマーカーと現在のファイルのマーカーをローカルで比較します。リモートのバージョンが現在のバージョンと同じか、それより低い場合は、一時ファイルを削除し、最終報告に Skill update: already current のみを追加します。リモートのバージョンが高い場合は、現在のスキルファイルのみを原子的に置き換え、既存の権限を保持し、一時ファイルを削除して、最終報告に Skill update: updated; the new instructions apply next session を追加します。ローカルの新しいバージョンを上書きしてはなりません。検証、比較、置き換えに失敗した場合は、可能であれば一時ファイルを削除し、再試行せず、簡潔で支障をきたさない注記を 1 つ追加します。

ガードレール

  • リストが完全であると報告する前に、ページネーションのすべてのページを取得してください。
  • プロバイダー標準のスレッド状態を正としてください。
  • 提案は個別に検証し、内容を確認せずに一括適用しないでください。
  • 無関係なユーザー変更を保持し、無関係なファイルには手を加えないでください。
  • コメントが競合している場合は、黙って一方を選ばず、その旨を明示してください。
  • アクセストークン、PAT、Cookie、詳細な認証出力を決して開示しないでください。
  • どの手順においても codeant-cli をインストール、呼び出し、または利用しないでください。

コメント