review-prs
Skill2 starsChanged 20 days agoMITView on GitHub
List open PRs that request your review — author, freshness, CI/conflict blockers — or watch them live and auto-dispatch a Herdr Codex pane to review or re-review each Ready PR
10 other projects use a version of this.
Adopted by
Most recently taken up by
- EJRyan89/coding-agent-skillstheir own version, first seen Oct 17, 2026
- ismail9k/skillstheir own version, first seen Oct 17, 2026
- kaiohenricunha/dotbabeltheir own version, first seen Oct 17, 2026
- huacnlee/omamailtheir own version, first seen Oct 9, 2026
- mxschmitt/awesome-playwrighttheir own version, first seen Oct 8, 2026
- pyinfra-dev/pyinfratheir own version, first seen Oct 8, 2026
Other versions10 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 10
- vinta/awesome-python★ 333ksame name
- googleapis/mcp-toolbox★ 17ksame name
- googleapis/genai-toolbox★ 17ksame name
- BuilderIO/agent-native★ 7.6ksame name
- pyinfra-dev/pyinfra★ 6.1ksame name
- mxschmitt/awesome-playwright★ 1.6ksame name
- huacnlee/omamail★ 331same name
- ismail9k/skills★ 30same name
- EJRyan89/coding-agent-skills★ 2same name
- kaiohenricunha/dotbabel★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository6 other files it gives its agents.
- architectSkill
- coordinateSkill
- defend-prSkill
- finalize-change-footprintSkill
- finalize-code-commentsSkill
- finalize-sweepSkill
The file
We split this skill into the rules it gives an agent
7 rules. 0 are common, 3 are distinctive, and 4 are very specific to this project.
0
Common
Most of the 9 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 18
Read-only for the orchestrator: this skill never merges, closes, or assigns reviewers itself.
- Very specific: line 22
Read through orch-settings (docs/settings.md), which prints the resolved values.
- Distinctive: line 62
After the tables, add only what the buckets do not already say: months-old parked PRs, or which Ready PRs you just dispatched.
- Very specific: line 66
Run list with the same scope (tables + snapshot).
- Distinctive: line 68
Start the watcher in the background, scope explicit, its output appended to a log in your scratchpad:
- Very specific: line 74
Default interval 120s (--interval overrides).
- Distinctive: line 109
Run one dispatch per queue item in the background:
“Common” is measured: kept by at least 6 in 10 of the 9 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Review PRs
Scripts: ~/.claude/skills/review-prs/scripts/ (prs.sh runs prs.py on the orchestration's Python 3.11+; dispatch.sh; watch-events.sh). State: ~/.cache/review-prs/.
- list (default): open PRs that still request your review (
review-requested:@me), bucketed by whether you can review now. - watch: the list once, then a background watcher that reports each change. It stays silent while nothing changes.
- auto-dispatch (default on
watch, and whenever the user asks to review/dispatch): for each 🔔 Ready for your review PR, open a Herdr sibling pane and start Codex on$ORCH_CODEX_WORKER_MODEL($ORCH_CODEX_SMART_MODELwhen only that one is set) to review or re-review it.
Read-only for the orchestrator: this skill never merges, closes, or assigns reviewers itself. Codex may post the GitHub review (that is the point of dispatch). Pass --no-dispatch to list/watch without launching agents.
Settings
Read through orch-settings (docs/settings.md), which prints the resolved values; never read ~/.claude/orchestration.toml directly, since an empty providers.enabled there still means Codex is on:
models.codex_worker(ORCH_CODEX_WORKER_MODEL): the review model; when it is empty or a<placeholder>,models.codex_smartserves. Applies only whencodexis inORCH_PROVIDERS; then, both empty or a<placeholder>: dispatch nothing and tell the user to fill one in.providers.enabled(ORCH_PROVIDERS): withoutcodex,dispatch-queueplans an empty queue with anoteanddispatch.shrefuses; list and watch as with--no-dispatch, and say once in one line that Codex reviews are off.watchers.pr_scope(ORCH_WATCHERS_PR_SCOPE): the scope when no scope flag is given outside a repo.
Repo settings of the PR's clone shape the prompt: guard.big_repo forbids broad Git reads, legacy.scan adds the legacy check.
Arguments
watch— start watch mode. Without it, list once.--repo owner/name— one repo.--repo nameworks together with--org.--org ORG— every repo in the org.--all— every PR requesting you, anywhere.--actionable— list only Ready-for-review PRs.--no-dispatch— never open Herdr/Codex panes.
With no scope flag, the script uses the GitHub repo of the current directory, else watchers.pr_scope, else --all.
List
~/.claude/skills/review-prs/scripts/prs.sh list [scope] [--actionable]It prints markdown tables. The user cannot see tool output rendered: copy the script's output into your reply verbatim, as markdown. Every table stays a table, and every PR stays its full bare https://github.com/... URL. Never answer "see above", never summarize the tables into prose or bullets, and never shorten a URL to #1234.
The buckets, first match wins:
| Bucket | Test |
| 📝 Drafts | isDraft |
| 🔴 Conflicting | mergeable == CONFLICTING |
| ❔ Merge state unknown | mergeable == UNKNOWN after one retry; never dispatched |
| 🔴 CI failing | rollup FAILURE / ERROR |
| ⏳ Waiting on CI | rollup PENDING / EXPECTED |
| 🔔 Ready for your review | none of the above |
Three short columns: PR, Title (≤60 chars), Author · status. Your own authored PRs and bot README-sync titles are hidden.
After the tables, add only what the buckets do not already say: months-old parked PRs, or which Ready PRs you just dispatched.
Watch
- Run
listwith the same scope (tables + snapshot). - Unless
--no-dispatch, run Auto-dispatch below for the current Ready queue. Start the watcher in the background, scope explicit, its output appended to a log in your scratchpad:
~/.claude/skills/review-prs/scripts/prs.sh watch [scope] >>"<scratchpad>/pr-watch.log" 2>&1Default interval 120s (
--intervaloverrides). Follow it with one Monitor on~/.claude/skills/review-prs/scripts/watch-events.sh "<scratchpad>/pr-watch.log": it prints only event lines, from line one on first attach and after the last line it read on a restart, so no event is skipped.- Tell the user: you only speak on changes; watch lasts until the session ends; "stop the PR watch" ends it. On
new:/ready:events for actionable PRs, run Auto-dispatch again (skip SHAs already dispatched).
Reporting a watch event
| Prefix | Meaning |
new: | PR started requesting your review |
changed: | draft/CI/conflict/new commits |
ready: | became reviewable (or new commits while still ready) |
cleared: | open, but no longer requesting you |
merged: / closed: | left the list with real GitHub state |
PR fetch failing 3x in a row: / recovered: | auth/network |
Relay in plain words with full bare URLs. End with now: counts. PushNotification for new: only: Review requested: PR <n> (<short title>) by <author>.
Auto-dispatch (Herdr + Codex)
Requires HERDR_ENV=1. If not inside Herdr, say so and stop dispatch (list/watch still fine).
Queue
~/.claude/skills/review-prs/scripts/prs.sh dispatch-queue [scope]JSON fields per item: url, number, title, author, repo, sha, kind (review | re-review | re-request), agent (rev<number>-<sha7>-<repo hash>, plus -<4 hex> for a re-request; unique per repo and head), cwd (local clone or null), model.
cwd comes from the clones of the open work, the current directory, or ~/Projects/<owner>/<name>; a clone matches when its origin is the repo, or else its upstream (a fork of it), and a clone whose origin is the repo wins. Skip entries with cwd: null and tell the user no local clone was found.
Skip entries already marked for the same sha, pending, blocked, or done (script does this). Each dispatch-queue result includes every blocked current head with its recorded reason; a new head or an explicit release-dispatched clears that condition. It also lists in stuck every review pending for 30 minutes or more (url, sha, agent, pane, minutes); nothing expires, so release or finish it by hand. Concurrency: up to 3 Codex reviews at once. Queue the rest; when any in-flight review finishes, start the next queued item until 3 are running again (or the queue is empty).
Launch one review
Run one dispatch per queue item in the background:
~/.claude/skills/review-prs/scripts/dispatch.sh "<url>" <number> "<title>" "<author>" <sha> <kind> <agent> "<cwd>" <owner/repo> [right|down]Set ORCH_REVIEW_EXTRA_STEPS when dispatching to add review-specific instructions; dispatch.sh includes them in the authorized review prompt.
Any follow-up sent to a review pane must repeat that it must post without asking for confirmation.
It first claims the SHA (pending, under a lock); a head another dispatch already claimed or finished prints TAKEN <sha> and exits 3 before any pane, agent or worktree. It then records the ids of your submitted reviews on the PR; when that read fails it prints SNAPSHOT FAILED, releases the claim and sends nothing. Then it checks out a detached worktree at the SHA under ~/.cache/review-prs/worktrees/<agent> (fetching pull/<n>/head when the clone lacks it; if GitHub's pull ref lags, it validates and fetches the PR fork's owner/repository/ref directly). If neither source provides the SHA it prints HEAD FAILED and releases the claim. It splits a sibling pane there in the current tab without taking focus (down when the pane is already narrow; PANE=<id> reuses an empty pane instead), starts Codex on $ORCH_CODEX_WORKER_MODEL in that worktree (--cd, also for a PANE) without loading the PR's AGENTS.md (-c project_doc_max_bytes=0; review rules come from the base branch), sends the review prompt and waits for the turn to end. The prompt tells Codex to post through python3 <orch>/lib/github_write.py --timeout 240 api -X POST repos/<owner>/<repo>/pulls/<number>/reviews --input -, with the JSON payload (commit_id, event, body, inline comments) on stdin from a quoted heredoc and no temporary files (not gh pr review). The wrapper serializes writes and retries only a confirmed secondary-limit/abuse response; other errors are reported without replaying a write. Codex replies APPROVE|COMMENT|REQUEST_CHANGES — <url> and ends its turn: no polling, no waiting for CI or replies.
Output lines: WORKTREE <path> and PANE <id> AGENT <name> PR <url> at start; PROMPT_EXIT <n> and the agent's last lines at the end. HEAD FAILED <sha> ... means neither the pull ref nor validated fork ref contained the requested SHA; its claim is released. WORKTREE FAILED ... means checkout setup failed; its claim is released. Codex 0.164.0's 1 hook needs review before it can run and N hooks need review before they can run screens are never accepted: HOOKS UNTRUSTED <hook list> records the SHA as blocked with reason hooks need review, closes the pane it opened, and removes its worktree. It never sends keys to approve or trust hooks. The screen is read again after an update banner is dismissed. An incomplete prompt stays pending: a bounded transcript cannot reliably prove that a turn never started, except that UNDELIVERED agent_blocked followed by RELEASED <sha> closes a pane this dispatch opened and releases its claim for retry. Then either LASTREVIEW <state> <time> <url> (your submitted review of the dispatched SHA whose id was not among your reviews before the prompt; the SHA is marked done), or INCOMPLETE no review of <sha> (the SHA stays pending when a prompt did not post a review). A release closes the pane it opened first, so the agent name is free for the retry; a pane passed in as PANE is never closed or has its worktree removed. Then CLOSED <pane> and REMOVED <worktree> (a pane it opened, review posted, prompt finished) or LEFT OPEN <pane>; DONE. VERIFY FAILED means the reviews could not be read: the SHA stays pending and the pane open; check the PR by hand. After closing a LEFT OPEN pane yourself, remove its worktree: git -C <cwd> worktree remove --force <worktree>. gh calls stop after 45 seconds.
Tell the user which pane/agent is reviewing which PR (full URL). When the review finishes you must announce the outcome — silence after dispatch is not enough.
Report and close
Report in one short line with the full bare PR URL:
APPROVE/APPROVED→ Approved https://github.com/...CHANGES_REQUESTED→ Changes requested https://github.com/...COMMENT/COMMENTED→ Commented https://github.com/...
Take it from LASTREVIEW only (a trailing SWEPT means the review body carries the sweep marker): the agent's one-liner is a claim, the posted review is the fact. With INCOMPLETE, say Review not posted with the PR URL and a one-sentence note from the agent's lines, whatever verdict the agent printed — do not invent an approval.
Close review panes only with ~/.claude/coordinator/watchers/close-pane.sh <pane_id>: it marks the pane closed on purpose, so the workers watcher reports it as closed, not dead. dispatch.sh does this itself for a pane it opened once the review is posted and the prompt finished. For LEFT OPEN (no review yet, timeout, blocked, or a pane passed in as PANE), report first and close only when it is done or the user says to abandon it. Never close panes you did not create for this dispatch.
Re-review
dispatch-queue emits kind: re-review when the same URL was marked before with a different head SHA (new commits while still requesting you, or after CI became green again). Same launch path; prompt Mode is re-review.
A manual review of a moved head is re-queued once when an older completed dispatched SHA remains recorded; the re-review claim prevents another duplicate.
dispatch-queue emits kind: re-request when the head already has a done review and the PR asks for your review again personally (the author clicked re-request; a team-only request does not count, because a member's review does not clear it). dispatch.sh claims the head again with claim-dispatched --retake, and the agent name gets a suffix so it never meets the pane of the earlier review.
Sweep in the review
The prompt runs the repo's review.finalize_commands (default /finalize-sweep in report-only mode, with the base ref, the PR URL and 25 slices as inputs; [] leaves the sweep out) on your first review of a PR and on a head you would APPROVE, and skips it when one of your own earlier reviews holds a <!-- finalize-sweep {"head":"<sha>"} --> marker for that head. The findings table goes in the review body with that marker as its last line before the trailer; fix findings block APPROVE and nit findings never do. last-review marks a review SWEPT when its body carries the marker of the head, and dispatch.sh prints SWEEP MISSING for a first review or an APPROVE without it.
Rules
- Orchestrator never merges, closes, or assigns reviewers. Codex posts reviews only.
- Do not dispatch Draft / CI-failing / CI-running / Conflicting buckets — only Ready.
- At most 3 concurrent Codex reviews unless the user raises the limit. When one finishes, report → close pane → fill from the queue.
- A PR missing from search is not proof it is gone — watcher checks up to 10 absent PRs per poll through GraphQL and keeps direct or team requests. A failed departure read retains that entry without adding a miss, reports READFAIL, and allows other PR updates to continue.
merge state unknownis not a pass —listretries once.
Common pitfalls
- GitHub MCP often misses private org repos — use
gh(the script does). review-requested:@meclears after you (or Codex) submit a review. A PR you reviewed whose head moved stays in the queue without a new request (reviewed-by:@me), so watch mode re-reviews it after further pushes.- GraphQL search must paginate;
mergeStateStatusneeds themerge-info-previewAccept header. - Herdr
agent startneeds an empty shell pane; it does not create layout —dispatch.shsplits first. - Agent names:
[a-z][a-z0-9_-]{0,31}, unique among live agents (dispatch-queuemakes them so).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

