Skip to content
Agent Orchestration
Skill

/github-pr-review

Post PR review comments using the GitHub API with inline comments, suggestions, and priority labels.

BOOST
From plugin
extensions
17185 skills4 commands
Install
$ npx -y skills add openhands/extensions --skill github-pr-review --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/github-pr-review

Context preview

The summary Claude sees to decide when to auto-load this skill.

Post PR review comments using the GitHub API with inline comments, suggestions, and priority labels.

SKILL.md

github-pr-review.SKILL.md
name: github-pr-review
description: Post PR review comments using the GitHub API with inline comments, suggestions, and priority labels.
triggers:
- /github-pr-review

GitHub PR Review

Post structured code review feedback using the GitHub API with inline comments on specific lines. Windows PowerShell equivalents for JSON file creation, temp paths, line lookup, and fallback `curl` are in `references/windows.md`.

Key Rule: One API Call

Bundle ALL comments into a **single review API call**. Do not post comments individually.

Posting a Review

Use the GitHub CLI (`gh`) with a JSON input file. The `GITHUB_TOKEN` is automatically available.

**Important**: Always use `--input` with a JSON file instead of `-F` flags. This avoids shell quoting issues with special characters in comment bodies (quotes, backticks, newlines, etc.) and eliminates the need for complex heredoc scripts.

Step 1: Create a JSON file

cat > /tmp/review.json << 'EOF'
{
  "commit_id": "{commit_sha}",
  "event": "COMMENT",
  "body": "Brief 1-3 sentence summary.",
  "comments": [
    {
      "path": "path/to/file.py",
      "line": 42,
      "side": "RIGHT",
      "body": "🟠 Important: Your comment here."
    },
    {
      "path": "another/file.js",
      "line": 15,
      "side": "RIGHT",
      "body": "🟡 Suggestion: Another comment."
    }
  ]
}
EOF

Step 2: Post the review

gh api -X POST repos/{owner}/{repo}/pulls/{pr_number}/reviews --input /tmp/review.json

Parameters

| Parameter | Description | |-----------|-------------| | `commit_id` | Commit SHA to comment on (use `git rev-parse HEAD`) | | `event` | `APPROVE`, `COMMENT`, or `REQUEST_CHANGES` (see below) | | `path` | File path as shown in the diff | | `line` | Line number in the NEW version (right side of diff) | | `side` | `RIGHT` for new/added lines, `LEFT` for deleted lines | | `body` | Comment text with priority label |

Choosing the `event` Value

| Event | When to use | |-------|-------------| | `APPROVE` | No issues found, or only 🟡 suggestions that are non-blocking | | `COMMENT` | You have 🟠 Important feedback but it's not a hard blocker | | `REQUEST_CHANGES` | There are 🔴 Critical issues that **must** be fixed before merge |

**Default to `APPROVE`** when the code is correct and merge-ready. Use `COMMENT` or `REQUEST_CHANGES` only when there are actionable issues that warrant it.

Multi-Line Comments

For comments spanning multiple lines, add `start_line` to specify the range:

{
  "path": "path/to/file.py",
  "start_line": 10,
  "line": 12,
  "side": "RIGHT",
  "body": "🟡 Suggestion: Refactor this block:\n\n```suggestion\nline_one = \"new\"\nline_two = \"code\"\nline_three = \"here\"\n```"
}

**`start_line`/`line` define the range that will be REPLACED.** The suggestion block may have any number of lines — it does **not** have to match the range size. See the next section for the exact semantics; getting this wrong is how suggestions silently delete or duplicate code.

Priority Labels

Start each comment with a priority label. **Minimize nits** - leave minor style issues to linters.

| Label | When to Use | |-------|-------------| | 🔴 **Critical** | Must fix: security vulnerabilities, bugs, data loss risks | | 🟠 **Important** | Should fix: logic errors, performance issues, missing error handling | | 🟡 **Suggestion** | Worth considering: significant improvements to clarity or maintainability |

**Do NOT post 🟢 Nit or 🟢 Acceptable comments.** If code is fine, simply don't comment on it. Inline comments that say "this looks good" or "acceptable trade-off" are noise — they create review threads that must be resolved without providing actionable value.

**Example:**

🟠 Important: This function doesn't handle None, which could cause an AttributeError.

```suggestion
if user is None:
    raise ValueError("User cannot be None")

## GitHub Suggestions

For small code changes, use the suggestion syntax for one-click apply:

~~~
```suggestion
improved_code_here()

~~~

Use suggestions for: renaming, typos, small refactors (1-5 lines), type hints, docstrings.

Avoid for: large refactors, architectural changes, ambiguous improvements.

How Suggestions Actually Work (READ THIS BEFORE WRITING ONE)

A suggestion block **replaces** the targeted range with its contents. The replaced range is:

  • `line` only → the single line `line` (replaces 1 line)
  • `start_line` + `line` → the inclusive range `start_line..line` (replaces `line - start_line + 1` lines)

The suggestion content can be **any number of lines** — 0 (deletion), 1, or many. It does not have to match the range size. Whatever is between the ` ```suggestion ` and closing ` ``` ` fences becomes the new content of those lines.

Writing the wrong combination of `start_line`/`line` and suggestion body is what causes accepted suggestions to **duplicate** or **delete** code. Use the table below as your contract:

| Intent | `start_line` | `line` | Suggestion body must contain | |--------|--------------|--------|-------------------------------| | Change line N | omit | N | the new content for line N | | Change lines N..M | N | M | the new content for the whole block | | **Add** a line **after** line N (keep line N) | omit | N | line N's exact current text, then the new line(s) | | **Add** a line **before** line N (keep line N) | omit | N | the new line(s), then line N's exact current text | | **Insert** lines inside range N..M (keep N..M) | N | M | every original line in N..M plus the new lines, in the final desired order | | **Delete** line N | omit | N | empty body (just an empty ` ```suggestion ``` ` block) | | **Delete** lines N..M | N | M | empty body |

Common Mistakes That Break Code

1. **Duplicated lines.** You copy a neighboring line (N-1 or N+1) into the suggestion body as context — that line is still present in the file outside the replaced range, so accepting the suggestion inserts a second copy of

Read more
Ships withextensions

This repository is the public extensions registry for OpenHands. It contains reusable, shareable skills, plugins, and Agent Canvas Apps that customize agent behavior and interfaces. Skills overview docs: SDK skill guide:

Get the whole plugin

Other skills on extensions.