From engineering
Address unresolved PR review feedback end-to-end — fetch inline review-thread and top-level comments (from any author — copilot, human reviewers, other bots), triage each with the user, validate and apply fixes, lint, test, commit/amend, push, and post threaded replies. Use when asked to "address PR comments", "fix review feedback", "respond to bugbot", "reply to PR comments", "address review feedback", or "triage PR review findings".
How this skill is triggered — by the user, by Claude, or both
Slash command
/engineering:fix-pr-feedback [PR-number-or-URL][PR-number-or-URL]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Fetch unresolved review feedback on a PR — from any author, including copilot, human reviewers, or other automation — triage each item with the user, validate and apply fixes, run linters and tests, commit (amend or follow-up depending on review state), push, and reply to dismissed comments with threaded replies.
Fetch unresolved review feedback on a PR — from any author, including copilot, human reviewers, or other automation — triage each item with the user, validate and apply fixes, run linters and tests, commit (amend or follow-up depending on review state), push, and reply to dismissed comments with threaded replies.
Works for any repo via the gh CLI; derive owner/repo from gh repo view rather than hardcoding.
Scope: both inline review-thread comments (attached to a file/line) and substantive top-level PR conversation comments.
$ARGUMENTS is provided, use it. Accept either a PR number or a full URL (https://github.com/{owner}/{repo}/pull/{number} — extract owner/repo/number from the URL).gh pr view --json number --jq .number (works when checked out on the PR's branch).
b. If that fails, search by branch name: gh pr list --head $(git branch --show-current) --json number --jq '.[0].number'.{owner}/{repo} from gh repo view --json nameWithOwner --jq .nameWithOwner (or from the URL).gh pr view <N> --json headRefName --jq .headRefNamegit branch --show-current.git checkout <pr-branch> && git pull --ff-only. Do not proceed until on the PR branch — file paths and line numbers in comments only make sense against the PR branch's content.BASE=$(gh pr view <N> --json baseRefName --jq .baseRefName), usually main), then git fetch origin "$BASE" && git log --oneline HEAD..origin/$BASE. If that shows any commits, the branch is behind — rebase it: git rebase origin/$BASE, resolving conflicts before applying fixes. This repo requires branches be up-to-date with main to merge, so the rebase has to happen eventually anyway — do it now. If the rebase does not complete cleanly (conflicts, or a nonzero exit leaving the repo mid-rebase), stop and surface it to the user — never edit, commit, or push while mid-rebase. Confirm the rebase finished (git status shows no rebase in progress) before continuing. Do not talk yourself out of it because the commented file is new or its lines won't shift: a behind branch can still conflict on shared files you aren't touching for the comments (plugin manifests, version bumps, lockfiles, changelogs), and those conflicts surface only on rebase. Do the rebase before the Step 3 fetch; if you rebase after already fetching, re-run the entire Step 3 fetch — a rebase shifts line/path, isOutdated, and resolution state, so stale data would point fixes at the wrong place. (A rebase rewrites history → the later push needs --force-with-lease. Note: rebasing + force-pushing an approved PR usually dismisses its approvals — re-check reviewDecision in Step 7 afterward, since the PR may no longer be approved.)gh api graphql -f query='{
repository(owner: "<owner>", name: "<repo>") {
pullRequest(number: <N>) {
reviewThreads(first: 50) {
nodes {
isResolved
isOutdated
comments(first: 1) {
nodes { databaseId author { login } body path line }
}
}
}
}
}
}'
isResolved == false. Do not filter by author — every unresolved thread is in scope. Exclude replies (a thread's first comment is the top-level one).gh pr view <N> --json comments. Filter out automation noise. Include substantive ones in the triage table with line shown as (top-level). These are replied to via the issue-comments endpoint, not a thread reply (see Step 8).isOutdated status for context (outdated threads point at changed code — likely stale).databaseId (as id), path, line, isOutdated, author.login, and parse a title + description out of the body:
author.login is cursor[bot] or cursor (bugbot has structured output worth using): title = first ### heading; severity = the **X Severity** pattern; description = text between <!-- DESCRIPTION START --> and <!-- DESCRIPTION END -->. Note any "Triggered by learned rule" footer.Before asking the user what to do, do a first pass on each comment as a senior engineer would:
Present a summary table to the user:
| # | Author | Title | Severity | File | Line | Outdated? | Status |
The Severity column is filled in only for bugbot comments; otherwise show —. Status is Already resolved or Open.
Present numbered options (use AskUserQuestion) for how to handle the open comments:
The user may also scope by number (e.g. "do option 3 for #1 and #2, skip #3"). Collect decisions into a fix list and a reply/dismiss list.
For each item in the fix list:
a. Read the relevant file and lines.
b. Analyze the issue and apply the fix.
c. Identify which commit in the PR introduced the affected lines (reuse $BASE from Step 2):
git log "origin/$BASE..HEAD" --follow --format="%H %s" -- <file> to find candidate commits.git log "origin/$BASE..HEAD" --oneline for context if needed.
d. Track which files were modified and which commits they belong to.After all fixes are applied, run verification. Match the linter/tests to the file types changed:
.rb): rubocop <files>.js, .jsx, .ts, .tsx): the project's lint command (e.g. npx eslint <files>); component tests if applicable..md): npx prettier --check <files>gh pr view <N> --json reviewDecision):
git add <files> && git commit --amend --no-edit.--amend only touches HEAD, so do not use it here — it would fold every staged fix into HEAD and misplace them. Instead, stage and create a fixup per originating commit (git add <files-for-that-commit> && git commit --fixup=<sha>), then fold them in with git rebase --autosquash origin/$BASE (a rewrite → push needs --force-with-lease). Commit each commit's fixes separately so each fixup targets the right <sha>.git add <files> && git commit -m "...") so re-reviewers see exactly what changed since approval, instead of rewriting approved history.git push for a new follow-up commit; git push --force-with-lease if you amended or rebased.--force-with-lease lease, or non-fast-forward), stop and surface it — do not proceed to Step 8 and post replies claiming "fixed in <commit>" for a commit that never reached the remote. Confirm git rev-parse HEAD matches the remote (git rev-parse @{u}, or re-check the PR head) before replying.After user approval, and after any code changes are pushed (so replies can reference the actual fix commit), reply using the endpoint that matches the comment type:
gh api repos/{owner}/{repo}/pulls/{N}/comments/{ID}/replies -X POST -f body="<reply>" — this posts a threaded reply attached to the original comment's file/line. For multi-line bodies or bodies with quotes, use a heredoc:
gh api repos/{owner}/{repo}/pulls/{N}/comments/{ID}/replies -X POST --input - <<'EOF'
{"body": "your reply here"}
EOF
gh api repos/{owner}/{repo}/issues/{N}/comments -f body="<reply>" — GitHub has no threaded reply for these, so this posts a new top-level comment; @-mention the reviewer so they're notified.Summary table:
| # | Author | Title | Action | Commit |
Followed by the PR URL.
npx claudepluginhub blacksam07/agent-skills --plugin engineeringGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.