Manage PRs
Operating Rule
Treat GitHub as the source of truth. Do not rely on stale browser state, old summaries, local guesses, or a previous agent's report.
Only mark review threads resolved after:
- The related fix is committed.
- The branch is pushed.
- The live PR state is re-read and the fixed thread IDs are still the threads being resolved.
Top-level PR conversation comments do not have review-thread resolution. Address them by fixing the issue, pushing the fix, and replying only when a reply is useful or explicitly requested.
Quick Start
From the target repo:
python3 "<skill-dir>/scripts/inspect_pr_state.py" --repo "." --pr "<number-or-url>"
If the current branch has exactly one PR, omit --pr.
After fixes are pushed and the live thread IDs are confirmed:
python3 "<skill-dir>/scripts/resolve_review_threads.py" --repo "." --thread-id "<thread-id>"
Workflow
Confirm the target PR.
- Use a provided PR number/URL when present.
- Otherwise run
gh pr view --json number,url,headRefName,headRepositoryOwner.
- Run
git status --short before editing. Preserve unrelated user changes.
Refresh from GitHub.
- Run
git fetch --all --prune.
- Inspect mergeability with
gh pr view <pr> --json number,url,headRefName,baseRefName,mergeable,mergeStateStatus,reviewDecision.
- If the branch is behind or conflicted, update from the PR base using the repo's normal merge/rebase pattern before calling the PR clean.
Inventory every blocker.
- Run
inspect_pr_state.py.
- Read unresolved review threads.
- Read top-level PR conversation comments.
- Read review summary bodies, especially
CHANGES_REQUESTED.
- Read failing and pending checks.
- For failing GitHub Actions checks, fetch logs with
gh run view <run-id> --log or use the existing gh-fix-ci skill/script if available.
- For external CI providers, open the details URL if tooling is available; otherwise report the exact external URL and continue with local reproduction where possible.
Cluster comments by root cause.
- Multiple comments often point at one bug. Fix the bug once instead of making one-off edits for each comment.
- Separate actionable requests from stale, duplicate, or already-addressed comments.
- Do not resolve a stale-looking thread until live code proves it is obsolete and the branch has been pushed.
Fix and verify.
- Reproduce failing CI locally when feasible.
- Run the narrowest meaningful existing verification first, then broader repository-prescribed gates when the PR touches shared code.
- Do not weaken lint, typecheck, tests, snapshots, coverage, security checks, or required workflows to get green.
Commit and push.
- Use the repo's commit conventions.
- If push is rejected, fetch/rebase or merge the remote branch, rerun the relevant checks, then push again.
- Never resolve review threads before this push succeeds.
Re-check GitHub.
- Re-run
inspect_pr_state.py.
- Re-run
gh pr checks <pr> or the provider-specific status command.
- If checks are pending, wait or watch them when practical. Do not claim there are no failing checks while required checks are still red.
Resolve completed review threads.
- Resolve only the exact thread IDs whose requested changes were fixed and pushed.
- Use
resolve_review_threads.py or the GraphQL mutation directly.
- Re-run
inspect_pr_state.py and confirm unresolved actionable review threads are zero.
Final report.
- Include the PR URL/number.
- List the comments fixed, top-level comments addressed, and CI failures cleared.
- State the exact verification run.
- If anything remains pending or externally blocked, say exactly which check/comment and link the details.
Comment Handling Rules
- Review threads: fix, push, then resolve via GraphQL
resolveReviewThread.
- Top-level PR conversation comments: fix the underlying issue. Reply only when a human needs a note; do not pretend they can be resolved.
- Review summary bodies: treat
CHANGES_REQUESTED as actionable even when there is no inline thread.
- Bot comments: handle if they identify a real blocker. Ignore noise only after proving it is non-actionable.
- Duplicates: mention they are duplicates in the final report, but still verify there is no separate unresolved request.
CI/CD Handling Rules
- Required checks must not be failing when done.
- A local green test does not replace a red GitHub check. Use logs to connect the local fix to the failing workflow.
- Treat pending checks as pending, not green.
- Treat skipped/neutral checks as their own bucket. They are not failures unless branch protection or the PR UI marks them as blockers.
- If a failure is environmental or third-party, gather the run URL, error text, and retry status before reporting it as blocked.
- If several PRs share the same failing workflow, fix the shared workflow once and verify each affected PR state separately.
Useful GraphQL Mutation
Use this only after the fix is pushed:
gh api graphql \
-f threadId="<thread-id>" \
-f query='mutation($threadId:ID!){resolveReviewThread(input:{threadId:$threadId}){thread{id isResolved}}}'
Bundled Scripts
scripts/inspect_pr_state.py: prints unresolved review threads, top-level PR comments, review summaries, and status checks for a PR.
scripts/resolve_review_threads.py: resolves explicit review-thread IDs after the branch has been fixed and pushed.
1---2name: manage-prs3description: Manage and maintain GitHub pull requests end-to-end. Use when asked to fix PR review comments, unresolved review threads, top-level PR conversation comments, requested changes, merge conflicts, or CI/CD failures; when the user says to manage, maintain, clean up, unblock, get green, finish, or prepare a PR; or when a PR must have no unresolved actionable comments and no failing checks.4---56# Manage PRs78## Operating Rule910Treat GitHub as the source of truth. Do not rely on stale browser state, old summaries, local guesses, or a previous agent's report.1112Only mark review threads resolved after:13141. The related fix is committed.152. The branch is pushed.163. The live PR state is re-read and the fixed thread IDs are still the threads being resolved.1718Top-level PR conversation comments do not have review-thread resolution. Address them by fixing the issue, pushing the fix, and replying only when a reply is useful or explicitly requested.1920## Quick Start2122From the target repo:2324```bash25python3 "<skill-dir>/scripts/inspect_pr_state.py" --repo "." --pr "<number-or-url>"26```2728If the current branch has exactly one PR, omit `--pr`.2930After fixes are pushed and the live thread IDs are confirmed:3132```bash33python3 "<skill-dir>/scripts/resolve_review_threads.py" --repo "." --thread-id "<thread-id>"34```3536## Workflow37381. Confirm the target PR.39 - Use a provided PR number/URL when present.40 - Otherwise run `gh pr view --json number,url,headRefName,headRepositoryOwner`.41 - Run `git status --short` before editing. Preserve unrelated user changes.42432. Refresh from GitHub.44 - Run `git fetch --all --prune`.45 - Inspect mergeability with `gh pr view <pr> --json number,url,headRefName,baseRefName,mergeable,mergeStateStatus,reviewDecision`.46 - If the branch is behind or conflicted, update from the PR base using the repo's normal merge/rebase pattern before calling the PR clean.47483. Inventory every blocker.49 - Run `inspect_pr_state.py`.50 - Read unresolved review threads.51 - Read top-level PR conversation comments.52 - Read review summary bodies, especially `CHANGES_REQUESTED`.53 - Read failing and pending checks.54 - For failing GitHub Actions checks, fetch logs with `gh run view <run-id> --log` or use the existing `gh-fix-ci` skill/script if available.55 - For external CI providers, open the details URL if tooling is available; otherwise report the exact external URL and continue with local reproduction where possible.56574. Cluster comments by root cause.58 - Multiple comments often point at one bug. Fix the bug once instead of making one-off edits for each comment.59 - Separate actionable requests from stale, duplicate, or already-addressed comments.60 - Do not resolve a stale-looking thread until live code proves it is obsolete and the branch has been pushed.61625. Fix and verify.63 - Reproduce failing CI locally when feasible.64 - Run the narrowest meaningful existing verification first, then broader repository-prescribed gates when the PR touches shared code.65 - Do not weaken lint, typecheck, tests, snapshots, coverage, security checks, or required workflows to get green.66676. Commit and push.68 - Use the repo's commit conventions.69 - If push is rejected, fetch/rebase or merge the remote branch, rerun the relevant checks, then push again.70 - Never resolve review threads before this push succeeds.71727. Re-check GitHub.73 - Re-run `inspect_pr_state.py`.74 - Re-run `gh pr checks <pr>` or the provider-specific status command.75 - If checks are pending, wait or watch them when practical. Do not claim there are no failing checks while required checks are still red.76778. Resolve completed review threads.78 - Resolve only the exact thread IDs whose requested changes were fixed and pushed.79 - Use `resolve_review_threads.py` or the GraphQL mutation directly.80 - Re-run `inspect_pr_state.py` and confirm unresolved actionable review threads are zero.81829. Final report.83 - Include the PR URL/number.84 - List the comments fixed, top-level comments addressed, and CI failures cleared.85 - State the exact verification run.86 - If anything remains pending or externally blocked, say exactly which check/comment and link the details.8788## Comment Handling Rules8990- Review threads: fix, push, then resolve via GraphQL `resolveReviewThread`.91- Top-level PR conversation comments: fix the underlying issue. Reply only when a human needs a note; do not pretend they can be resolved.92- Review summary bodies: treat `CHANGES_REQUESTED` as actionable even when there is no inline thread.93- Bot comments: handle if they identify a real blocker. Ignore noise only after proving it is non-actionable.94- Duplicates: mention they are duplicates in the final report, but still verify there is no separate unresolved request.9596## CI/CD Handling Rules9798- Required checks must not be failing when done.99- A local green test does not replace a red GitHub check. Use logs to connect the local fix to the failing workflow.100- Treat pending checks as pending, not green.101- Treat skipped/neutral checks as their own bucket. They are not failures unless branch protection or the PR UI marks them as blockers.102- If a failure is environmental or third-party, gather the run URL, error text, and retry status before reporting it as blocked.103- If several PRs share the same failing workflow, fix the shared workflow once and verify each affected PR state separately.104105## Useful GraphQL Mutation106107Use this only after the fix is pushed:108109```bash110gh api graphql \111 -f threadId="<thread-id>" \112 -f query='mutation($threadId:ID!){resolveReviewThread(input:{threadId:$threadId}){thread{id isResolved}}}'113```114115## Bundled Scripts116117- `scripts/inspect_pr_state.py`: prints unresolved review threads, top-level PR comments, review summaries, and status checks for a PR.118- `scripts/resolve_review_threads.py`: resolves explicit review-thread IDs after the branch has been fixed and pushed.