feat(default): add pr-review-multi-source skill (adapted from optimus)#331
feat(default): add pr-review-multi-source skill (adapted from optimus)#331gandalf-at-lerian wants to merge 1 commit intomainfrom
Conversation
WalkthroughIntroduces 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
Sequence DiagramsequenceDiagram
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
Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
default/skills/pr-review-multi-source/SKILL.md
| ### 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 | ||
| ``` |
There was a problem hiding this comment.
🧩 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=100Sources: [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.mdRepository: LerianStudio/ring
Length of output: 73
🏁 Script executed:
cd default/skills/pr-review-multi-source && sed -n '100,150p' SKILL.mdRepository: LerianStudio/ring
Length of output: 1969
🏁 Script executed:
cd default/skills/pr-review-multi-source && sed -n '130,150p' SKILL.mdRepository: 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.mdRepository: LerianStudio/ring
Length of output: 229
🏁 Script executed:
cd default/skills/pr-review-multi-source && sed -n '110,145p' SKILL.mdRepository: LerianStudio/ring
Length of output: 1456
🏁 Script executed:
cd default/skills/pr-review-multi-source && sed -n '135,145p' SKILL.mdRepository: LerianStudio/ring
Length of output: 318
🏁 Script executed:
cd default/skills/pr-review-multi-source && sed -n '495,510p' SKILL.mdRepository: LerianStudio/ring
Length of output: 408
🏁 Script executed:
cd default/skills/pr-review-multi-source && sed -n '490,520p' SKILL.mdRepository: LerianStudio/ring
Length of output: 772
🏁 Script executed:
cd default/skills/pr-review-multi-source && sed -n '495,505p' SKILL.md | cat -nRepository: LerianStudio/ring
Length of output: 380
🏁 Script executed:
cd default/skills/pr-review-multi-source && sed -n '115,125p' SKILL.md | cat -nRepository: LerianStudio/ring
Length of output: 645
🏁 Script executed:
cd default/skills/pr-review-multi-source && sed -n '135,142p' SKILL.md | cat -nRepository: 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}/commentsUpdate 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.
| 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`. |
There was a problem hiding this comment.
🧩 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
databaseIdis deprecated and not future-proof. Use globalid/node_idinstead. [2] - A
PullRequestReviewCommentin GraphQL does not expose a “parent thread id” field, so the only reliable way to get theReviewThread.idis: list threads → inspect their comments → match (commonly recommended/used in practice). [3]
Recommended mapping algorithm
- From REST
GET /repos/{owner}/{repo}/pulls/comments/{comment_id}, takenode_id(notid). [1] - Query the PR’s
reviewThreads, requesting each thread’sidand its comments’idvalues. - Find the thread where any comment’s
id== the RESTnode_id. That thread’sidis theReviewThread.idyou want. - If the thread has many comments, paginate
reviewThreadsand/orcommentsuntil 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:
- Use the REST comment's
node_id(global GraphQL node ID) instead of numericid - Query
reviewThreadswithcomments(first: 100)and fetch each comment's globalidfield - Match the REST
node_idagainst any comment'sidin 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.
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
Origin
Adapted from alexgarzao/optimus (optimus-pr-review), converted to Ring format.
cc @alexgarzao