Skip to main content
ClaudeWave
Skill63 estrellas del repoactualizado 3d ago

fetch-pr-feedback

Fetch unresolved review comments from a PR and evaluate with receive-feedback skill

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/existential-birds/beagle /tmp/fetch-pr-feedback && cp -r /tmp/fetch-pr-feedback/plugins/beagle-core/skills/fetch-pr-feedback ~/.claude/skills/fetch-pr-feedback
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# Fetch PR Feedback

Fetch review comments from all reviewers on the current PR, format them, and evaluate using the [receive-feedback](../receive-feedback/SKILL.md) skill. Excludes the PR author and current user by default. Line-specific comments belonging to resolved review threads are also excluded by default.

## Usage

Invoke the **fetch-pr-feedback** skill, optionally passing these flags:

```
fetch-pr-feedback [--pr <number>] [--include-author] [--include-resolved]
```

**Flags:**
- `--pr <number>` - PR number to target (default: current branch's PR)
- `--include-author` - Include PR author's own comments (default: excluded)
- `--include-resolved` - Include line-specific comments from resolved review threads (default: excluded)

## Instructions

### Gates (sequence; do not skip)

Advance only after each **Pass when** is satisfied.

1. **PR context** — **Pass when:** `$PR_NUMBER` is set to a positive integer and `gh pr view` / `gh api` for that PR completed with exit code **0**, **or** you stop in **Get PR Context** with only the failure given there (“No PR found for current branch…”).
2. **Fetch** — **Pass when:** the resolved-thread GraphQL call (skipped if `--include-resolved`) and both paginated `gh api … | jq -s -f …` runs (issue comments + review comments) exit **0** and parse as JSON (empty `[]` is valid). On non-zero exit or jq error, stop; surface command stderr—do not invent comments.
3. **Formatted artifact** — **Pass when:** output is either (a) markdown matching **Format Feedback Document** (header `# PR #$PR_NUMBER Review Feedback`, per-reviewer `## Reviewer: …` with Summary / Line-Specific sections), **or** (b) exactly: `No review comments found on this PR (excluding PR author, current user, and resolved threads).`
4. **Load receive-feedback** — **Pass when:** the [receive-feedback](../receive-feedback/SKILL.md) skill is loaded; only then run that skill’s verify → evaluate → execute loop on that formatted document.

### 1. Parse Arguments

Extract flags from `$ARGUMENTS`:
- `--pr <number>` or detect from current branch
- `--include-author` flag (boolean, default false)
- `--include-resolved` flag (boolean, default false)

### 2. Get PR Context

```bash
# If --pr was specified, use that number directly
# Otherwise, get PR for current branch:
gh pr view --json number,headRefName,url,author --jq '{number, headRefName, url, author: .author.login}'

# Get repo owner/name
gh repo view --json owner,name --jq '{owner: .owner.login, name: .name}'

# Get current authenticated user
gh api user --jq '.login'
```

Store as `$PR_NUMBER`, `$PR_AUTHOR`, `$OWNER`, `$REPO`, `$CURRENT_USER`.

**Note:** `$OWNER`, `$REPO`, etc. are placeholders. Substitute actual values from previous steps.

If no PR exists for current branch, fail with: "No PR found for current branch. Use `--pr` to specify a PR number."

### 3. Fetch Comments

Fetch both types of comments, excluding `$PR_AUTHOR` and `$CURRENT_USER` (unless `--include-author` is set). Use `--paginate` with `jq -s` to combine paginated JSON arrays into one.

Unless `--include-resolved` is set, first fetch the databaseIds of every review comment that belongs to a resolved review thread. Issue comments (summary/walkthrough) aren't part of review threads, so this only affects line-specific review comments.

**Resolved-thread comment IDs** (skip this block entirely when `--include-resolved` is set; set `RESOLVED_IDS='[]'` instead):

```bash
RESOLVED_IDS=$(gh api graphql \
  -F owner="$OWNER" -F repo="$REPO" -F pr="$PR_NUMBER" \
  -f query='
    query($owner: String!, $repo: String!, $pr: Int!) {
      repository(owner: $owner, name: $repo) {
        pullRequest(number: $pr) {
          reviewThreads(first: 100) {
            nodes {
              isResolved
              comments(first: 100) { nodes { databaseId } }
            }
          }
        }
      }
    }
  ' \
  --jq '[.data.repository.pullRequest.reviewThreads.nodes[]
         | select(.isResolved)
         | .comments.nodes[].databaseId
         | select(. != null)]')
```

The `first: 100` limits cover typical PRs. For very large PRs (>100 threads or >100 comments in a single thread), thread/comment-level pagination would need to be added; for now, that's a known limitation.

Write jq filters to temp files using heredocs with single-quoted delimiters (prevents shell escaping issues with `!=`, regex patterns, and angle brackets):

**Issue comments** (summary/walkthrough posts):

```bash
cat > /tmp/issue_comments.jq << 'JQEOF'
def clean_body:
  gsub("<!-- suggestion_start -->.*?<!-- suggestion_end -->"; ""; "s")
  | gsub("<!--.*?-->"; ""; "s")
  | gsub("<details>\\s*<summary>\\s*🧩 Analysis chain[\\s\\S]*?</details>"; ""; "s")
  | gsub("<details>\\s*<summary>\\s*🤖 Prompt for AI Agents[\\s\\S]*?</details>"; ""; "s")
  | gsub("<details>\\s*<summary>\\s*📝 Committable suggestion[\\s\\S]*?</details>"; ""; "s")
  | gsub("<details>\\s*<summary>Past reviewee.*?</details>"; ""; "s")
  | gsub("<details>\\s*<summary>Recent review details[\\s\\S]*?</details>"; ""; "s")
  | gsub("<details>\\s*<summary>\\s*Tips\\b.*?</details>"; ""; "s")
  | gsub("\\n?\\n---\\n+(?=\\s*(?:✨\\s*Finishing Touches|🪧\\s*Tips?|🤖\\s*Generated|<sub>|_Generated by|Generated by Claude|Generated with))[\\s\\S]*$"; ""; "s")
  | gsub("^\\s+|\\s+$"; "")
  | if length > 4000 then .[:4000] + "\n\n[comment truncated]" else . end
;
[(add // []) | .[] | select(
  .user.login != $pr_author and
  .user.login != $current_user
)] |
map({id, user: .user.login, body: (.body | clean_body), created_at})
JQEOF

gh api --paginate "repos/$OWNER/$REPO/issues/$PR_NUMBER/comments" | \
  jq -s --arg pr_author "$PR_AUTHOR" --arg current_user "$CURRENT_USER" \
  -f /tmp/issue_comments.jq
```

**Review comments** (line-specific):

```bash
cat > /tmp/review_comments.jq << 'JQEOF'
def clean_body:
  gsub("<!-- suggestion_start -->.*?<!-- suggestion_end -->"; ""; "s")
  | gsub("<!--.*?-->"; ""; "s")
  | gsub("<details>\\s*<summary>\\s*🧩 Analysis
release-tagSlash Command

tag and push a release after the release PR is merged

releaseSlash Command

create a release PR (auto-detects previous tag)

deepagents-architectureSkill

Guides architectural decisions for Deep Agents applications. Use when deciding between Deep Agents vs alternatives, choosing backend strategies, designing subagent systems, or selecting middleware approaches.

deepagents-code-reviewSkill

Reviews Deep Agents code for bugs, anti-patterns, and improvements. Use when reviewing code that uses create_deep_agent, backends, subagents, middleware, or human-in-the-loop patterns. Catches common configuration and usage mistakes.

deepagents-implementationSkill

Implements agents using Deep Agents. Use when building agents with create_deep_agent, configuring backends, defining subagents, adding middleware, or setting up human-in-the-loop workflows.

langgraph-architectureSkill

Guides architectural decisions for LangGraph applications. Use when deciding between LangGraph vs alternatives, choosing state management strategies, designing multi-agent systems, or selecting persistence and streaming approaches.

langgraph-code-reviewSkill

Reviews LangGraph code for bugs, anti-patterns, and improvements. Use when reviewing code that uses StateGraph, nodes, edges, checkpointing, or other LangGraph features. Catches common mistakes in state management, graph structure, and async patterns.

langgraph-implementationSkill

Implements stateful agent graphs using LangGraph. Use when building graphs, adding nodes/edges, defining state schemas, implementing checkpointing, handling interrupts, or creating multi-agent systems with LangGraph.