# Copilot Review&fix

> 現在のブランチに紐づくプルリクでCopilotレビューを起動し、指摘を修正して未ステージ状態で止める。

- Skill: `satoru314/copilot-review-fix` (Agent Skill)
- Install (CLI): `npx skillmds@latest add satoru314/copilot-review-fix`
- Raw SKILL.md: https://api.skillmd.com/api/skills/satoru314/copilot-review-fix/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Satoru314 (https://skillmd.com/u/satoru314)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/satoru314/copilot-review-fix

---


現在ブランチのPRで Copilot レビューを実行し、レビュー指摘を反映して未ステージ状態で完了する。

## 依存スキル
- `copilot-review-trigger`
- このスキルは Copilot 起動を自前実装せず、必ず `copilot-review-trigger` を実行してから後続処理に進む。

## 実行ポリシー（Codex環境）
- `gh` は `pr` サブコマンドを基本とする。Copilotのインライン指摘取得時のみ `gh api graphql`（読み取り専用）を使ってよい。
- このスキルは **サンドボックス解除時のみ** 実行する。`sandbox_permissions=require_escalated` や `prefix_rule` を使った昇格実行は行わない。
- サンドボックス有効のセッションでは `このスキルはサンドボックス解除時のみ実行可能です` と報告して停止する。
- このスキルはステージングしない。`git add` / `git commit` / `git push` は行わない。
- 既存のステージ状態は変更しない。`git restore --staged` / `git reset` でインデックスを操作しない。
- 変更混在を避けるときは「対象外ファイルを編集しない」ことで担保し、既存ステージを巻き戻さない。

## 手順

1. 前提確認（PR特定）
```bash
gh pr list --head "$(git branch --show-current)" --state open --json number,url --jq '.[0]'
```
- PRが取れない場合は `このブランチに紐づくPRがありません` と報告して停止する。

2. Copilotレビュー起動
- `copilot-review-trigger` スキルを実行して、レビューを起動する。

3. 新着Copilotレビュー到着待ち（ポーリング）
```bash
gh pr view <PR番号> --json reviews --jq '
  [.reviews[]
   | select(.author.login=="copilot-pull-request-reviewer")
   | .submittedAt]
  | max // ""'
```
- 起動前に「最新Copilotレビュー時刻（BASE_SUBMITTED_AT）」を取得して保存する。
- 起動後は30秒間隔で確認し、`submittedAt > BASE_SUBMITTED_AT` の新着レビューが出るまで最大20分待機する。
- 新着レビューが無く、既存レビューしかない場合は「未到着」として待機継続する。
- 20分以内に新着レビューが到着しない場合は `copilotレビューがタイムアウトしました: <PR URL>` と報告して停止する。

4. Copilotレビュー本文の取得（概要）
```bash
gh pr view <PR番号> --json reviews --jq '
  [.reviews[]
   | select(.author.login=="copilot-pull-request-reviewer")
   | {submittedAt, body}]
  | sort_by(.submittedAt)
  | last'
```
- ここで得られるのは概要メッセージのことがある。

5. Copilotのインライン指摘（実作業用）を取得
```bash
gh api graphql -f query='
query($owner:String!, $name:String!, $number:Int!){
  repository(owner:$owner,name:$name){
    pullRequest(number:$number){
      reviewThreads(first:50){
        nodes{
          isResolved
          comments(first:20){
            nodes{
              author{login}
              body
              path
              outdated
              createdAt
            }
          }
        }
      }
    }
  }
}' -f owner="<owner>" -f name="<repo>" -F number=<PR番号>
```
- `author.login=="copilot-pull-request-reviewer"` のコメントだけを対象にする。
- `createdAt >= BASE_SUBMITTED_AT` で今回実行ぶんを優先する。
- `[must]` / `[ask]` / `[nits]` を優先度として扱う（`must` を必須対応）。

6. 修正実装と検証
- 指摘内容に基づいてコードを修正する。
- 影響範囲に応じて最低限の確認を行う（例: `npm run typecheck`, `npm run test`）。
- コマンド失敗時は代替手段を試し、代替不能なら失敗理由を報告して停止する。

7. 結果報告
- 以下を簡潔に報告する。
  - 取得したCopilotレビュー要点
  - 実施した修正概要
  - 変更したファイル一覧（未ステージ）
  - 未対応項目（あれば）

## 実行用コマンド例

```bash
if [ "${CODEX_SANDBOX_MODE:-}" != "danger-full-access" ]; then
  echo "このスキルはサンドボックス解除時のみ実行可能です"
  exit 0
fi

REMOTE_URL=$(git remote get-url origin 2>/dev/null || true)
REPO=$(printf '%s\n' "$REMOTE_URL" \
  | sed -E 's#^git@github.com:##; s#^https://github.com/##; s#\.git$##')

if [ -z "$REPO" ] || [ "$REPO" = "$REMOTE_URL" ] || ! printf '%s' "$REPO" | grep -Eq '^[^/]+/[^/]+$'; then
  echo "origin からGitHubリポジトリを特定できませんでした"
  exit 1
fi

BRANCH=$(git branch --show-current)
PR_NUMBER=$(gh pr list -R "$REPO" --head "$BRANCH" --state open --json number --jq '.[0].number // empty')
PR_URL=$(gh pr list -R "$REPO" --head "$BRANCH" --state open --json url --jq '.[0].url // empty')

if [ -z "$PR_NUMBER" ] || [ "$PR_NUMBER" = "null" ]; then
  echo "このブランチに紐づくPRがありません"
  exit 0
fi

# 0) baseline
BASE_SUBMITTED_AT=$(gh pr view -R "$REPO" "$PR_NUMBER" --json reviews --jq '
  [.reviews[]
   | select(.author.login=="copilot-pull-request-reviewer")
   | .submittedAt]
  | max // ""')

# 1) trigger (copilot-review-trigger を使う想定)
gh pr edit -R "$REPO" "$PR_NUMBER" --add-reviewer "copilot-pull-request-reviewer" >/dev/null

# 2) wait
FOUND=0
for _ in $(seq 1 40); do
  LATEST_SUBMITTED_AT=$(gh pr view -R "$REPO" "$PR_NUMBER" --json reviews --jq '
    [.reviews[]
     | select(.author.login=="copilot-pull-request-reviewer")
     | .submittedAt]
    | max // ""')
  if [ -n "$LATEST_SUBMITTED_AT" ] && [ "$LATEST_SUBMITTED_AT" != "$BASE_SUBMITTED_AT" ]; then
    FOUND=1
    break
  fi
  sleep 30
done

if [ "$FOUND" -ne 1 ]; then
  echo "copilotレビューがタイムアウトしました: $PR_URL"
  exit 1
fi

gh pr view -R "$REPO" "$PR_NUMBER" --json reviews --jq '
  [.reviews[]
   | select(.author.login=="copilot-pull-request-reviewer")
   | {submittedAt, body}]
  | sort_by(.submittedAt)
  | last'

gh api graphql -f query='
query($owner:String!, $name:String!, $number:Int!){
  repository(owner:$owner,name:$name){
    pullRequest(number:$number){
      reviewThreads(first:50){
        nodes{
          comments(first:20){
            nodes{
              author{login}
              body
              path
              createdAt
            }
          }
        }
      }
    }
  }
}' -f owner="${REPO%/*}" -f name="${REPO#*/}" -F number="$PR_NUMBER"
```

## 注意
- レビュー本文の適用は盲従しない。破壊的変更や仕様変更は除外する。
- 同一ブランチで複数回実行する場合、既存レビューと新着レビューを `submittedAt` と `createdAt` で区別する。
- このスキルはステージングしない。変更は作業ツリーに残す。
- 既にステージ済みの変更があっても、その状態は保持する（解除しない）。

