Agent skill
resolve-pr-issues
Fix PR issues including review comments and CI failures. Use when user says "fix the failing CI on my PR", "address the review comments on PR
Install this agent skill to your Project
npx add-skill https://github.com/Uniswap/ai-toolkit/tree/next/packages/plugins/development-pr-workflow/skills/resolve-pr-issues
SKILL.md
PR Issue Resolver
Orchestrate resolution of all outstanding PR feedback — inline comments, review bodies, and CI failures — through a structured triage-then-dispatch pipeline.
When to Activate
- User mentions PR review comments to address
- CI/CD checks are failing on a PR
- User wants to fix a pull request
- User needs to respond to reviewer feedback
- Build or tests failing on a PR
- User says "fix my PR" or "address the comments"
Workflow Overview
Phase 0: Input Parsing
↓
Phase 1: Gather (parallel fetch)
↓
Phase 2: Normalize (unified item list)
↓
Phase 3: Triage (act vs. explain-why-not)
↓
Phase 4: Dispatch (subagents for code changes, direct replies for explanations)
↓
Phase 5: Collect & Verify
↓
Phase 6: Commit & Report
Phase 0: Input Parsing
Extract from the user's request:
pr_number(required): Parse from user message, PR URL, or prompt for itowner(optional): Infer viagh repo view --json owner --jq '.owner.login'repo(optional): Infer viagh repo view --json name --jq '.name'
Validate access and state before proceeding:
gh pr view {pr_number} --json number,title,state --jq '{number, state}'
- If the command fails (access error, PR not found), surface the error to the user. Do not continue.
- If
stateisMERGEDorCLOSED, warn the user: "PR #{number} is {state}. Do you still want to proceed?" Require explicit confirmation before continuing — resolving comments on a merged/closed PR is almost never what the user intended.
Phase 1: Gather
Fetch all PR data in parallel:
| Data | Primary Method | Fallback |
|---|---|---|
| PR details | pull_request_read(method: "get") |
gh pr view {number} --json title,author,state,body |
| Inline comments | pull_request_read(method: "get_review_comments") |
gh api repos/{owner}/{repo}/pulls/{number}/comments |
| Review bodies | gh api repos/{owner}/{repo}/pulls/{number}/reviews |
None (primary method — MCP lacks reviews endpoint) |
| CI status | pull_request_read(method: "get_status") |
gh pr checks {number} |
| PR diff | pull_request_read(method: "get_diff") |
gh pr diff {number} |
| Changed files | pull_request_read(method: "get_files") |
gh pr view {number} --json files |
Note: The changed files list is used in Phase 4 to scope agent work — agents should only modify files in this list (plus cross-file references). It also helps validate that inline comment file paths actually exist in the PR diff.
Error Handling
- Inline comments: If both
pull_request_readMCP andgh apifallback fail for inline comments, stop and surface the error immediately. Inline comments are the primary input — do not proceed with an empty comment list. The user must resolve the access issue before the workflow can continue. - Review bodies: If
gh apifor review bodies fails (auth, rate limit, network), surface the error to the user before proceeding. The workflow may continue with inline comments and CI items, but the user must know review bodies were not fetched. Do not silently skip them. - CI status / diff / changed files: If these fail, surface the error but allow the workflow to continue with reduced functionality. Note the missing data in the triage summary.
Phase 2: Normalize
Parse all feedback into a unified item list. Each item has:
| Field | Type | Description |
|---|---|---|
id |
string | Comment ID or generated identifier |
source |
"inline" / "review_body" / "ci" |
Where the feedback came from |
author |
string | GitHub username |
is_bot |
boolean | True for CI bots, GitHub Actions, etc. |
is_resolved |
boolean | True if thread is resolved or comment is outdated |
location |
{file, line} or null |
Code location (null for review body items, CI failures) |
content |
string | Comment text or CI failure description |
review_state |
string | APPROVED, CHANGES_REQUESTED, COMMENTED |
blocking |
boolean | Derived from review state + language analysis |
context |
string | Surrounding code or CI log excerpt |
Resolved/Outdated Detection
- Inline comments with
position: null→ outdated (diff line no longer exists) - Comment threads marked as resolved → already handled
- Set
is_resolved: true— these are filtered out during triage
Blocking Classification
CHANGES_REQUESTEDreview state → defaultblocking: trueCOMMENTEDorAPPROVEDreview state → defaultblocking: false- Language overrides: "must", "required", "blocking", "critical", "security", "vulnerability" →
blocking: true - Language overrides: "nit", "optional", "consider", "suggestion", "minor", "nice to have" →
blocking: false - CI failures → always
blocking: true
Review Body Parsing
The review body is free-form text. Parse it into discrete items:
- Each bullet point, numbered item, or paragraph with a distinct concern = one item
- Standalone questions = separate item (will become RESPOND_ONLY)
- General praise/acknowledgment = skip (no item created)
CI Bot Deduplication
If an inline comment author is a known bot (e.g., github-actions[bot], codecov-commenter, renovate[bot]) AND the content overlaps with a CI check failure on the same file/line, merge into one item. Use the inline comment as the canonical item (it has location context).
Exception: Do NOT deduplicate when the inline bot comment is stale or resolved (is_resolved: true). In that case, keep the CI failure as a separate item — a stale bot comment does not mean the underlying CI failure is resolved.
Phase 3: Triage
For each normalized item, classify:
| Classification | Criteria | Action |
|---|---|---|
ACTION_REQUIRED |
Specific code change suggested, bug reported, CI failure, lint/type error | Dispatch to subagent |
RESPOND_ONLY |
Question asked, concern raised without specific fix, design discussion | Post reply with explanation |
NO_ACTION |
Praise, acknowledgment, already resolved, outdated, duplicate | Log in report |
Decision Tree
Apply in order — first match wins:
- Is the thread already resolved or outdated? →
NO_ACTION - Is it a CI failure? →
ACTION_REQUIRED - Is it a bot comment with specific errors? →
ACTION_REQUIRED - Does it suggest a specific code change? →
ACTION_REQUIRED - Does it report a bug or incorrect behavior? →
ACTION_REQUIRED - Does it raise a potential bug concern without a specific fix (e.g., "this looks wrong", "this seems buggy")? →
RESPOND_ONLY, but flag for user review in the triage summary — the user may want to promote it toACTION_REQUIRED - Does it ask a question or raise a non-bug concern without a specific fix? →
RESPOND_ONLY - Is it praise, acknowledgment, or informational? →
NO_ACTION
See pr-guide.md § Triage Examples for classification examples and edge cases.
Output
Three lists: action_items, respond_items, no_action_items.
Log the triage decisions visibly so the user can see what will be acted on vs. replied to before dispatch begins. Present a summary table:
| # | Source | Author | Location | Classification | Reason |
|---|
Phase 4: Dispatch
ACTION_REQUIRED Items
Group inline comments by file path. For each file group, spawn a comment-resolver-agent:
Task(
subagent_type: "development-pr-workflow:comment-resolver-agent",
description: "Resolve comments on {file_path}",
prompt: "Resolve PR review comments on `{file_path}` in PR #{pr_number} ({owner}/{repo}).
## Comments to Address
{for each comment in group:}
### Comment {n} ({comment_id}, by @{author})
- Source: {inline | review_body | ci}
- Location: {file:line or general}
- Blocking: {yes/no}
- Content: {comment text}
## Context
PR Title: {title}
PR Description: {description}
<file-diff>
{relevant diff for this file}
</file-diff>
## Instructions
1. Read the file and apply each requested change
2. If ambiguous, make the most reasonable interpretation and note it
3. For CI failures, investigate and fix (may require running commands)
4. You MAY modify files outside the assigned group if a comment requires cross-file changes
5. Verify locally that the file still parses/compiles
6. Do NOT commit — leave changes uncommitted
Report per comment: ID, what changed, files modified, any issues.",
run_in_background: true,
model: "sonnet"
)
Review body items without file location: Batch up to 3 items per agent instance. Provide the full PR diff so the agent can identify relevant file(s). If there are more than 5 unlocated review body items, process in batches of 3 to avoid spawning excessive agents.
CI failures without a specific file: Each gets its own agent instance with CI logs and failure context. Cap at 3 concurrent CI failure agents — process additional failures sequentially after earlier agents complete.
RESPOND_ONLY Items
The orchestrator handles these directly — no subagent needed.
For inline comments — reply to the comment thread:
# Write reply to unique temp file, then send as JSON field via -F
REPLY_FILE=$(mktemp /tmp/pr-reply-XXXXXX.md)
cat > "$REPLY_FILE" << 'REPLY_EOF'
{explanation}
REPLY_EOF
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-F body=@"$REPLY_FILE"
rm -f "$REPLY_FILE"
For review body items — post a general PR comment:
# Write reply to unique temp file to avoid shell injection
REPLY_FILE=$(mktemp /tmp/pr-reply-XXXXXX.md)
cat > "$REPLY_FILE" << 'REPLY_EOF'
{response}
REPLY_EOF
gh pr comment {pr_number} --body-file "$REPLY_FILE"
rm -f "$REPLY_FILE"
Security note: Never interpolate reply text directly into shell command arguments. Reply content may echo untrusted PR comment text. Always write to a unique temp file (via
mktemp), then pass via-F body=@file(forgh api) or--body-file(forgh pr comment). The-Fflag sends the file content as a proper JSON field — do NOT use--input, which sends raw bytes and will cause a 422 from the GitHub API.
Reply content must:
- Acknowledge the reviewer's point
- Explain the rationale for the current approach
- Reference relevant code or docs if helpful
- Be respectful and substantive (not dismissive)
NO_ACTION Items
No action. Log in final report.
Phase 5: Collect & Verify
-
Collect results from each agent's Task completion output (agents return structured reports when their Task completes)
-
Aggregate: changes made per comment, unresolved issues, all files modified
-
Detect cross-agent file conflicts: Compare the "files modified" lists from each agent. If two or more agents modified the same file:
- Run
git diff {file}to see the combined changes - If agents modified different line ranges (non-overlapping functions/blocks), this is not a conflict — no action needed
- If agents modified the same logical code region (overlapping lines or the same function), flag as a conflict. Re-run the affected changes sequentially: apply the higher-priority (blocking) agent's changes first, then layer the other agent's changes on top, verifying each step
- Run
-
Detect project tooling before running verification:
- Check for
nx.json→ Nx commands - Check
package.jsonscripts → npm scripts - Do NOT assume specific commands exist
- Check for
-
Run verification using detected tooling. Resolve the PR's base branch dynamically to match CI behavior:
bashPR_BASE=$(gh pr view {pr_number} --json baseRefName --jq '.baseRefName')Then run:
- Format (e.g.,
npx nx format:write --uncommitted) - Lint (e.g.,
npx nx affected --target=lint --base=origin/$PR_BASE) - Typecheck (e.g.,
npx nx affected --target=typecheck --base=origin/$PR_BASE) - Tests if relevant (e.g.,
npx nx affected --target=test --base=origin/$PR_BASE)
- Format (e.g.,
-
On failure: Identify which changes caused the failure. Fix directly or re-dispatch. Re-verify.
Phase 6: Commit & Report
Commit Policy
Always ask the user before committing. If they agree, ask whether to create:
- A single commit with all changes, or
- Separate commits grouped by comment/file
Never auto-commit.
Report
Provide a structured summary:
## PR #{number} Issue Resolution Summary
### Triage Results
| Category | Count | Items |
| --------------- | ----- | ------------ |
| Action Required | {n} | {brief list} |
| Responded | {n} | {brief list} |
| No Action | {n} | {brief list} |
### Changes Applied
#### Inline Comments ({n} resolved)
- **{file}:{line}** (@{author}): {summary} → {what was done}
#### Review Body Items ({n} addressed)
- **Blocking**: {item} → {what was done}
- **Non-blocking**: {item} → {what was done}
#### CI Fixes ({n} resolved)
- {failure} → {fix applied}
### Replies Posted ({n})
- @{author} on {file}:{line}: {reply summary}
### Files Modified
- `{path}`: {change summary}
### Verification
- Format: {pass/fail}
- Lint: {pass/fail}
- Typecheck: {pass/fail}
- Tests: {pass/fail}
### Unresolved Items
- {items that couldn't be addressed, with reasons}
Detailed Reference
For GitHub MCP usage, triage examples, reply templates, and CI troubleshooting, see pr-guide.md.
Didn't find tool you were looking for?