Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pr-review-toolkit/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pr-review-toolkit",
"version": "1.11.1",
"version": "1.12.0",
"description": "Comprehensive PR review board using shared workflow context",
"author": {
"name": "cblecker",
Expand Down
26 changes: 25 additions & 1 deletion pr-review-toolkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,36 @@ as a single Workflow-based skill. The workflow collects shared PR context,
runs specialist reviewers, and returns an interactive review board for the
human reviewer.

## Usage
## Skills

### review-pr

```text
/pr-review-toolkit:review-pr <github-pr-url>
```

Conduct a comprehensive PR review and return an interactive review board.
See [Review Flow](#review-flow) below.

### address-pr-feedback

```text
/pr-review-toolkit:address-pr-feedback [--interactive]
```

Systematically collect, analyze, score, and address pull request review
feedback from the current branch's PR. After implementing changes, drafts
reply comments and posts them to GitHub with per-reply user approval.

By default, the skill auto-detects the open PR for the current branch and
fetches all review comments via GitHub MCP. Use `--interactive` to manually
paste feedback items instead.

**Flow:** branch validation &rarr; feedback collection &rarr; parallel
analysis and scoring (Sonnet + Haiku agents) &rarr; per-item action
confirmation &rarr; plan generation &rarr; implementation &rarr; reply
posting.

## Review Flow

The skill parses a GitHub PR URL and launches the bundled workflow. The skill
Expand Down
254 changes: 254 additions & 0 deletions pr-review-toolkit/skills/address-pr-feedback/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
---
name: address-pr-feedback
description: >-
Systematically collect, analyze, score, and address pull request review
feedback, then post reply comments
disable-model-invocation: true
user-invocable: true
arguments: [--interactive]
argument-hint: [--interactive]
Comment thread
cblecker marked this conversation as resolved.
---

# Address PR Feedback

Systematically collect, analyze, score, and plan execution for pull request
review feedback, then post reply comments to GitHub.

## Phase 0: Branch Validation

**Validate branch first:**

- Run `git branch --show-current` to get the current branch
- Run `git ls-remote --symref origin HEAD 2>/dev/null | grep "^ref:" | awk '{print $2}' | sed 's|refs/heads/||'` to get the mainline branch
- If the current branch matches the mainline branch:
- Display: "Error: You're on the mainline branch. Please checkout a feature branch and retry this skill."
- Stop execution

**Then ensure plan mode is active:**

- If plan mode is not already active, call `EnterPlanMode` and wait for user
approval
- If plan mode is already active (check for "Plan mode is active" in system
context), proceed directly

## Phase 1: Feedback Collection

Check if the argument contains `--interactive`. If it does, use the
**interactive collection** path. Otherwise, use the **auto-fetch** path.

### Auto-Fetch Path (Default)

1. **Detect PR from current branch:**
- Run `git remote get-url origin` and extract owner/repo
(strip protocol prefix, `.git` suffix, and hosting domain)
- Run `git branch --show-current` to get the branch name
- Determine if this is a fork workflow:
- Run `git remote get-url upstream 2>/dev/null` — if it succeeds, this is
a fork workflow; extract the upstream owner/repo
- Find the open PR:
- Fork workflow: use `list_pull_requests` with `state: "open"` and
`head: "<fork-owner>:<branch>"`, scoped to the upstream owner/repo
- Non-fork workflow: use `list_pull_requests` with `state: "open"` and
`head: "<owner>:<branch>"`, scoped to the owner/repo
Comment on lines +41 to +52

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make PR detection robust for SSH remotes and non-fork upstream remotes.

The current slug extraction only works reliably for HTTPS-style origin URLs, and treating any upstream remote as a fork can send list_pull_requests to the wrong repository. Parse both SSH/HTTPS URL forms and derive fork status from the tracked repo/branch metadata instead of remote presence alone.

Suggested adjustment
- - Run `git remote get-url origin` and extract owner/repo
-   (strip protocol prefix, `.git` suffix, and hosting domain)
+ - Run `git remote get-url origin` and parse owner/repo from both HTTPS and SSH URL forms.
...
- - Determine if this is a fork workflow:
-   - Run `git remote get-url upstream 2>/dev/null` — if it succeeds, this is
-     a fork workflow; extract the upstream owner/repo
+ - Determine fork workflow from branch tracking / repo slug comparison, not just the
+   presence of an `upstream` remote.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
1. **Detect PR from current branch:**
- Run `git remote get-url origin` and extract owner/repo
(strip protocol prefix, `.git` suffix, and hosting domain)
- Run `git branch --show-current` to get the branch name
- Determine if this is a fork workflow:
- Run `git remote get-url upstream 2>/dev/null` — if it succeeds, this is
a fork workflow; extract the upstream owner/repo
- Find the open PR:
- Fork workflow: use `list_pull_requests` with `state: "open"` and
`head: "<fork-owner>:<branch>"`, scoped to the upstream owner/repo
- Non-fork workflow: use `list_pull_requests` with `state: "open"` and
`head: "<owner>:<branch>"`, scoped to the owner/repo
1. **Detect PR from current branch:**
- Run `git remote get-url origin` and parse owner/repo from both HTTPS and SSH URL forms.
- Run `git branch --show-current` to get the branch name
- Determine if this is a fork workflow from branch tracking / repo slug comparison, not just the
presence of an `upstream` remote.
- Find the open PR:
- Fork workflow: use `list_pull_requests` with `state: "open"` and
`head: "<fork-owner>:<branch>"`, scoped to the upstream owner/repo
- Non-fork workflow: use `list_pull_requests` with `state: "open"` and
`head: "<owner>:<branch>"`, scoped to the owner/repo
🧰 Tools
🪛 SkillSpector (2.3.7)

[warning] 187: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pr-review-toolkit/skills/address-pr-feedback/SKILL.md` around lines 41 - 52,
The PR detection logic in the current branch flow is too brittle because the
origin slug parsing only handles HTTPS remotes and the presence of an `upstream`
remote is being used as a fork signal. Update the branch detection steps around
`git remote get-url origin`, `git branch --show-current`, and the
`list_pull_requests` call to correctly parse both SSH and HTTPS remote URL
forms, and determine fork status from tracked repo/branch metadata rather than
from `upstream` existing alone. Keep the fork and non-fork `head` construction
in the same detection path, but ensure the repo owner/repo scoping is derived
from the parsed remote data.

- If no PR found, display:
"Error: No open PR found for branch `<branch>`. Push and open a PR first,
or use `--interactive` to paste feedback manually."
- Stop execution if no PR found

2. **Fetch all comments** using `pull_request_read` on the found PR:
- `get_reviews` — review bodies and review events
- `get_review_comments` — inline review comments with threads
- `get_comments` — issue-style conversation comments

Include all comments — no bot filtering, no trust filtering. The scoring
phase handles relevance naturally.
Comment on lines +63 to +64

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Skip comments authored by the current automation.

With Phase 6 writing replies back as normal PR comments, the default auto-fetch path will re-ingest those replies on the next run and can re-open already handled items. Exclude the tool’s own replies (or any comments from the current actor) from the auto-fetch set.

Suggested adjustment
- Include all comments — no bot filtering, no trust filtering. The scoring
- phase handles relevance naturally.
+ Include all comments, but skip comments authored by the current automation
+ so Phase 6 replies are not reprocessed on subsequent runs. The scoring phase
+ still handles relevance for everything else.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Include all comments — no bot filtering, no trust filtering. The scoring
phase handles relevance naturally.
Include all comments, but skip comments authored by the current automation
so Phase 6 replies are not reprocessed on subsequent runs. The scoring phase
still handles relevance for everything else.
🧰 Tools
🪛 SkillSpector (2.3.7)

[warning] 187: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pr-review-toolkit/skills/address-pr-feedback/SKILL.md` around lines 63 - 64,
The auto-fetch path is currently including every comment, which re-ingests
replies created by the current automation and can reopen handled items. Update
the comment collection logic in the feedback workflow to exclude comments
authored by the current actor or this tool’s own replies before scoring, and
keep the filtering centralized where the fetch/list step prepares the comments
for downstream processing.


3. **Normalize** each comment into a structured item:
- `text` — comment body
- `author` — GitHub username
- `file` / `line` — file path and line number (inline comments only; null
for others)
- `commentId` — numeric comment ID (for reply posting)
- `threadId` — thread node ID (inline comments) or null
- `type` — `"review"` | `"inline"` | `"conversation"`

### Interactive Collection Path (`--interactive`)

Display: "Ready to accept feedback items. Say 'done' when finished."

Loop until user says "done":

1. Receive user input
2. Launch Haiku agent to parse:
- Fetch any GitHub comment URLs (use GitHub MCP tools)
- Extract feedback text
- Extract author (if available)
- Extract file/line location (if available)
- Normalize into structured format with `commentId`, `threadId`, and `type`
fields (set to null if not available from pasted content)
3. Acknowledge: "Recorded item [N]: [brief summary]"
4. Continue loop

Store all items in conversation context.

## Phase 2: Analysis & Scoring

Before analyzing, **deduplicate related items.** Multiple comments often
address the same underlying concern (e.g., two reviewers flag the same issue,
or one reviewer comments on both the declaration and usage of the same
problem). Group these into a single logical item — track all associated
`commentId`/`threadId` values so replies can be posted to each thread in
Phase 6.

**For 5 or fewer items**, analyze and score inline — the context is small
enough that agents add latency without improving quality.

**For 6+ items, launch parallel Sonnet agents** (one per feedback item, or
batched 3-5 items if many):

Each agent prompt:

```text
Analyze this PR feedback item:
[item details]

Read relevant code context (minimal - only affected files/lines).
Check CLAUDE.md for applicable guidance.

Return:
- Validity: Is this feedback correct and still applicable?
- Impact: What's the practical effect? (bug/enhancement/style)
- Effort: Implementation cost (S/M/L)
- Guidance: Is it backed by CLAUDE.md or project standards?
- Recommended action: Implement/modify/reject/discuss
- Draft reply: Brief explanation for reviewer (e.g., "Addressed in
[commit/location]" or "Fixed by [change description]")

Flag false positives:
- Code no longer present
- Already addressed in subsequent commits
- Conflicts with other feedback items
- Based on outdated PR state
```

**Launch parallel Haiku agents** for scoring (one per item):

Each scoring agent receives the analysis and applies this rubric (0-100
scale):

| Score | Interpretation |
|-------|----------------|
| 0-25 | Invalid: feedback doesn't apply, code doesn't have this issue, or already fixed; may be misunderstanding or based on outdated PR state |
| 26-50 | Valid but minor: real issue but stylistic preference, nitpick, or low practical impact; not backed by project standards |
| 51-75 | Important: verified real issue with practical impact; affects functionality or code quality meaningfully |
| 76-100 | Critical: definitely correct, high impact, affects users or core functionality, or explicitly violates CLAUDE.md/standards |

**Scoring factors:**

- Validity (40%): Is feedback correct and still applicable to current code
state?
- Impact (30%): Practical effect on functionality, users, or code quality
- Effort (20%): Implementation cost (inverse — lower effort = higher score
contribution)
- Guidance backing (10%): Explicitly mentioned in CLAUDE.md or project
standards

Return score with rationale.

## Phase 3: Action Confirmation

Order items by score (highest first).

For each item, use `AskUserQuestion`:

```text
Question: "Item [N]: [summary] - Score: [X] - Recommended: [action]. Confirm course of action?"
Header: "Item [N]"
Options:
- "Implement as suggested" (description: Apply the feedback exactly as stated)
- "Implement differently" (description: Address the concern but with a different approach - will specify)
- "Reject" (description: Do not address this feedback - will provide reason)
- "Discuss with reviewer" (description: Need clarification before deciding)
```

Record confirmed action for each item.

## Phase 4: Plan Generation

Use Haiku agent to write plan file with this structure:

```markdown
# PR Feedback Execution Plan

Total items: [count]

## Execution Instructions

**IMPORTANT:** Use TaskCreate to create a task for each item below FIRST before
implementing any changes.

1. Create tasks for all items
2. Implement in order (highest score first)
3. Mark tasks complete as you go
4. Verify all changes before re-requesting review

## Feedback Items

### Item 1: [summary]
- **Score:** [X]
- **Action:** [confirmed action]
- **Files:** [affected files with paths]
- **Implementation:**
- [Step 1]
- [Step 2]
- [...]
- **Draft reply:** [Brief comment explaining how this was addressed]

### Item 2: [summary]
...

## Verification Checklist

- [ ] All tasks created via TaskCreate
- [ ] All implementations complete
- [ ] Tests pass
- [ ] Code follows project standards
- [ ] Ready for re-review
```

## Phase 5: Exit Plan Mode

Call `ExitPlanMode` to signal planning is complete and request user approval.

After user approval, execution begins:

1. Tasks are created using TaskCreate
2. Each item is implemented following the plan
3. Tasks are marked complete as work progresses

## Phase 6: Reply Posting

After all implementation tasks are complete, iterate over each implemented
item that has a draft reply.

For each item:

1. Present the draft reply text (generated in Phase 2, refined in Phase 4)
2. Use `AskUserQuestion`:

```text
Question: "Post this reply for Item [N]?"
Header: "Reply [N]"
Options:
- "Post as-is" (description: Post the draft reply to the PR comment)
- "Edit then post" (description: Modify the reply text before posting)
- "Skip" (description: Do not post a reply for this item)
```

3. If "Edit then post" is selected, receive the edited text from the user
4. For approved replies, post via GitHub MCP:
- Inline review comments (type `"inline"`, has `commentId`):
use `add_reply_to_pull_request_comment` with the original `commentId`
and `pullNumber`
- Conversation comments (type `"conversation"` or `"review"`):
use `add_issue_comment` on the PR number
Loading