CtrlK
BlogDocsLog inGet started
Tessl Logo

gh-pr-inline

Post inline comments on GitHub PRs and respond to review feedback via gh api

83

1.29x
Quality

75%

Does it follow best practices?

Impact

96%

1.29x

Average score across 3 eval scenarios

SecuritybySnyk

Advisory

Suggest reviewing before use

Optimize this skill with Tessl

npx tessl skill review --optimize ./dot_config/opencode/skill/gh-pr-inline/SKILL.md
SKILL.md
Quality
Evals
Security

Why Not gh pr review

gh pr review doesn't support inline comments on specific lines. Use gh api instead.

Posting Inline Comments

Use --input - with heredoc JSON (not -f 'comments=[...]' which gets stringified):

gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews \
  --method POST \
  --input - << 'EOF'
{
  "event": "REQUEST_CHANGES",
  "comments": [
    {"path":"file.rb","line":10,"body":"Comment text"},
    {"path":"other.rb","line":25,"body":"Another comment"}
  ]
}
EOF

Event Types

  • COMMENT - Neutral feedback
  • APPROVE - Approve the PR
  • REQUEST_CHANGES - Block merge until addressed

Multi-line Comments

For comments spanning lines, add start_line:

{"path":"file.rb","start_line":5,"line":10,"body":"This block..."}

Responding to PR Feedback

When addressing reviewer comments after making fixes, don't reply to every comment. Use this workflow:

  1. Fixed it? Resolve the conversation thread (no reply needed).
  2. Not addressing it? Reply explaining why (disagreement, out of scope, etc.).

Listing Review Threads

Fetch all threads with their resolution status and comment IDs:

gh api graphql -f query='
  query($owner:String!,$repo:String!,$pr:Int!) {
    repository(owner:$owner,name:$repo) {
      pullRequest(number:$pr) {
        reviewThreads(first:100) {
          nodes {
            id
            isResolved
            path
            line
            comments(first:5) {
              nodes { id body author { login } }
            }
          }
        }
      }
    }
  }' -f owner=OWNER -f repo=REPO -F pr=NUMBER

Resolving a Thread (Fixed)

Use the thread's GraphQL id (starts with PRRT_):

gh api graphql -f query='
  mutation($id:ID!) {
    resolveReviewThread(input:{threadId:$id}) {
      thread { isResolved }
    }
  }' -f id=PRRT_kwDOxxxxxxx

Replying to a Thread (Not Fixing)

Use the REST API with the top comment's numeric ID from the thread:

gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
  --method POST \
  -f body="Intentionally left as-is because..."

Line Number Gotchas

  • Line numbers are file lines in HEAD commit (new file version)
  • GitHub's diff display can be off-by-one from what you expect
  • Always verify comments landed on the right line after posting
  • To delete a misplaced comment: gh api repos/{owner}/{repo}/pulls/comments/{id} --method DELETE

Important Notes

  • Omit top-level body field to skip summary comment
  • Each comment needs: path, line, body
  • Safety: Always show proposed comments and wait for approval before posting
Repository
athal7/dotfiles
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.