Skip to content

feat(default): add pr-review-multi-source skill (adapted from optimus)#331

Open
gandalf-at-lerian wants to merge 1 commit intomainfrom
feat/pr-review-multi-source
Open

feat(default): add pr-review-multi-source skill (adapted from optimus)#331
gandalf-at-lerian wants to merge 1 commit intomainfrom
feat/pr-review-multi-source

Conversation

@gandalf-at-lerian
Copy link
Copy Markdown
Contributor

Summary

Adds ring:pr-review-multi-source to the default plugin.

Fills a gap in Ring: fetches PR metadata AND existing review comments from ALL sources (CodeRabbit, human reviewers, CI bots), dispatches Ring's 7 reviewer agents to evaluate both code AND existing comments, with source attribution.

Key features

  • 9-phase workflow: fetch PR context → present summary → review type → dispatch agents → consolidate with attribution → interactive resolution → batch apply → final summary → respond to PR comments
  • References Ring's existing agents (ring:code-reviewer, ring:security-reviewer, ring:business-logic-reviewer, ring:test-reviewer, ring:nil-safety-reviewer, ring:consequences-reviewer, ring:dead-code-reviewer)
  • Source attribution on every finding

Origin

Adapted from alexgarzao/optimus (optimus-pr-review), converted to Ring format.

cc @alexgarzao

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

Walkthrough

Introduces a new skill definition implementing an end-to-end PR review orchestrator. The skill defines a multi-phase workflow: fetching and validating PR context, collecting existing comments, dispatching multiple reviewer agents, consolidating findings with existing comment evaluation, enabling interactive finding resolution, applying fixes with lint and test verification gates, and posting reply templates back to GitHub comment threads.

Changes

Cohort / File(s) Summary
PR Review Multi-Source Skill
default/skills/pr-review-multi-source/SKILL.md
New skill definition implementing end-to-end PR review orchestration with PR context fetching, multi-agent code review with existing comment evaluation, interactive finding resolution in severity order, batched fix application with lint/unit/integration verification gates, and GitHub comment thread reply posting and resolution via GraphQL API.

Sequence Diagram

sequenceDiagram
    actor User
    participant Orchestrator as PR Review<br/>Orchestrator
    participant GitHub as GitHub API
    participant Agents as Reviewer<br/>Agents (5-7)
    participant Verify as Verification<br/>System
    
    User->>Orchestrator: Trigger skill with PR URL or branch
    Orchestrator->>GitHub: Fetch PR context and metadata
    GitHub-->>Orchestrator: PR details (title, body, state, diff)
    Orchestrator->>GitHub: Collect existing comments & reviews
    GitHub-->>Orchestrator: All PR comments and threads
    Orchestrator->>Orchestrator: Present PR summary to user
    Orchestrator->>User: Select review mode (Initial/Final)
    User->>Orchestrator: Choose mode (5 or 7 agents)
    
    Orchestrator->>Agents: Dispatch agents with PR context<br/>+ file contents + existing comments
    Agents->>Agents: Review code + evaluate<br/>existing comments
    Agents-->>Orchestrator: Review findings + comment evaluations<br/>(AGREE/CONTEST/ALREADY FIXED)
    
    Orchestrator->>Orchestrator: Consolidate findings + deduplicate<br/>+ attribute sources
    Orchestrator->>User: Present findings in severity order
    User->>Orchestrator: Approve/reject findings interactively
    Orchestrator->>Orchestrator: Record user decisions
    
    Orchestrator->>Verify: Apply approved fixes + run tests
    Verify->>Verify: Execute lint, unit,<br/>integration, E2E
    Verify-->>Orchestrator: Test results
    Orchestrator->>Orchestrator: Revert failing fixes,<br/>repeat bounded attempts
    
    Orchestrator->>GitHub: Post reply templates to comment threads
    GitHub-->>Orchestrator: Confirmation
    Orchestrator->>GitHub: Resolve review threads via GraphQL
    GitHub-->>Orchestrator: Resolution confirmation
    Orchestrator-->>User: Display PR readiness verdict<br/>& reply summary table
Loading

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@default/skills/pr-review-multi-source/SKILL.md`:
- Around line 107-120: The gh REST API calls used to collect review comments in
the SKILL.md (the commands "gh api repos/{owner}/{repo}/pulls/{number}/reviews"
and "gh api repos/{owner}/{repo}/pulls/{number}/comments") do not include
pagination and will miss items beyond the first page; update both commands to
include the --paginate flag so they become paginated requests (use --paginate
with the existing gh api calls for reviews and comments) to ensure complete
comment collection across all pages.
- Around line 519-540: The current GraphQL query and matching logic uses
comments.nodes[0].databaseId which is deprecated and fragile; update the query
to request reviewThreads { comments(first: 100) { nodes { id body } } } (keep
reviewThreads and comments fields) and change the matching logic to compare the
REST comment's node_id (global GraphQL node ID collected in Step 0.3) against
any comment's id in comments.nodes[*] rather than only the first comment or
databaseId so threads are matched reliably.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e0910bec-adf4-4cf2-bf94-9ab741043547

📥 Commits

Reviewing files that changed from the base of the PR and between 9011f82 and 7e681c5.

📒 Files selected for processing (1)
  • default/skills/pr-review-multi-source/SKILL.md

Comment on lines +107 to +120
### Step 0.3: Collect Existing PR Comments

Collect ALL comments from ALL sources on the PR:

**General PR comments:**
```bash
gh pr view <PR_NUMBER_OR_URL> --comments
```

**Review comments (inline code comments and review summaries):**
```bash
gh api repos/{owner}/{repo}/pulls/{number}/reviews
gh api repos/{owner}/{repo}/pulls/{number}/comments
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

GitHub CLI docs: does gh api repos/{owner}/{repo}/pulls/{number}/commentsrequire--paginate to fetch all PR comments beyond default page size?

💡 Result:

Yes. gh api repos/{owner}/{repo}/pulls/{number}/comments hits a paginated REST endpoint that returns 30 items per page by default (max per_page=100) [2]. gh api will only return the first page unless you add --paginate, which “fetch[es] all pages of results” by following pagination links until exhausted [1].

Example:

gh api repos/OWNER/REPO/pulls/NUMBER/comments --paginate
# (optional) maximize page size:
gh api repos/OWNER/REPO/pulls/NUMBER/comments --paginate -f per_page=100

Sources: [1] GitHub CLI gh api manual (--paginate), [2] GitHub REST docs for “List review comments on a pull request” (default per_page=30).


🏁 Script executed:

cd default/skills/pr-review-multi-source && wc -l SKILL.md

Repository: LerianStudio/ring

Length of output: 73


🏁 Script executed:

cd default/skills/pr-review-multi-source && sed -n '100,150p' SKILL.md

Repository: LerianStudio/ring

Length of output: 1969


🏁 Script executed:

cd default/skills/pr-review-multi-source && sed -n '130,150p' SKILL.md

Repository: LerianStudio/ring

Length of output: 831


🏁 Script executed:

cd default/skills/pr-review-multi-source && grep -n "gh api repos/{owner}/{repo}/pulls/{number}" SKILL.md

Repository: LerianStudio/ring

Length of output: 229


🏁 Script executed:

cd default/skills/pr-review-multi-source && sed -n '110,145p' SKILL.md

Repository: LerianStudio/ring

Length of output: 1456


🏁 Script executed:

cd default/skills/pr-review-multi-source && sed -n '135,145p' SKILL.md

Repository: LerianStudio/ring

Length of output: 318


🏁 Script executed:

cd default/skills/pr-review-multi-source && sed -n '495,510p' SKILL.md

Repository: LerianStudio/ring

Length of output: 408


🏁 Script executed:

cd default/skills/pr-review-multi-source && sed -n '490,520p' SKILL.md

Repository: LerianStudio/ring

Length of output: 772


🏁 Script executed:

cd default/skills/pr-review-multi-source && sed -n '495,505p' SKILL.md | cat -n

Repository: LerianStudio/ring

Length of output: 380


🏁 Script executed:

cd default/skills/pr-review-multi-source && sed -n '115,125p' SKILL.md | cat -n

Repository: LerianStudio/ring

Length of output: 645


🏁 Script executed:

cd default/skills/pr-review-multi-source && sed -n '135,142p' SKILL.md | cat -n

Repository: LerianStudio/ring

Length of output: 339


Add --paginate flag to REST API calls for complete comment collection.

At lines 118-119, the commands lack pagination, which defaults to 30 items per page. Larger PRs will have truncated results:

gh api repos/{owner}/{repo}/pulls/{number}/reviews
gh api repos/{owner}/{repo}/pulls/{number}/comments

Update both to:

gh api --paginate repos/{owner}/{repo}/pulls/{number}/reviews
gh api --paginate repos/{owner}/{repo}/pulls/{number}/comments
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@default/skills/pr-review-multi-source/SKILL.md` around lines 107 - 120, The
gh REST API calls used to collect review comments in the SKILL.md (the commands
"gh api repos/{owner}/{repo}/pulls/{number}/reviews" and "gh api
repos/{owner}/{repo}/pulls/{number}/comments") do not include pagination and
will miss items beyond the first page; update both commands to include the
--paginate flag so they become paginated requests (use --paginate with the
existing gh api calls for reviews and comments) to ensure complete comment
collection across all pages.

Comment on lines +519 to +540
To get the thread node ID, query the PR's review threads:
```bash
gh api graphql -f query='
query {
repository(owner: "<owner>", name: "<repo>") {
pullRequest(number: <number>) {
reviewThreads(first: 100) {
nodes {
id
isResolved
comments(first: 1) {
nodes { body databaseId }
}
}
}
}
}
}
'
```

Match each thread by its first comment's `databaseId` to the `comment_id` collected in Step 0.3, then resolve using the thread's `id`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

GitHub GraphQL API PullRequest.reviewThreads: best practice to map a REST PR review comment id (databaseId) back to the correct ReviewThread.id when a thread has multiple comments.

💡 Result:

Best practice: don’t map from the REST comment id/GraphQL databaseId if you can avoid it. Instead, use the REST comment’s node_id (global GraphQL node ID) and then find the thread that contains that comment.

Why

  • GitHub’s GraphQL databaseId is deprecated and not future-proof. Use global id / node_id instead. [2]
  • A PullRequestReviewComment in GraphQL does not expose a “parent thread id” field, so the only reliable way to get the ReviewThread.id is: list threads → inspect their comments → match (commonly recommended/used in practice). [3]

Recommended mapping algorithm

  1. From REST GET /repos/{owner}/{repo}/pulls/comments/{comment_id}, take node_id (not id). [1]
  2. Query the PR’s reviewThreads, requesting each thread’s id and its comments’ id values.
  3. Find the thread where any comment’s id == the REST node_id. That thread’s id is the ReviewThread.id you want.
  4. If the thread has many comments, paginate reviewThreads and/or comments until you find it.

Example GraphQL query shape:

query($owner:String!, $repo:String!, $pr:Int!, $after:String) {
  repository(owner:$owner, name:$repo) {
    pullRequest(number:$pr) {
      reviewThreads(first:100, after:$after) {
        pageInfo { hasNextPage endCursor }
        nodes {
          id
          comments(first:100) {
            pageInfo { hasNextPage endCursor }
            nodes { id }  # compare to REST node_id
          }
        }
      }
    }
  }
}

If you only have the REST numeric id

You can still match against comments.nodes.databaseId, but treat it as a fallback only (deprecated). [2]

Practical tip (if you control creation time)

If you create threads/comments via GraphQL, store the returned PullRequestReviewThread.id at creation time, so you don’t need to re-discover it later by scanning.

Sources: REST review comment payload includes id + node_id. [1] databaseId deprecation in GraphQL. [2] Community/StackOverflow guidance: to map comment → thread you typically must enumerate reviewThreads and filter by contained comments. [3]


Use global node IDs and match against all thread comments, not deprecated databaseId.

Matching by only the first comment's databaseId is fragile for threads with multiple comments. However, the deeper issue is that databaseId is deprecated in GitHub's GraphQL API.

Recommended approach:

  1. Use the REST comment's node_id (global GraphQL node ID) instead of numeric id
  2. Query reviewThreads with comments(first: 100) and fetch each comment's global id field
  3. Match the REST node_id against any comment's id in the thread

This is more reliable than databaseId and aligns with GitHub's recommended practices.

Updated query structure
- comments(first: 1) {
-   nodes { body databaseId }
- }
+ comments(first: 100) {
+   nodes { id }
+ }

Match REST node_id against the thread's comments.nodes[*].id.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@default/skills/pr-review-multi-source/SKILL.md` around lines 519 - 540, The
current GraphQL query and matching logic uses comments.nodes[0].databaseId which
is deprecated and fragile; update the query to request reviewThreads {
comments(first: 100) { nodes { id body } } } (keep reviewThreads and comments
fields) and change the matching logic to compare the REST comment's node_id
(global GraphQL node ID collected in Step 0.3) against any comment's id in
comments.nodes[*] rather than only the first comment or databaseId so threads
are matched reliably.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant