
Qodo Pr Resolver
- 2.3k installs
- 44 repo stars
- Updated August 2, 2026
- qodo-ai/qodo-skills
qodo-pr-resolver fetches Qodo PR issues, applies fixes, and replies on major git hosting providers.
About
Qodo PR Resolver fetches AI review issues for the current branch pull request, fixes them interactively or in batch, and replies to inline comments on supported git hosts. Prerequisites require git, a provider CLI such as gh or glab, an open reviewed PR from bots like pr-agent-pro or qodo-merge, and tracked-file awareness when checking uncommitted changes. Step zero handles uncommitted or unpushed work with warnings before review because Qodo only sees pushed commits. Provider detection reads origin URL patterns documented per host in providers.md including Gerrit Change-Id lookup. Issue types include PR Compliance Guide, PR Code Suggestions, and structured Code Review by Qodo with severity sections. Workflow fetches comments, presents issues by severity, applies selected fixes, and posts resolution replies with optional fix summaries. JUST_PUSHED tracking waits for fresh Qodo runs after push. Gerrit, Azure DevOps, and Bitbucket paths use curl or az variants per resources. The skill supports interactive triage rather than blind batch application of every suggestion.
- Supports GitHub, GitLab, Bitbucket, Azure DevOps, and Gerrit PRs.
- Detects pr-agent-pro and qodo-merge bot review comments.
- Step zero warns on uncommitted or unpushed commits before fetch.
- Applies fixes interactively or in batch with inline replies.
- Uses provider-specific commands from resources/providers.md.
Qodo Pr Resolver by the numbers
- 2,258 all-time installs (skills.sh)
- +18 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #70 of 1,352 Code Review & Quality skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 4, 2026 (Skillselion catalog sync)
qodo-pr-resolver capabilities & compatibility
- Capabilities
- multi provider pr and mr discovery · qodo bot comment parsing by severity · push and commit hygiene checks · interactive and batch fix application · inline reply and fix summary posting
- Works with
- github · gitlab · bitbucket · azure devops
- Use cases
- code review · testing · debugging
- Runs
- Runs locally
- Pricing
- Freemium
What qodo-pr-resolver says it does
Qodo hasn't reviewed them yet.
npx skills add https://github.com/qodo-ai/qodo-skills --skill qodo-pr-resolverAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2.3k |
|---|---|
| repo stars | ★ 44 |
| Security audit | 1 / 3 scanners passed |
| Last updated | August 2, 2026 |
| Repository | qodo-ai/qodo-skills ↗ |
How do I see and fix Qodo review comments on my open pull request?
Fetch Qodo PR review issues, apply fixes interactively or in batch, and reply on GitHub, GitLab, Bitbucket, Azure DevOps, or Gerrit.
Who is it for?
Branches with Qodo bot reviews on GitHub, GitLab, or enterprise git hosts.
Skip if: Skip when no Qodo review exists on the open PR or provider CLI is unavailable.
When should I use this skill?
User asks to fix Qodo comments, resolve PR issues, or run qodo pr resolver.
What you get
Resolved Qodo issues with code fixes and inline replies documenting decisions.
- Resolved Gerrit review threads
- Tagged Qodo comment replies
Files
Qodo PR Resolver
Fetch Qodo review issues for your current branch's PR/MR, fix them interactively or in batch, and reply to each inline comment with the decision. Supports GitHub, GitLab, Bitbucket, Azure DevOps, and Gerrit.
Prerequisites
Required Tools:
- Git - For branch operations
- Git Provider CLI - One of:
gh(GitHub),glab(GitLab),curl(Bitbucket/Gerrit), oraz(Azure DevOps)
Installation and authentication details: See providers.md for provider-specific setup instructions.
Required Context:
- Must be in a git repository
- Repository must be hosted on a supported git provider (GitHub, GitLab, Bitbucket, Azure DevOps, or Gerrit)
- Current branch must have an open PR/MR (or Gerrit change)
- PR/MR must have been reviewed by Qodo (pr-agent-pro bot, qodo-merge[bot], etc.)
Quick Check:
git --version # Check git installed
git remote get-url origin # Identify git providerSee providers.md for provider-specific verification commands.
Understanding Qodo Reviews
Qodo (formerly Codium AI) is an AI-powered code review tool that analyzes PRs/MRs with compliance checks, bug detection, and code quality suggestions.
Bot Identifiers
Look for comments from: `pr-agent-pro`, `pr-agent-pro-staging`, `qodo-merge[bot]`, `qodo-ai[bot]`
Review Comment Types
1. PR Compliance Guide 🔍 - Security/ticket/custom compliance with 🟢/🟡/🔴/⚪ indicators 2. PR Code Suggestions ✨ - Categorized improvements with importance ratings 3. Code Review by Qodo - Structured issues with 🐞/📘/📎 sections and agent prompts (most detailed)
Instructions
When the user asks for a code review, to see Qodo issues, or fix Qodo comments:
Step 0: Check code push status
Check for uncommitted changes, unpushed commits, and get the current branch.
Note: Only consider tracked files when checking for uncommitted changes. Untracked files (scripts, local configs, etc.) that are not part of the repository should be ignored. Use git diff --name-only and git diff --cached --name-only rather than git status --porcelain which includes untracked files.
Scenario A: Uncommitted changes exist
- Inform: "⚠️ You have uncommitted changes. These won't be included in the Qodo review."
- Ask: "Would you like to commit and push them first?"
- If yes: Wait for user action, then proceed to Step 1
- If no: Warn "Proceeding with review of pushed code only" and continue to Step 1
Scenario B: Unpushed commits exist
(no uncommitted changes)
- Inform: "⚠️ You have N unpushed commits. Qodo hasn't reviewed them yet."
- Ask: "Would you like to push them now?"
- If yes: Execute
git push, inform "Pushed! Qodo will review shortly." Record internallyJUST_PUSHED = true. Continue to Step 1 (the Wait for Qodo review flow in Step 3a will handle the waiting). - If no: Warn "Proceeding with existing PR review" and continue to Step 1
Scenario C: Everything pushed
(both uncommitted changes and unpushed commits are empty)
- Proceed to Step 1
Step 1: Detect git provider
Detect git provider from the remote URL (git remote get-url origin).
See providers.md for provider detection patterns. For Gerrit, also check for .gitreview file, port 29418 in remote URL, or googlesource.com — see gerrit.md.
Step 2: Find the open PR/MR
Find the open PR/MR for this branch using the provider's CLI.
See providers.md § Find Open PR/MR for provider-specific commands. For Gerrit, look up the change using the Change-Id from the HEAD commit message — see gerrit.md § Find Open Change.
Step 3: Get Qodo review comments
Get the Qodo review comments using the provider's CLI.
Qodo typically posts both a summary comment (PR-level, containing all issues) and inline review comments (one per issue, attached to specific lines of code). You must fetch both.
See providers.md § Fetch Review Comments for provider-specific commands.
Look for comments where the author is "qodo-merge[bot]", "pr-agent-pro", "pr-agent-pro-staging" or similar Qodo bot name.
Gerrit note: Qodo posts as tagged human comments via /comments with tag: "autogenerated:qodo". Also check change messages (/messages) for the summary comment. Filter by tag field or bot username. See gerrit.md § Fetch Review Comments.
Step 3a: Check if review is ready / Wait for Qodo review
Check if the Qodo review is complete:
- If any comment contains "Come back again in a few minutes" or "An AI review agent is analysing this pull request", the review is still running
- If no Qodo bot comments are found at all, the review hasn't started yet
If the review is not ready (in progress, not started, or we just pushed/created a PR):
1. Ask using AskUserQuestion: "⏳ Qodo review is not ready yet. Would you like to wait for it to complete?"
- Options: "Wait for review" (Recommended) / "Exit and come back later"
2. If "Exit and come back later": Inform "Run this skill again in a few minutes once Qodo has reviewed the PR." Exit skill. 3. If "Wait for review":
- Inform: "Monitoring for Qodo review completion (checking every 30 seconds)..."
- Use the Monitor tool to poll for review completion:
description: "Waiting for Qodo review on PR #<number>"timeout_ms:600000(10 minutes)persistent:falsecommand: A polling script that runs in awhile true; do ... sleep 30; doneloop. The script should use the same provider-specific comment-fetch commands from Step 3 (Fetch Review Comments) to check for Qodo bot comments. If Qodo comments are found AND they do not contain "Come back again in a few minutes" or "An AI review agent is analysing this pull request", outputREVIEW_COMPLETEand exit. Use|| trueon API calls for transient failure resilience.- When the Monitor emits
REVIEW_COMPLETE: Inform "Qodo review is ready!" and return to Step 3 to fetch and parse the review comments normally. - If the Monitor times out (10 minutes): Inform "Qodo review hasn't appeared yet. You can run this skill again later." Exit skill.
If the review is ready (Qodo comments found, no "in progress" markers): Proceed directly to Step 3b.
Step 3b: Deduplicate issues
Deduplicate issues across summary and inline comments:
- Qodo posts each issue in two places: once in the summary comment (PR-level) and once as an inline review comment (attached to the specific code line). These will share the same issue title.
- Qodo may also post multiple summary comments (Compliance Guide, Code Suggestions, Code Review, etc.) where issues can overlap with slightly different wording.
- Deduplicate by matching on issue title (primary key - the same title means the same issue):
- If an issue appears in both the summary comment and as an inline comment, merge them into a single issue
- Prefer the inline comment for file location (it has the exact line context)
- Prefer the summary comment for severity, type, and agent prompt (it is more detailed)
- IMPORTANT: Preserve each issue's inline review comment ID — you will need it later (Step 8) to reply directly to that comment with the decision
- Also deduplicate across multiple summary comments by location (file path + line numbers) as a secondary key
- If the same issue appears in multiple places, combine the agent prompts
Gerrit deduplication: Qodo inline comments contain an Agent Prompt section (rendered as plain text — Gerrit doesn't support expandable blocks) with detailed fix instructions. When deduplicating, preserve the Agent Prompt from each unique finding.
Step 4: Parse and display the issues
- Extract the review body/comments from Qodo's review
- Parse out individual issues/suggestions
- IMPORTANT: Preserve Qodo's exact issue titles verbatim — do not rename, paraphrase, or summarize them. Use the title exactly as Qodo wrote it.
- IMPORTANT: Preserve Qodo's original ordering — display issues in the same order Qodo listed them. Qodo already orders by severity.
- Extract location, issue description, and suggested fix
- Extract the agent prompt from Qodo's suggestion (the description of what needs to be fixed)
Severity mapping
Derive severity from Qodo's action level and position:
1. Action level determines severity range:
- "Action required" issues → Can only be 🔴 CRITICAL or 🟠 HIGH
- "Review recommended" / "Remediation recommended" issues → Can only be 🟡 MEDIUM or ⚪ LOW
- "Other" / "Advisory comments" issues → Always ⚪ LOW (lowest priority)
2. Qodo's position within each action level determines the specific severity:
- Group issues by action level ("Action required" vs "Review recommended" vs "Other")
- Within "Action required" and "Review recommended" groups: earlier positions → higher severity, later positions → lower severity
- Split point: roughly first half of each group gets the higher severity, second half gets the lower
- All "Other" issues are treated as ⚪ LOW regardless of position
Example: 7 "Action required" issues would be split as:
- Issues 1-3: 🔴 CRITICAL
- Issues 4-7: 🟠 HIGH
- Result: No MEDIUM or LOW issues (because there are no "Review recommended" or "Other" issues)
Example: 5 "Action required" + 3 "Review recommended" + 2 "Other" issues would be split as:
- Issues 1-2 or 1-3: 🔴 CRITICAL (first ~half of "Action required")
- Issues 3-5 or 4-5: 🟠 HIGH (second ~half of "Action required")
- Issues 6-7: 🟡 MEDIUM (first ~half of "Review recommended")
- Issue 8: ⚪ LOW (second ~half of "Review recommended")
- Issues 9-10: ⚪ LOW (all "Other" issues)
Action guidelines:
- 🔴 CRITICAL / 🟠 HIGH ("Action required"): Always "Fix"
- 🟡 MEDIUM ("Review recommended"): Usually "Fix", can "Defer" if low impact
- ⚪ LOW ("Review recommended" or "Other"): Can be "Defer" unless quick to fix; "Other" issues are lowest priority
Output format
IMPORTANT: Use actual Unicode emoji characters (e.g. 🔴, 🟠, 📘, ⛨, ⚙), NOT GitHub-style shortcodes (:red_circle:, :books:, :shield:). Shortcodes do not render in terminal environments.
Display as a markdown table in Qodo's exact original ordering (do NOT reorder by severity - Qodo's order IS the severity ranking):
Qodo Issues for PR #123: [PR Title]
| # | Severity | Issue Title | Issue Details | Type | Action |
|---|----------|-------------|---------------|------|--------|
| 1 | 🔴 CRITICAL | Insecure authentication check | • **Location:** src/auth/service.py:42<br><br>• **Issue:** Authorization logic is inverted | 🐞 Bug ⛨ Security | Fix |
| 2 | 🔴 CRITICAL | Missing input validation | • **Location:** src/api/handlers.py:156<br><br>• **Issue:** User input not sanitized before database query | 📘 Rule violation ⛯ Reliability | Fix |
| 3 | 🟠 HIGH | Database query not awaited | • **Location:** src/db/repository.py:89<br><br>• **Issue:** Async call missing await keyword | 🐞 Bug ✓ Correctness | Fix |Step 5: Ask user for fix preference
Single-finding shortcut: If exactly one issue was parsed in Step 4, skip this question entirely — "Review each issue" and "Auto-fix all" collapse to the same thing with one finding and are misleading. Proceed directly to Step 6 (manual review) for that single issue, regardless of its Action ("Fix" or "Defer"). Step 6's per-issue prompt always surfaces in single-finding mode, so the user is never silently skipped over.
Otherwise (two or more issues), ask the user how they want to proceed using AskUserQuestion:
Options:
- 🔍 "Review each issue" - Review and approve/defer each issue individually (recommended for careful review)
- ⚡ "Auto-fix all" - Automatically apply all fixes marked as "Fix" without individual approval (faster, but less control)
- ❌ "Cancel" - Exit without making changes
Based on the user's choice:
- If "Review each issue": Proceed to Step 6 (manual review)
- If "Auto-fix all": Skip to Step 7 (auto-fix mode - apply all "Fix" issues automatically using Qodo's agent prompts)
- If "Cancel": Exit the skill
Step 6: Review and fix issues (manual mode)
If "Review each issue" was selected:
- For each issue marked as "Fix" (starting with CRITICAL) — plus, in single-finding mode, the lone issue even if marked "Defer":
- Read the relevant file(s) to understand the current code
- Implement the fix by executing the Qodo agent prompt as a direct instruction. The agent prompt is the fix specification — follow it literally, do not reinterpret or improvise a different solution. Only deviate if the prompt is clearly outdated relative to the current code (e.g. references lines that no longer exist).
- Calculate the proposed fix in memory (DO NOT use Edit or Write tool yet)
- Present the fix and ask for approval in a SINGLE step:
1. Show a brief header with issue title and location 2. Show Qodo's agent prompt in full so the user can verify the fix matches it 3. Display current code snippet 4. Display proposed change as markdown diff 5. Immediately use AskUserQuestion with these options:
- If the issue's Action is "Fix" (default for CRITICAL/HIGH, and most MEDIUM):
- ✅ "Apply fix" - Apply the proposed change
- ⏭️ "Defer" - Skip this issue (will prompt for reason)
- 🔧 "Modify" - User wants to adjust the fix first
- If the issue's Action is "Defer" (only reachable in single-finding mode):
- ⏭️ "Confirm defer" - Keep the deferral (will prompt for reason)
- ✅ "Apply fix anyway" - Apply the proposed change despite the suggested deferral
- 🔧 "Modify" - User wants to adjust the fix first
- WAIT for user's choice via AskUserQuestion
- If "Apply fix" / "Apply fix anyway" selected:
- Apply change using Edit tool (or Write if creating new file)
- GitHub / GitLab / Bitbucket / Azure DevOps: Git commit the fix:
git add <modified-files> && git commit -m "fix: <issue title>" - Gerrit: Do NOT commit yet — stage the change (
git add <modified-files>) but wait until all fixes are applied, then amend into a single commit (see Gerrit note below) - Confirm: "✅ Fix applied!"
- Mark issue as completed
- If "Defer" / "Confirm defer" selected:
- Ask for deferral reason using AskUserQuestion
- Record reason and move to next issue
- If "Modify" selected:
- Inform user they can make changes manually
- Move to next issue
- Continue until all in-scope issues are addressed or the user decides to stop
- After all fixes are applied, reply to all Qodo inline comments in one batch (see Step 8)
Gerrit commit strategy: In Gerrit, each commit becomes a separate change. To keep all fixes as a single new patchset on the existing change: 1. Apply all fixes (Edit tool) and stage them (git add) 2. After ALL fixes are done, amend the original commit: git commit --amend --no-edit 3. Push once in Step 9
Do NOT create individual commits per fix for Gerrit.
Important notes
Single-step approval with AskUserQuestion:
- NO native Edit UI (no persistent permissions possible)
- Each fix requires explicit approval via custom question
- Clearer options, no risk of accidental auto-approval
CRITICAL: Single validation only - do NOT show the diff separately and then ask. Combine the diff display and the question into ONE message. The user should see: brief context → current code → proposed diff → AskUserQuestion, all at once.
Example: Show location, Qodo's guidance, current code, proposed diff, then AskUserQuestion with options (✅ Apply fix / ⏭️ Defer / 🔧 Modify). Wait for user choice, apply via Edit tool if approved.
Step 7: Auto-fix mode
If "Auto-fix all" was selected:
- For each issue marked as "Fix" (starting with CRITICAL):
- Read the relevant file(s) to understand the current code
- Implement the fix by executing the Qodo agent prompt as a direct instruction. The agent prompt is the fix specification — follow it literally, do not reinterpret or improvise a different solution. Only deviate if the prompt is clearly outdated relative to the current code (e.g. references lines that no longer exist).
- Apply the fix using Edit tool
- GitHub / GitLab / Bitbucket / Azure DevOps: Git commit the fix:
git add <modified-files> && git commit -m "fix: <issue title>" - Gerrit: Stage only (
git add <modified-files>) — do NOT commit yet - Report each fix with the agent prompt that was followed:
✅ Fixed: [Issue Title] at [Location]Agent prompt: [the Qodo agent prompt used]
- Mark issue as completed
- Gerrit: After ALL fixes are applied, amend into one commit:
git commit --amend --no-edit - Reply to all Qodo inline comments in one batch (see Step 8)
- After all auto-fixes are applied, display summary:
- List of all issues that were fixed
- List of any issues that were skipped (with reasons)
Step 8: Post summary and reply to comments
REQUIRED: After all issues have been reviewed (fixed or deferred), ALWAYS post a comment summarizing the actions taken, even if all issues were deferred.
See providers.md § Post Summary Comment for provider-specific commands and summary format.
Gerrit: Batch the summary comment AND all inline replies into a single API call. This is more efficient and avoids multiple email notifications. Use the unified review endpoint with both message (summary) and comments (inline replies) — see gerrit.md § Post Summary Comment.
Important resolution rules for inline replies:
- Fixed issues: set
"unresolved": false(resolves the thread) - Deferred issues: set
"unresolved": false(resolves the thread — the next Qodo review will re-evaluate)
After posting the summary, resolve the Qodo review comment:
Find the Qodo "Code Review by Qodo" comment and mark it as resolved or react to acknowledge it.
See providers.md § Resolve Qodo Review Comment for provider-specific commands.
If resolve fails (comment not found, API error), continue — the summary comment is the important part.
Step 9: Push to remote
If any fixes were applied (commits were created in Steps 6/7), ask the user if they want to push:
- If yes:
git push(for Gerrit:git push origin HEAD:refs/for/<target-branch>— this creates a new patchset on the existing change, matched by theChange-Idin the commit message. See gerrit.md § Push Changes) - If no: Inform them they can push later with
git push
Important: If all issues were deferred, there are no commits to push — skip this step.
Step 9b: Handle draft PR status
Only run this step if `DRAFT_PR_CREATED = true` (a draft PR was created earlier in this session). Skip entirely if the PR already existed or was created as a regular PR.
- Ask using AskUserQuestion: "We opened this PR as a draft. Would you like to mark it as ready for review, or keep it as a draft?"
- Options: "Mark as ready for review" / "Keep as draft"
- If "Mark as ready for review": Use provider CLI to mark PR as ready (see providers.md § Mark PR Ready for Review). Inform: "PR marked as ready for review!"
- If "Keep as draft": Inform: "PR will remain as a draft. You can mark it ready later."
Step 10: Show PR URL
After completing all steps, always echo the PR/MR URL to the user so they can easily navigate to it. Use the PR URL detected in Step 2.
Example output: 🔗 PR: https://github.com/owner/repo/pull/123 For Gerrit: 🔗 Change: https://<gerrit-host>/c/<project>/+/<change-number>
Special cases
Unsupported git provider
If the remote URL doesn't match GitHub, GitLab, Bitbucket, Azure DevOps, or Gerrit, inform the user and exit.
See providers.md § Error Handling for details.
No PR/MR exists
- Inform: "No PR/MR found for branch
<branch-name>. A PR is needed to trigger a Qodo review." - For non-Gerrit providers, ask using AskUserQuestion: "How would you like to proceed?"
- "Open draft PR" (Recommended) — Create a draft PR since the code isn't finalized yet. Use provider CLI with draft flag (see providers.md § Create PR/MR). Record internally:
DRAFT_PR_CREATED = trueand save the PR number/ID. Inform "Draft PR created!" then proceed to the Wait for Qodo review flow (Step 3a). - "Open PR" — Create a regular (non-draft) PR. Use provider CLI without draft flag (see providers.md § Create PR/MR). Set
DRAFT_PR_CREATED = false. Inform "PR created!" then proceed to the Wait for Qodo review flow (Step 3a). - "I'll open it manually" — Inform: "No problem! Open the PR yourself, then run this skill again once the PR exists and Qodo has reviewed it." Exit skill.
- For Gerrit, ask: "Would you like me to create a change?" If yes, push with
git push origin HEAD:refs/for/<branch>(see gerrit.md § Create Change). Then proceed to the Wait for Qodo review flow (Step 3a). If no, exit skill.
IMPORTANT: Do NOT proceed to Step 3b without a PR/MR. This skill only works with Qodo reviews, not manual reviews.
No Qodo review yet / Review in progress
Handled by Step 3a — proceeds to the Wait for Qodo review flow.
Missing CLI tool
If the detected provider's CLI is not installed, provide installation instructions and exit.
See providers.md § Error Handling for provider-specific installation commands.
Inline reply commands
Used per-issue in Steps 6 and 7 to reply to Qodo's inline comments:
Use the inline comment ID preserved during deduplication (Step 3b) to reply directly to Qodo's comment.
See providers.md § Reply to Inline Comments for provider-specific commands and reply format. For Gerrit, all replies go through a single unified endpoint and can be batched — see gerrit.md § Reply to Comments.
Keep replies short (one line). If a reply fails, log it and continue.
Gerrit Provider Reference
Gerrit uses Changes (not Pull Requests). All API interactions use curl + HTTP Basic Auth — there is no official Gerrit CLI.
Key differences from other providers:
- Changes are identified by a
Change-Idin the commit message (not a branch name) - Push for review:
git push origin HEAD:refs/for/<target-branch>(notgit push) - All comment operations go through a single unified endpoint (
POST /revisions/current/review) - Qodo posts as tagged human comments with
tag: "autogenerated:qodo"(not robot comments) - All API responses are prefixed with
)]}'— must strip before JSON parsing
Provider Detection
Gerrit detection is multi-signal (checked after GitHub/GitLab/Bitbucket/Azure DevOps):
1. `.gitreview` file in repo root (strongest signal) — parse host and project from it 2. Port `29418` in SSH remote URL 3. `googlesource.com` in remote URL (Google-hosted Gerrit)
# Check for .gitreview file
if [ -f .gitreview ]; then
GERRIT_HOST=$(git config -f .gitreview gerrit.host 2>/dev/null)
GERRIT_PROJECT=$(git config -f .gitreview gerrit.project 2>/dev/null)
fi
# Check remote URL patterns
REMOTE_URL=$(git remote get-url origin)
echo "$REMOTE_URL" | grep -qE ':29418/' && echo "Gerrit (SSH)"
echo "$REMOTE_URL" | grep -q 'googlesource.com' && echo "Gerrit (Google)"Prerequisites
Authentication
HTTP Basic Auth with a password generated from Gerrit's settings page.
Qodo config (~/.qodo/config.json) — store credentials persistently:
{
"GERRIT_URL": "https://review.example.com",
"GERRIT_USERNAME": "your-username",
"GERRIT_HTTP_PASSWORD": "your-http-password"
}GERRIT_URL: Gerrit instance base URL (always required — there is no default host)GERRIT_USERNAME: Your Gerrit usernameGERRIT_HTTP_PASSWORD: HTTP password from Settings → HTTP Credentials (this is NOT your account password)
Extract project info from .gitreview
GERRIT_PROJECT=$(git config -f .gitreview gerrit.project 2>/dev/null)
TARGET_BRANCH=$(git config -f .gitreview gerrit.defaultbranch 2>/dev/null || echo "main")Magic JSON prefix
All Gerrit REST API responses start with )]}' on the first line (XSS protection). Strip it before parsing:
| tail -c +6 | python3 -m json.toolEvery curl command in this file includes this pipe.
Verify
curl -s -u "$GERRIT_USERNAME:$GERRIT_HTTP_PASSWORD" \
"$GERRIT_URL/a/accounts/self" | tail -c +6 | python3 -m json.toolNote: All authenticated endpoints use the /a/ prefix in the path. Some Gerrit instances also have an API prefix (e.g. /r/) — if GERRIT_URL includes it (e.g. https://git-master.example.com/r), the full path becomes /r/a/changes/....
Find Open Change
Gerrit has no "source branch" concept. Changes are identified by Change-Id from the commit message.
Extract Change-Id from commit
CHANGE_ID=$(git log -1 --format=%b | grep 'Change-Id:' | sed 's/.*Change-Id: //')Query by Change-Id (preferred)
curl -s -u "$GERRIT_USERNAME:$GERRIT_HTTP_PASSWORD" \
"$GERRIT_URL/a/changes/?q=change:$CHANGE_ID+status:open&o=CURRENT_REVISION&o=MESSAGES" \
| tail -c +6 | python3 -m json.toolQuery by project + owner (fallback)
curl -s -u "$GERRIT_USERNAME:$GERRIT_HTTP_PASSWORD" \
"$GERRIT_URL/a/changes/?q=status:open+project:$GERRIT_PROJECT+owner:self&o=CURRENT_REVISION" \
| tail -c +6 | python3 -m json.toolResponse is a JSON array. Key fields: _number (change number), project, branch, current_revision.
Fetch Review Comments
Gerrit has three separate comment endpoints. Fetch all three.
Human comments (where Qodo posts)
Qodo posts inline comments as human comments with tag: "autogenerated:qodo". This is the primary endpoint to check.
Filter for Qodo: check tag field equals "autogenerated:qodo", or author.username matches the Qodo bot user (e.g. "svc-qodo-gerrit", "qodo-bot").
curl -s -u "$GERRIT_USERNAME:$GERRIT_HTTP_PASSWORD" \
"$GERRIT_URL/a/changes/<change-id>/comments" \
| tail -c +6 | python3 -m json.toolResponse: map of file paths to arrays of comment objects. Key fields: id, tag, author, path, line, range, message, unresolved.
Change messages (top-level / summary)
curl -s -u "$GERRIT_USERNAME:$GERRIT_HTTP_PASSWORD" \
"$GERRIT_URL/a/changes/<change-id>/messages" \
| tail -c +6 | python3 -m json.toolReturns array of message objects with id, author, message, date.
Qodo comment structure
Qodo inline comments contain:
- The issue description with severity and category
- An expandable Agent Prompt section with detailed fix instructions
- Rule citations (e.g.
CODING-SAFETY-001) when compliance rules are configured
Parse the comment message field for the issue text. The Agent Prompt appears after a **Agent Prompt** header in the comment body (Gerrit doesn't support expandable <details> tags, so it renders as plain text).
Reply to Comments
All comment operations use a single unified endpoint:
POST /a/changes/<change-id>/revisions/current/reviewReply to an inline comment (human or robot)
curl -s -u "$GERRIT_USERNAME:$GERRIT_HTTP_PASSWORD" \
-H "Content-Type: application/json" \
-X POST \
"$GERRIT_URL/a/changes/<change-id>/revisions/current/review" \
-d '{
"comments": {
"<file-path>": [{
"in_reply_to": "<comment-id>",
"message": "<reply-body>",
"unresolved": false
}]
}
}' | tail -c +6in_reply_to: the comment'sidfield (works for both robot and human comments)unresolved: falseresolves the thread in the same call — no separate resolve step needed
Reply format (same as other providers):
- Fixed:
✅ **Fixed** — <brief description>— set"unresolved": false - Deferred:
⏭️ **Deferred** — <reason>— set"unresolved": false
Resolution of deferred items will be re-evaluated by the next Qodo review when a new patchset is pushed.
Batch multiple replies
Multiple replies across files can be combined in a single request:
{
"comments": {
"file1.py": [{"in_reply_to": "id1", "message": "Fixed", "unresolved": false}],
"file2.py": [{"in_reply_to": "id2", "message": "Deferred", "unresolved": false}]
}
}Post Summary Comment
Uses the same unified endpoint with the message field:
curl -s -u "$GERRIT_USERNAME:$GERRIT_HTTP_PASSWORD" \
-H "Content-Type: application/json" \
-X POST \
"$GERRIT_URL/a/changes/<change-id>/revisions/current/review" \
-d '{"message": "<summary-comment-body>"}' | tail -c +6Optimization: Summary and all inline replies can be batched in a single request:
{
"message": "## Qodo Fix Summary\n...",
"comments": {
"file1.py": [{"in_reply_to": "id1", "message": "Fixed", "unresolved": false}]
}
}Summary format: same as providers.md § Summary format.
Resolve Comments
Resolution is part of the reply — set "unresolved": false in the reply payload.
No separate resolve API call is needed. If replies in the Reply step already set "unresolved": false, all resolved issues are handled automatically.
To resolve without replying (empty message):
{
"comments": {
"<file-path>": [{
"in_reply_to": "<comment-id>",
"message": "",
"unresolved": false
}]
}
}Push Changes
Gerrit does not use normal git push.
Push to existing change (new patch set)
TARGET_BRANCH=$(git config -f .gitreview gerrit.defaultbranch 2>/dev/null || echo "main")
git push origin HEAD:refs/for/$TARGET_BRANCHThis creates a new patch set on the existing change (matched by Change-Id in commit message).
Push with topic
git push origin HEAD:refs/for/$TARGET_BRANCH%topic=qodo-fixesCreate Change
No API call needed — pushing creates the change automatically:
TARGET_BRANCH=$(git config -f .gitreview gerrit.defaultbranch 2>/dev/null || echo "main")
git push origin HEAD:refs/for/$TARGET_BRANCHThe commit must have a Change-Id footer. If missing, install the commit-msg hook:
curl -sLo .git/hooks/commit-msg $GERRIT_URL/tools/hooks/commit-msg && chmod +x .git/hooks/commit-msgError Handling
Missing environment variables
If GERRIT_URL, GERRIT_USERNAME, or GERRIT_HTTP_PASSWORD is unset:
- Inform: "Missing Gerrit authentication. Add these to
~/.qodo/config.json:" - List all three keys with descriptions
- Exit the skill
No Change-Id in commit
If Change-Id grep returns empty:
- Inform: "No Change-Id found in commit message."
- Suggest installing the hook:
curl -sLo .git/hooks/commit-msg $GERRIT_URL/tools/hooks/commit-msg && chmod +x .git/hooks/commit-msg - Exit the skill
API authentication failure (HTTP 401)
- Inform: "Gerrit authentication failed. Check
GERRIT_USERNAMEandGERRIT_HTTP_PASSWORD." - Note: HTTP password is generated at Settings → HTTP Credentials, not the account password
- Exit the skill
Recovery: squash accidental per-fix commits
If separate commits were accidentally created (one per fix), squash them before pushing:
# Find the original change commit (the one with the Change-Id)
ORIGINAL=$(git log --format=%H --grep="Change-Id:" | head -1)
git reset --soft $ORIGINAL
git commit --amend --no-edit
git push origin HEAD:refs/for/$TARGET_BRANCHChange URL format
For Step 10 (Show PR URL), the Gerrit change URL is:
🔗 Change: https://<gerrit-host>/c/<project>/+/<change-number>Git Provider Commands Reference
This document contains all provider-specific CLI commands and API interactions for the Qodo PR Resolver skill. Reference this file when implementing provider-specific operations.
Supported Providers
- GitHub (via
ghCLI) - GitLab (via
glabCLI) - Bitbucket (via REST API with
curl) - Azure DevOps (via
azCLI with DevOps extension) - Gerrit (via REST API with
curl) — see gerrit.md
Provider Detection
Detect the git provider from the remote URL:
git remote get-url originMatch against:
github.com→ GitHubgitlab.com→ GitLabbitbucket.org→ Bitbucketdev.azure.com→ Azure DevOps.gitreviewfile or port29418orgooglesource.com→ Gerrit (see gerrit.md)
Prerequisites by Provider
GitHub
CLI: gh
- Install:
brew install ghor cli.github.com - Authenticate:
gh auth login - Verify:
gh --version && gh auth statusGitLab
CLI: glab
- Install:
brew install glabor glab.readthedocs.io - Authenticate:
glab auth login - Verify:
glab --version && glab auth statusBitbucket
Authentication: Bitbucket REST API with an App Password (there is no official bb CLI)
- Create an App Password: Bitbucket → Settings → App passwords
- Required scopes: Repositories: Read, Pull requests: Read, Write
- Qodo config (
~/.qodo/config.json) — store credentials persistently:
{
"BB_USERNAME": "your-bitbucket-username",
"BB_APP_PASSWORD": "your-app-password",
"BB_URL": "https://bitbucket.example.com"
}BB_URL is optional — only needed for self-hosted Bitbucket (defaults to https://api.bitbucket.org).
- Workspace and repo slug are extracted from the remote URL at runtime:
BB_REMOTE=$(git remote get-url origin)
BB_WORKSPACE=$(echo "$BB_REMOTE" | sed -E 's|.*bitbucket\.org[:/]([^/]+)/.*|\1|')
BB_REPO=$(echo "$BB_REMOTE" | sed -E 's|.*bitbucket\.org[:/][^/]+/([^/.]+)(\.git)?$|\1|')- Verify:
curl -s -u "$BB_USERNAME:$BB_APP_PASSWORD" \
"https://api.bitbucket.org/2.0/user" | python3 -m json.toolAzure DevOps
CLI: az with DevOps extension
- Install:
brew install azure-clior docs.microsoft.com/cli/azure - Install extension:
az extension add --name azure-devops - Qodo config (
~/.qodo/config.json) — optional, for non-interactive auth:
{
"AZURE_DEVOPS_EXT_PAT": "your-personal-access-token",
"AZURE_DEVOPS_URL": "https://dev.azure.com"
}AZURE_DEVOPS_EXT_PAT replaces az login. AZURE_DEVOPS_URL is optional — only needed for on-premises Azure DevOps Server.
- Authenticate and configure:
az login
# Extract org/project from remote URL and configure defaults:
ADO_REMOTE=$(git remote get-url origin)
ADO_ORG=$(echo "$ADO_REMOTE" | sed -E 's|https://[^@]*@?dev\.azure\.com/([^/]+)/.*|\1|')
ADO_PROJECT=$(echo "$ADO_REMOTE" | sed -E 's|https://[^/]*/[^/]+/([^/]+)/.*|\1|')
ADO_REPO=$(echo "$ADO_REMOTE" | sed -E 's|.*/([^/]+)$|\1|')
az devops configure --defaults organization=https://dev.azure.com/$ADO_ORG project=$ADO_PROJECT
# Get repository ID (required for thread API calls):
ADO_REPO_ID=$(az repos show --name $ADO_REPO --query id -o tsv)- Verify:
az --version && az devops configure --listFind Open PR/MR
Get the PR/MR number for the current branch:
GitHub
gh pr list --head <branch-name> --state open --json number,titleGitLab
glab mr list --source-branch <branch-name>Bitbucket
BRANCH=$(git branch --show-current)
curl -s -u "$BB_USERNAME:$BB_APP_PASSWORD" \
"https://api.bitbucket.org/2.0/repositories/$BB_WORKSPACE/$BB_REPO/pullrequests?state=OPEN" \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
branch = '$BRANCH'
for pr in data.get('values', []):
if pr['source']['branch']['name'] == branch:
print(json.dumps({'id': pr['id'], 'title': pr['title']}, indent=2))
"Azure DevOps
az repos pr list --source-branch <branch-name> --status active --output jsonFetch Review Comments
Qodo posts both summary comments (PR-level) and inline review comments (per-line). Fetch both.
GitHub
# PR-level comments (includes the summary comment with all issues)
gh pr view <pr-number> --json comments
# Inline review comments (per-line comments on specific code)
gh api repos/{owner}/{repo}/pulls/<pr-number>/commentsGitLab
# All MR notes including inline comments
glab mr view <mr-iid> --commentsBitbucket
# All PR comments including inline comments
curl -s -u "$BB_USERNAME:$BB_APP_PASSWORD" \
"https://api.bitbucket.org/2.0/repositories/$BB_WORKSPACE/$BB_REPO/pullrequests/<pr-id>/comments"Azure DevOps
# List all PR threads (includes both summary and inline comments)
# Note: az repos pr thread subcommands do not exist — use az devops invoke
az devops invoke \
--area git \
--resource pullRequestThreads \
--route-parameters project=$ADO_PROJECT repositoryId=$ADO_REPO_ID pullRequestId=<pr-id> \
--http-method GET \
--api-version 7.1 \
--output jsonReply to Inline Comments
Use the inline comment ID preserved during deduplication to reply directly to Qodo's comments.
GitHub
gh api repos/{owner}/{repo}/pulls/<pr-number>/comments/<inline-comment-id>/replies \
-X POST \
-f body='<reply-body>'Reply format:
- Fixed:
✅ **Fixed** — <brief description of what was changed> - Deferred:
⏭️ **Deferred** — <reason for deferring>
GitLab
glab api "/projects/:id/merge_requests/<mr-iid>/discussions/<discussion-id>/notes" \
-X POST \
-f body='<reply-body>'Bitbucket
curl -s -u "$BB_USERNAME:$BB_APP_PASSWORD" \
-H "Content-Type: application/json" \
-X POST \
"https://api.bitbucket.org/2.0/repositories/$BB_WORKSPACE/$BB_REPO/pullrequests/<pr-id>/comments" \
-d '{"content": {"raw": "<reply-body>"}, "parent": {"id": <inline-comment-id>}}'Azure DevOps
# Add a reply comment to an existing thread (az repos pr thread does not exist)
echo '{"content": "<reply-body>", "commentType": 1}' > /tmp/ado_comment.json
az devops invoke \
--area git \
--resource pullRequestThreadComments \
--route-parameters project=$ADO_PROJECT repositoryId=$ADO_REPO_ID pullRequestId=<pr-id> threadId=<thread-id> \
--http-method POST \
--api-version 7.1 \
--in-file /tmp/ado_comment.json \
--output jsonPost Summary Comment
After reviewing all issues, post a summary comment to the PR/MR.
GitHub
gh pr comment <pr-number> --body '<comment-body>'GitLab
glab mr comment <mr-iid> --message '<comment-body>'Bitbucket
curl -s -u "$BB_USERNAME:$BB_APP_PASSWORD" \
-H "Content-Type: application/json" \
-X POST \
"https://api.bitbucket.org/2.0/repositories/$BB_WORKSPACE/$BB_REPO/pullrequests/<pr-id>/comments" \
-d '{"content": {"raw": "<comment-body>"}}'Azure DevOps
# Create a new top-level comment thread (az repos pr thread create does not exist)
cat > /tmp/ado_thread.json << 'EOF'
{"comments": [{"content": "<comment-body>", "commentType": 1}], "status": "active"}
EOF
az devops invoke \
--area git \
--resource pullRequestThreads \
--route-parameters project=$ADO_PROJECT repositoryId=$ADO_REPO_ID pullRequestId=<pr-id> \
--http-method POST \
--api-version 7.1 \
--in-file /tmp/ado_thread.json \
--output jsonSummary format:
## Qodo Fix Summary
Reviewed and addressed Qodo review issues:
### ✅ Fixed Issues
- **Issue Title** (Severity) - Brief description of what was fixed
### ⏭️ Deferred Issues
- **Issue Title** (Severity) - Reason for deferring
---
[](https://qodo.ai)
Generated by Qodo PR Resolver skill.Resolve Qodo Review Comment
After posting the summary, resolve the main Qodo review comment.
Steps: 1. Fetch all PR/MR comments 2. Find the Qodo bot comment containing "Code Review by Qodo" 3. Resolve or react to the comment
GitHub
# 1. Fetch comments to find the comment ID
gh pr view <pr-number> --json comments
# 2. React with thumbs up to acknowledge
gh api "repos/{owner}/{repo}/issues/comments/<comment-id>/reactions" \
-X POST \
-f content='+1'GitLab
# 1. Fetch discussions to find the discussion ID
glab api "/projects/:id/merge_requests/<mr-iid>/discussions"
# 2. Resolve the discussion
glab api "/projects/:id/merge_requests/<mr-iid>/discussions/<discussion-id>" \
-X PUT \
-f resolved=trueBitbucket
# Resolve a comment using the dedicated /resolve endpoint (POST, no body required)
curl -s -u "$BB_USERNAME:$BB_APP_PASSWORD" \
-X POST \
"https://api.bitbucket.org/2.0/repositories/$BB_WORKSPACE/$BB_REPO/pullrequests/<pr-id>/comments/<comment-id>/resolve"Azure DevOps
# Mark the thread as fixed (Azure DevOps uses "fixed" not "resolved"; az repos pr thread update does not exist)
echo '{"status": "fixed"}' > /tmp/ado_status.json
az devops invoke \
--area git \
--resource pullRequestThreads \
--route-parameters project=$ADO_PROJECT repositoryId=$ADO_REPO_ID pullRequestId=<pr-id> threadId=<thread-id> \
--http-method PATCH \
--api-version 7.1 \
--in-file /tmp/ado_status.json \
--output jsonCreate PR/MR
If no PR/MR exists for the current branch, create one. The user chooses between draft or regular mode — add the --draft flag when creating in draft mode.
GitHub
gh pr create --title '<title>' --body '<body>'Add --draft flag when creating in draft mode.
GitLab
glab mr create --title '<title>' --description '<body>'Add --draft flag when creating in draft mode.
Bitbucket
BRANCH=$(git branch --show-current)
curl -s -u "$BB_USERNAME:$BB_APP_PASSWORD" \
-H "Content-Type: application/json" \
-X POST \
"https://api.bitbucket.org/2.0/repositories/$BB_WORKSPACE/$BB_REPO/pullrequests" \
-d "{
\"title\": \"<title>\",
\"description\": \"<body>\",
\"source\": {\"branch\": {\"name\": \"$BRANCH\"}},
\"destination\": {\"branch\": {\"name\": \"main\"}}
}"Note: Bitbucket Cloud has no native draft PR API. When creating in draft mode, prefix the title with [DRAFT] as a convention (e.g. [DRAFT] <title>).
Azure DevOps
az repos pr create \
--title '<title>' \
--description '<body>' \
--source-branch <branch-name> \
--target-branch mainAdd --draft flag when creating in draft mode.
Mark PR Ready for Review
After all fixes are applied, if the PR was created as a draft, optionally mark it as ready for review.
GitHub
gh pr ready <pr-number>GitLab
glab mr update <mr-iid> --readyBitbucket
If the title was prefixed with [DRAFT], update it to remove the prefix:
curl -s -u "$BB_USERNAME:$BB_APP_PASSWORD" \
-H "Content-Type: application/json" \
-X PUT \
"https://api.bitbucket.org/2.0/repositories/$BB_WORKSPACE/$BB_REPO/pullrequests/<pr-id>" \
-d '{"title": "<title-without-draft-prefix>"}'Azure DevOps
az repos pr update --id <pr-id> --draft falseError Handling
Missing CLI Tool
If the detected provider's CLI is not installed: 1. Inform the user: "❌ Missing required CLI tool: <cli-name>" 2. Provide installation instructions from the Prerequisites section 3. Exit the skill
Unsupported Provider
If the remote URL doesn't match any supported provider: 1. Inform: "❌ Unsupported git provider detected: <url>" 2. List supported providers: GitHub, GitLab, Bitbucket, Azure DevOps, Gerrit 3. Exit the skill
API Failures
If inline reply or summary posting fails:
- Log the error
- Continue with remaining operations
- The workflow should not abort due to comment posting failures
Related skills
FAQ
Why are my latest changes missing?
Qodo reviews pushed commits only; commit and push or acknowledge reviewing stale code.
Which bots count as Qodo?
pr-agent-pro, pr-agent-pro-staging, qodo-merge[bot], and qodo-ai[bot] identifiers.
Does it work on Gerrit?
Yes with Change-Id lookup per gerrit.md provider detection patterns.
Is Qodo Pr Resolver safe to install?
skills.sh reports 1 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.