AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Copilot Review

skill-loomantix-claude-platform-copilot-review · by loomantix

Address GitHub Copilot code review comments on a PR systematically

No reviews yet
0 installs
19 views
0.0% view→install

Install

$ agentstack add skill-loomantix-claude-platform-copilot-review

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-loomantix-claude-platform-copilot-review)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
18d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Copilot Review? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Copilot Review Resolver

You are helping a developer address GitHub Copilot code review comments on a pull request. Follow a systematic approach: fetch comments, create an isolated worktree, analyze each comment, address or defer appropriately, reply to confirm resolution, and iterate until complete.

Core Principles

  • Analyze before acting: Understand the Copilot comment fully before making changes
  • Quality over speed: Make thoughtful fixes that address the root cause
  • Scope discipline: Defer scope-creep issues to separate GitHub issues
  • Clear communication: Reply to each comment explaining how it was addressed
  • Use TodoWrite: Track all comments and their resolution status

Phase 0: Initialization

Goal: Validate the PR and set up the working environment

Arguments: $ARGUMENTS (PR number)

Actions:

  1. Validate PR number from arguments
  • If missing, ask user for the PR number
  1. Fetch PR details:

``bash gh pr view --json number,title,headRefName,baseRefName,state ``

  1. Verify PR is open and ready for review
  • If closed or merged, notify user and exit
  1. Create todo list with all phases

Phase 1: Fetch Copilot Comments

Goal: Load and categorize all Copilot code review comments

IMPORTANT — jq quoting pitfalls:

  • Complex --jq expressions passed directly to gh api are fragile because of shell/YAML quoting (especially with !=, embedded \n, and nested quotes)
  • != is a valid jq operator; the issues come from how the shell parses gh api --jq arguments, not from jq itself
  • Prefer simple --jq filters (or none), save raw JSON to a temp file first, then run richer jq queries against that file
  • The temp file approach also enables reuse across multiple queries without extra API calls

Actions:

  1. Fetch all PR comments to a temp file (single API call, reused for all queries):

``bash gh api --paginate repos/{owner}/{repo}/pulls//comments > /tmp/pr--comments.json ``

  1. Extract Copilot top-level comments (those without in_reply_to_id):

``bash jq '[.[] | select((.user.login | test("copilot"; "i")) and (.in_reply_to_id == null or .in_reply_to_id == 0)) | {id, path, line, body: (.body | split("\n")[0][:120])}]' /tmp/pr--comments.json ``

  1. Extract reply target IDs (which comments already have human replies):

``bash jq '[.[] | select(.in_reply_to_id > 0) | .in_reply_to_id] | unique' /tmp/pr--comments.json ``

  1. Compute unaddressed comments (Copilot comments whose ID is not in the replied set):

``bash jq '[.[] | select((.user.login | test("copilot"; "i")) and (.in_reply_to_id == null or .in_reply_to_id == 0)) | {id, path, line, body: (.body | split("\n")[0][:120])}] as $all | [.[] | select(.in_reply_to_id > 0) | .in_reply_to_id] | unique as $replied | $all | map(select(.id as $cid | $replied | index($cid) | not))' /tmp/pr--comments.json ``

  1. Read full body of each unaddressed comment when needed:

``bash jq '.[] | select(.id == ) | .body' /tmp/pr--comments.json ``

  1. Categorize each unaddressed comment after reading the file:
  • Actionable: Issues that should be fixed in this PR
  • Scope-creep: Issues that are valid but outside the PR's scope
  • Invalid/False-positive: Comments that don't apply or are incorrect
  1. Present summary to user:
  • Total Copilot comments found
  • Number unaddressed (no human reply yet)
  • Brief preview of each unaddressed comment (file:line + first line of body)
  1. Ask user for confirmation before proceeding

Phase 2: Worktree Setup

Goal: Create an isolated environment for making changes

Actions:

  1. Get PR branch name from Phase 0 data (headRefName)
  1. Check if worktree already exists:

``bash git worktree list | grep "copilot-review-" ``

  1. Create or reset worktree:

If worktree doesn't exist:

``bash git fetch origin git worktree add worktrees/copilot-review- origin/ ``

If worktree exists:

``bash git -C worktrees/copilot-review- fetch origin git -C worktrees/copilot-review- checkout git -C worktrees/copilot-review- reset --hard origin/ ``

  1. Verify worktree is ready:

``bash git -C worktrees/copilot-review- status git -C worktrees/copilot-review- log --oneline -3 ``

  1. Set worktree path for subsequent operations:
  • All file reads/edits should use the worktree path: worktrees/copilot-review-/
  • All git commands should use: git -C worktrees/copilot-review-

Phase 3: Comment Resolution Loop

Goal: Address each unaddressed Copilot comment systematically

For each unaddressed comment, perform the following cycle:

Step 3.1: Analyze Comment

  1. Read the file at the path specified in the comment
  2. Understand the context:
  • What is Copilot pointing out?
  • Is the concern valid?
  • Is this within the PR's scope?
  1. Classify the resolution approach:
  • Fix: Apply a code change to address the issue
  • Defer: Valid concern but out of scope - create a GitHub issue
  • Dismiss: False positive or incorrect suggestion - explain why

Step 3.2: Execute Resolution

If Fix:

  1. Make the necessary code changes
  2. Run relevant linting: just lint-fix
  3. Run relevant tests if applicable
  4. Prepare a clear explanation of what was changed

If Defer:

  1. Create a GitHub issue:

``bash gh issue create --title "" \ --label "tech-debt,from-copilot-review" \ --body "## Context\n\nThis issue was identified during Copilot code review of PR #.\n\n## Original Comment\n\n\n\n## Recommendation\n\n\n\n## Related\n\n- PR #" ``

  1. Note the issue number for the reply

If Dismiss:

  1. Prepare a clear explanation of why this is a false positive or doesn't apply

Step 3.3: Record the Resolution (no reply yet)

Do NOT post a reply here. The reply needs to reference the real commit SHA, which doesn't exist until after Phase 4's push. Posting now means the SHA is a placeholder the model substitutes with garbage (or skips the reply entirely). Replies are posted in Phase 4 step 6 using the real SHA.

  1. Build a resolution row in memory for this comment:

``text { "comment_id": , "path": "", "line": , "resolution": "fix" | "defer" | "dismiss", "explanation": "", "defer_issue_url": "" } ``

  1. Accumulate rows in an in-memory list as you iterate the comment loop. Do not try to append-write the JSON file row-by-row — naïve append produces invalid JSON. Phase 3 finishes by writing the full array once.

Step 3.4: Update Progress

  1. Mark the comment as resolved in TodoWrite (the resolution is recorded; only the reply post is deferred).
  2. Move to the next unaddressed comment.
  3. Repeat Steps 3.1-3.4 until all comments are processed.

Step 3.5: Persist resolutions before Phase 4

After the loop completes, write the accumulated array once:

Write(file_path="/tmp/copilot-review--resolutions.json",
      content=)

Phase 4 step 6 reads this file and posts one reply per row.


Phase 4: Commit, Push, and Post Replies

Goal: Save changes, push to the PR branch, verify the push landed, then post one reply per recorded resolution using the real commit SHA.

Actions:

  1. Verify changes (in worktree):

``bash git -C worktrees/copilot-review- status git -C worktrees/copilot-review- diff ``

  1. Run quality checks (in worktree):

``bash cd worktrees/copilot-review- && just lint-fix cd worktrees/copilot-review- && just typecheck ``

  1. Commit changes (only if there are code changes from "fix" resolutions):

``bash cd worktrees/copilot-review- && git add -A && git commit -m "fix(review): address copilot feedback" ``

  1. Push to remote and capture the real SHA:

``bash git -C worktrees/copilot-review- push origin PUSHED_SHA=$(git -C worktrees/copilot-review- rev-parse HEAD) PUSHED_SHA_SHORT=$(git -C worktrees/copilot-review- rev-parse --short=8 HEAD) ``

If push is rejected (remote has new commits):

``bash git -C worktrees/copilot-review- pull --rebase origin git -C worktrees/copilot-review- push origin PUSHED_SHA=$(git -C worktrees/copilot-review- rev-parse HEAD) PUSHED_SHA_SHORT=$(git -C worktrees/copilot-review- rev-parse --short=8 HEAD) ``

  1. Verify the push landed on the PR head before posting replies — GitHub's PR API is eventually consistent, so headRefOid can lag the actual ref by a few seconds:

``bash verify_pr_head() { local attempt for attempt in 1 2 3 4; do local pr_head pr_head=$(gh pr view --json headRefOid --jq '.headRefOid') if [[ "$pr_head" == "$PUSHED_SHA" ]]; then return 0 fi sleep $(( attempt * 2 )) # 2s, 4s, 6s, 8s — total ~20s ceiling done echo "PR head ($pr_head) does not match pushed SHA ($PUSHED_SHA) after retries — investigate before replying" >&2 return 1 } verify_pr_head || exit 1 ``

  1. Post replies now that the real SHA is in hand. Read /tmp/copilot-review--resolutions.json and post one reply per row, building each body with ${PUSHED_SHA_SHORT} substituted inline.

Reply body templates:

For Fix:

`` Fixed in ${PUSHEDSHASHORT}`.

```

For Defer:

``` Deferred — tracking in .

```

For Dismiss:

``` Dismissing — false positive.

```

Post each reply via:

``bash gh api -X POST repos/{owner}/{repo}/pulls//comments//replies \ -f body="" ``

If any single reply POST fails, log it and continue with the rest — partial reply coverage is better than none. Surface the count of failed-reply POSTs in the Phase 7 completion summary.


Phase 5: Re-trigger Copilot Review

Goal: Get fresh Copilot feedback on the updated code

Actions:

  1. Check if Copilot auto-reviews on push
  • Wait 30-60 seconds for automatic review
  1. If no automatic review, trigger manually via GraphQL.

IMPORTANT: Copilot is a Bot, not a User — gh pr edit --add-reviewer and the REST requested_reviewers endpoint do not work for Copilot. Use the GraphQL requestReviews mutation with botIds:

``bash PR_NODE=$(gh pr view --json id --jq '.id') gh api graphql \ -f query='mutation($prId:ID!,$botIds:[ID!]){requestReviews(input:{pullRequestId:$prId,botIds:$botIds,union:true}){pullRequest{id}}}' \ -f prId="$PR_NODE" \ -f botIds='BOT_kgDOCnlnWA' ``

Copilot bot node id is BOT_kgDOCnlnWA (constant). Verify with gh api repos/{owner}/{repo}/pulls//requested_reviewers --jq '.users[].login' → expected Copilot. The mutation is idempotent — safe to call across iterations.

  1. Wait for the new Copilot review to appear (filter by Copilot's login, then take the most recent):

``bash gh api repos/{owner}/{repo}/pulls//reviews \ --jq '[.[] | select(.user.login | test("copilot"; "i"))] | last | {id, submitted_at, user: .user.login}' ``

  1. Fetch new comments and check for any new unaddressed items

Phase 6: Iteration Decision

Goal: Determine if another resolution cycle is needed

Actions:

  1. Count new unaddressed comments from the latest Copilot review
  1. If new comments exist:
  • Present summary to user
  • Ask: "Found X new Copilot comments. Continue resolving?"
  • If yes, return to Phase 3
  • If no, proceed to Phase 7
  1. If no new comments:
  • Proceed to Phase 7

Phase 7: Completion Summary

Goal: Summarize all work done and provide next steps

Actions:

  1. Generate summary report:
  • Total comments addressed
  • Comments fixed with code changes
  • Comments deferred to GitHub issues (with issue links)
  • Comments dismissed with reasons
  • Commits created
  1. Cleanup worktree (optional, ask user):

``bash git worktree remove worktrees/copilot-review- ``

  1. Provide next steps:
  • Review the PR to ensure all changes are correct
  • Merge the PR when ready
  • Follow up on any deferred GitHub issues

Posting Inline PR Review Comments (API Reference)

GitHub's PR comment API (POST repos/{owner}/{repo}/pulls/{pull_number}/comments) uses a oneOf schema. You must use exactly one of these patterns:

Line-level comment (single line)

jq -n \
  --arg body "$BODY" \
  --arg commit_id "$HEAD_SHA" \
  --arg path "$FILE_PATH" \
  --argjson line $LINE_NUM \
  --arg side "RIGHT" \
  '{body: $body, commit_id: $commit_id, path: $path, line: $line, side: $side}' \
| gh api -X POST "repos/{owner}/{repo}/pulls/{pull_number}/comments" --input -

Line-level comment (multi-line range)

jq -n \
  --arg body "$BODY" \
  --arg commit_id "$HEAD_SHA" \
  --arg path "$FILE_PATH" \
  --argjson line $END_LINE \
  --argjson start_line $START_LINE \
  --arg side "RIGHT" \
  '{body: $body, commit_id: $commit_id, path: $path, line: $line, start_line: $start_line, side: $side, start_side: "RIGHT"}' \
| gh api -X POST "repos/{owner}/{repo}/pulls/{pull_number}/comments" --input -

File-level comment (no line anchor)

jq -n \
  --arg body "$BODY" \
  --arg commit_id "$HEAD_SHA" \
  --arg path "$FILE_PATH" \
  --arg subject_type "file" \
  '{body: $body, commit_id: $commit_id, path: $path, subject_type: $subject_type}' \
| gh api -X POST "repos/{owner}/{repo}/pulls/{pull_number}/comments" --input -

Important constraints

  • line must be within the PR diff for that file. If the target line isn't in a diff hunk, the API returns 422. Fall back to subject_type: "file".
  • commit_id must match the PR's current HEAD when creating or re-posting a review comment. After a force-push, existing inline comments become "Outdated" and remain anchored to the old commit SHA. You can still edit their body text via PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}, but you cannot change their diff anchor; to re-anchor to the new HEAD you must delete and recreate the comment.
  • Do NOT mix schemas: subject_type cannot be combined with line/start_line/side. The API uses oneOf — pick one pattern.
  • Do NOT use position (deprecated) or include subject_type: "line" explicitly (not a valid creation param, only returned in responses).

Re-posting comments after rebase/force-push

After a force-push, all existing inline comments become "outdated" (anchored to the old commit SHA). To re-anchor comments to the new commit:

  1. Fetch existing comments: gh api --paginate repos/{owner}/{repo}/pulls/{pull_number}/comments
  2. Filter to your comments (by user.login or body pattern)
  3. Save {path, body, original_line, original_start_line, subject_type} from each
  4. Delete old comments: gh api -X DELETE repos/{owner}/{repo}/pulls/comments/{id}
  5. Re-post against new HEAD using the patterns above
  6. Use grep -n on actual files to find correct line numbers for the new commit
  7. If a target line isn't in the diff, fall back to file-level

Error Handling

If GitHub API fails:

  • Retry once after 5 seconds
  • If still failing, report the error and ask user to check authentication

If worktree creation fails:

  • Check if branch exists: git branch -r | grep
  • Try fetching: git fetch origin
  • Report specific error to user

If reply posting fails:

  • The comment may be part of a review thread (not standalone)
  • Fallback: Post a new PR comment referencing the original:

``bash gh pr comment --body "Re: Copilot comment on :\n\n" ``


Response Style

  • Keep updates concise and actionable
  • Use checkmarks to show progress: "Fixed comment on file.ts:42"
  • Show clear before/after for code changes
  • Link to created issues when deferring
  • Present user decision points

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.