AgentStack
SKILL verified MIT Self-run

Git Pr

skill-dmythro-agent-skills-git-pr · by dmythro

>-

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add skill-dmythro-agent-skills-git-pr

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Git Pr? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

PR and MR Workflows

Primary skill for pull request and merge request workflows across GitHub and GitLab. Covers the full lifecycle: creation, review queries, comment handling, line-specific comments, and merging. All recipes use minimal field sets for token efficiency.

Context Check (Do This First)

Before starting any PR workflow, detect the current state. This determines the right action:

# Check if a PR exists for the current branch (allowlisted, zero approval)
gh pr view --json number,state,reviewDecision,reviewRequests,title 2>/dev/null

| Result | Next action | |--------------------------------------------|------------------------------------------------------------| | PR exists, CHANGES_REQUESTED | Fetch unresolved threads (see Review Comment Handling) | | PR exists, REVIEW_REQUIRED or has pending reviewRequests | Check review state or wait for reviewers | | PR exists, a bot pending in REST requested_reviewers (Copilot shows as Copilot) | Auto-review in flight -- wait for it (Bot Review Loop); do NOT re-request | | PR exists, unresolved review comments | Address the comments first (Review Comment Handling); never request a new review over outstanding ones | | PR exists, APPROVED | Check CI status or proceed with merge | | PR exists, no review decision yet | Check CI status, review state, or push more changes | | No PR for current branch | Create a PR (see PR/MR Creation) |

This avoids offering to create a PR when one already exists, and immediately surfaces pending review work. The reviewDecision field reliably indicates whether a reviewer has requested changes without needing to fetch individual threads.

Auto-review is an optional setting -- never assume it either way (GitHub): automatic Copilot code review is a per-repo/org opt-in (repo/org settings or rulesets), so its presence varies between accounts, orgs, and even repos of the same owner. When enabled it requests Copilot on every non-draft PR at creation (and when a draft is marked ready for review), so a freshly created PR may already have a pending bot request or bot comments minutes later -- and on other repos nothing fires at all. There is no read-only "is it enabled" endpoint: detect, don't assume -- check for a pending request or an existing bot review first, and only request one if neither shows up; otherwise you get a duplicate round. Gotcha: the pending bot request is only visible via gh api repos/{owner}/{repo}/pulls/{n}/requested_reviewers (login Copilot) -- gh pr view --json reviewRequests omits bot reviewers and stays empty.

When to Use

  • Creating PRs or MRs -- draft workflows, fill patterns, title format
  • Addressing PR/MR review feedback -- "fix PR comments", "address review", "handle feedback", "resolve review threads"
  • Responding to code review -- evaluating reviewer comments, replying, resolving threads
  • Checking review state -- approvals, pending reviewers, review decisions
  • Querying PR/MR data -- files changed, commits, labels, linked issues
  • Posting comments on PRs/MRs -- line-specific comments, thread replies
  • Looping bot review rounds (GitHub only; Copilot, CodeRabbit) -- re-request the bot, wait for the async review, address comments, repeat until no valid comments remain ("loop the Copilot review", "loop 3 rounds")
  • Configuring tool allowlists -- auto-approval patterns for read-only commands

Critical Rules

  1. Prefer CLI subcommands over raw API calls. Subcommands handle pagination, error formatting, and repo detection. Only use gh api / glab api for operations not covered by subcommands (line comments, thread resolution, GraphQL).
  2. Use --json field1,field2 with gh to filter output. This IS the efficiency mechanism -- no --jq needed for basic queries. Only request fields you actually need.
  3. glab has no --json field1,field2 equivalent. Use -F json | jq '{fields}' to filter output for token efficiency.
  4. Use commands exactly as shown in this skill. The commands below are designed to match auto-approval allowlist patterns. Improvising flag order or adding unexpected flags may trigger permission prompts.

Provider Detection

git remote get-url origin

| Remote URL contains | Provider | CLI | PR term | |------------------------------------|----------|--------|---------| | github.com | GitHub | gh | PR | | gitlab.com or self-hosted GitLab | GitLab | glab | MR |

If ambiguous or both present, ask the user.


Read-Only vs Write Classification

  • Read-only (safe to auto-approve): view, list, status, diff, checks, search
  • Write (require user approval): create, edit, merge, close, reopen, comment, review, approve

> Reference: See references/allowlist.md for tiered auto-approval patterns.


PR/MR Summary (Current Branch)

GitHub:

gh pr view --json number,title,state,isDraft,reviewDecision,mergeable,baseRefName,headRefName

GitLab:

glab mr view -F json | jq '{iid:.iid,title:.title,state:.state,draft:.draft,merge_status:.merge_status,target:.target_branch,source:.source_branch}'

PR/MR Summary (By Number)

GitHub:

gh pr view {number} --json number,title,state,isDraft,reviewDecision,mergeable,baseRefName,headRefName

GitLab:

glab mr view {iid} -F json | jq '{iid:.iid,title:.title,state:.state,draft:.draft,merge_status:.merge_status,target:.target_branch,source:.source_branch}'

Review State

> Reference: See references/review-queries.md for advanced review queries: per-reviewer state, approval checks, pending reviewers.

GitHub:

gh pr view --json reviews,reviewRequests,latestReviews

GitLab:

glab mr view -F json | jq '{upvotes:.upvotes,reviewers:[.reviewers[]?.username]}'

For detailed approval info (GitLab):

glab api projects/{project_id}/merge_requests/{iid}/approvals | jq '{approved:.approved,approvers:[.approved_by[]?.user.username]}'

Files Changed

GitHub:

gh pr diff --name-only

GitLab:

glab mr diff

File Stats

GitHub:

gh pr view --json files

GitLab:

glab api projects/{project_id}/merge_requests/{iid}/changes | jq '[.changes[] | {path:.new_path,added:.diff | split("\n") | map(select(startswith("+"))) | length,removed:.diff | split("\n") | map(select(startswith("-"))) | length}]'

List Open PRs/MRs

GitHub:

gh pr list --json number,title,author,reviewDecision,updatedAt

GitLab:

glab mr list -F json | jq '[.[] | {iid:.iid,title:.title,author:.author.username,updated:.updated_at}]'

PR/MR Commits

GitHub:

gh pr view --json commits

GitLab:

glab api projects/{project_id}/merge_requests/{iid}/commits | jq '[.[] | {sha:.short_id,title:.title}]'

Search PRs/MRs

GitHub:

gh pr list --search "review-requested:@me" --json number,title,url

GitLab:

glab mr list --reviewer=@me -F json | jq '[.[] | {iid:.iid,title:.title,url:.web_url}]'

Create PR/MR (Write -- Manual Approval)

| Action | GitHub | GitLab | |-------------------|--------------------------------------------------------|-----------------------------------------------------------| | Create draft | gh pr create --draft --fill | glab mr create --draft --fill | | Create with title | gh pr create --title "feat: ..." --body "..." | glab mr create --title "feat: ..." --description "..." | | Create + request Copilot review | gh pr create --title "..." --body "..." --reviewer @copilot (gh >= 2.88) | n/a |

After creating a non-draft GitHub PR, check gh api repos/{owner}/{repo}/pulls/{n}/requested_reviewers before requesting any bot review -- repos with automatic Copilot review already have one in flight (and it will NOT show in gh pr view --json reviewRequests). On a repo you know has no auto-review, skip the create-then-edit round-trip and request Copilot at creation with --reviewer @copilot; when unsure, create normally and let the detection decide.

Merge (Write -- Manual Approval)

| Action | GitHub | GitLab | |--------------|---------------------------------------|-----------------------------------------------| | Squash merge | gh pr merge --squash --delete-branch | glab mr merge --squash --remove-source-branch | | Rebase merge | gh pr merge --rebase --delete-branch | glab mr merge --rebase --remove-source-branch |


Review Comment Handling

> Reference: See references/pr-comment-workflow.md for the full opinionated workflow with all command patterns and examples.

The workflow has two distinct phases -- never mix them:

Phase 1: Analyze and Fix (local work, no GitHub API writes, zero approvals)

  1. Fetch all unresolved review threads in a single GraphQL query with inline --jq filter
  2. For each thread: read the file at the referenced path+line, check if the comment is valid by researching the codebase (patterns, conventions, CLAUDE.md, git log)
  3. Be critical -- validate each comment against actual code before accepting. Reviewers can be wrong.
  4. Make all necessary code fixes
  5. Commit and push the fixes

Phase 2: Reply and Resolve (one batched command, one approval)

  1. Combine all replies and all resolves into a single &&-chained command
  2. REST replies first, then a single GraphQL mutation with aliases to batch-resolve all handled threads
  3. Leave "Needs discussion" threads unresolved

This ordering matters: pushing fixes first ensures reviewers see the changes when they read replies. Never reply to a comment claiming "Fixed" before the fix is actually pushed.

Fetch Unresolved Threads (Zero Approvals)

GitHub -- one command with $(...) substitution. Generate as a single line and do NOT prepend variable assignments (OWNER=..., REPO=...) -- both break allowlist matching:

gh api graphql -f query="{ repository(owner: \"$(gh repo view --json owner --jq '.owner.login')\", name: \"$(gh repo view --json name --jq '.name')\") { pullRequest(number: $(gh pr view --json number --jq '.number')) { reviewThreads(first: 100) { nodes { id isResolved isOutdated path line startLine comments(first: 20) { nodes { id databaseId body author { login } } } } } } } }" --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved==false)]'

Returns only unresolved threads directly.

Response field mapping (critical -- using wrong ID causes silent failures):

| Field | Format | Use for | |--------------------|-------------------------|------------------------------| | thread .id | PRRT_... (node ID) | resolveReviewThread mutation | | comment .databaseId | 2949637341 (numeric) | REST reply endpoint | | comment .id | PRRC_... (node ID) | Not typically needed |

GitLab (REST):

glab api projects/{project_id}/merge_requests/{iid}/discussions --paginate | jq '[.[] | select(.notes[0].resolvable==true and .notes[0].resolved==false) | {id:.id,path:.notes[0].position.new_path,line:.notes[0].position.new_line,body:.notes[0].body,author:.notes[0].author.username}]'

Reply and Resolve (One Batched Command)

GitHub -- combine all REST replies and a batch GraphQL resolve mutation into one &&-chained command. Reply uses databaseId (numeric), resolve uses thread id (PRRT_ node ID):

gh api repos/{owner}/{repo}/pulls/{pr}/comments/{databaseId_1}/replies -f body="Fixed in {sha} -- {explanation}" && \
gh api repos/{owner}/{repo}/pulls/{pr}/comments/{databaseId_2}/replies -f body="Addressed in {sha}" && \
gh api graphql -f query="
mutation {
  t1: resolveReviewThread(input: {threadId: \"PRRT_thread1\"}) { thread { isResolved } }
  t2: resolveReviewThread(input: {threadId: \"PRRT_thread2\"}) { thread { isResolved } }
}"

GitLab:

glab api projects/{id}/merge_requests/{iid}/discussions/{disc_1}/notes --method POST --field "body=Fixed in {sha}" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_1} --method PUT --field "resolved=true" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_2}/notes --method POST --field "body=Addressed" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_2} --method PUT --field "resolved=true"

Bot Review Loop (GitHub)

> Reference: See references/bot-review-loop.md for the full loop: per-bot config blocks (Copilot, CodeRabbit), the bot_status/bot_tick driver, polling, and termination logic.

GitHub review bots (Copilot, CodeRabbit) are GitHub-only, asynchronous (~minutes per review), and never block: their review state is always COMMENTED. The loop is identical per bot; only the identity (which login to filter) and the re-request trigger differ -- a per-bot config block sets both. There's no read-only "is it enabled" endpoint, so bot_tick exits 5 when the remote isn't GitHub or the re-request errors; an accepted-but-unanswered request exits 3 (slow or silently unavailable).

Iterate until no valid comments remain. Source a bot's config + the bot_status/bot_tick driver -- one round is:

  1. Re-request only when needed + wait -- bot_tick {N} first checks for unresolved bot threads (handle those, never re-request over them), then a review at HEAD, then a pending request in REST requested_reviewers (auto-review on non-draft PR creation usually means round 1 needs no re-request at all). Only if none of those apply does it re-request (Copilot: gh pr edit {N} --add-reviewer "@copilot", gh >= 2.88, no auto re-review on push; CodeRabbit: a @coderabbitai review comment), then polls for the async review. Returns 0 clean / 2 not clean / 3 retry / 4 failed / 5 not applicable.
  2. Validate, don't blind-fix -- evaluate each unresolved comment (Research Checklist); bots can be out of context or outdated. Fix valid ones (commit + push), reply with a rationale + resolve invalid ones. To clear every reviewer, run the loop once per active bot and handle human threads via the comment workflow above.
  3. Terminate -- stop when the bot has no comments; on zero valid comments (re-requesting would only resurface them); on a failed review (exit 4 -- usually structural: oversized PR, binary files, quota; escalate); on unavailability (exit 5); after the round cap (default 20, or "loop 3"); or if HEAD is unchanged since the last round.

Identity gotcha: each bot has a [bot]-suffixed login on REST and an unsuffixed one on GraphQL threads (Copilot: copilot-pull-request-reviewer[bot] / copilot-pull-request-reviewer, plus Copilot on REST inline comments; CodeRabbit: coderabbitai[bot] / coderabbitai). Filter the right one per surface.


Line-Specific Comments (Write)

> Reference: See references/line-comments.md for full patterns: single-line, multi-line range, replies, edit/delete, batch reviews.

GitHub:

gh api repos/{owner}/{repo}/pulls/{pr}/comments \
  -f body="{comment}" -f path="{file}" -F line={line} -f side=RIGHT \
  -f commit_id="$(gh pr view {pr} --json headRefOid --jq .headRefOid)"

GitLab:

glab api projects/{project_id}/merge_requests/{iid}/discussions --method POST \
  --field "body={comment}" \
  --field "position[base

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [dmythro](https://github.com/dmythro)
- **Source:** [dmythro/agent-skills](https://github.com/dmythro/agent-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.