Skills fetch-pr-feedback

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

install
source · Clone the upstream repo
git clone https://github.com/openclaw/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/anderskev/fetch-pr-feedback" ~/.claude/skills/openclaw-skills-fetch-pr-feedback && rm -rf "$T"
OpenClaw · Install into ~/.openclaw/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/anderskev/fetch-pr-feedback" ~/.openclaw/skills/openclaw-skills-fetch-pr-feedback && rm -rf "$T"
manifest: skills/anderskev/fetch-pr-feedback/SKILL.md
source content

Fetch PR Feedback

Fetch review comments from all reviewers on the current PR, format them, and evaluate using the receive-feedback skill. Excludes the PR author and current user by default.

Usage

/beagle-core:fetch-pr-feedback [--pr <number>] [--include-author]

Flags:

  • --pr <number>
    - PR number to target (default: current branch's PR)
  • --include-author
    - Include PR author's own comments (default: excluded)

Instructions

1. Parse Arguments

Extract flags from

$ARGUMENTS
:

  • --pr <number>
    or detect from current branch
  • --include-author
    flag (boolean, default false)

2. Get PR Context

# 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.

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):

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[\\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):

cat > /tmp/review_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[\\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,
  path,
  line_display: (
    .line as $end | .start_line as $start |
    if $start and $start != $end then "\($start)-\($end)"
    else "\($end // .original_line)" end
  ),
  body: (.body | clean_body),
  created_at
})
JQEOF

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

If

--include-author
is set, omit the
--arg pr_author
parameter and the
.user.login != $pr_author
condition from both jq filter files. Keep the
$current_user
exclusion either way.

4. Format Feedback Document

Noise stripping — handled by the

clean_body
jq function in Step 3. Order matters:
<!-- suggestion_start -->...<!-- suggestion_end -->
blocks are removed first, then remaining HTML comments, then known-noise
<details>
blocks (Analysis chain, Prompt for AI Agents, Committable suggestion, Past reviewee, Recent review details, Tips), and finally the
---
footer boilerplate. The
<details>
blocks must be stripped before the
---
footer pattern because bot analysis chains contain
---
separators that would otherwise truncate the actual finding. Substantive
<details>
blocks (e.g. "Suggested fix", "Proposed fix") are preserved. Comments exceeding 4000 chars after stripping are truncated with a
[comment truncated]
marker.

Group by reviewer — organize the formatted output by reviewer username:

# PR #$PR_NUMBER Review Feedback

## Reviewer: coderabbitai[bot]

### Summary Comments
[Issue comments from this reviewer, each separated by ---]

### Line-Specific Comments
[Review comments from this reviewer, each formatted as:]

**File: `path/to/file.ts:42`**
[cleaned comment body]

---

## Reviewer: another-reviewer

### Summary Comments
...

### Line-Specific Comments
...

If no comments found from any reviewer, output: "No review comments found on this PR (excluding PR author and current user)."

5. Evaluate with receive-feedback

Use the Skill tool to load the receive-feedback skill:

Skill(skill: "beagle-core:receive-feedback")

Then process the formatted feedback document:

  1. Parse each actionable item from the formatted document
  2. Process each item through verify → evaluate → execute
  3. Produce structured response summary

Example

# Fetch all reviewer comments on current branch's PR (default)
/beagle-core:fetch-pr-feedback

# Fetch from a specific PR
/beagle-core:fetch-pr-feedback --pr 123

# Include PR author's own comments
/beagle-core:fetch-pr-feedback --include-author

# Combined
/beagle-core:fetch-pr-feedback --pr 456 --include-author