9 pull requests idle for a week or more
4 wait on reviewers, 3 on their authors, and 2 are approved with passing checks but not merged.
Every Monday: open PRs with no commits, comments or reviews in 7 days, who each one waits on, and whether to nudge, merge or close it.
What lands on your board
4 wait on reviewers, 3 on their authors, and 2 are approved with passing checks but not merged.
An idle pull request gets more expensive every week it sits: it drifts from main, its author moves on to something else, and the conflict at the end is bigger than the change. Most repos have a few, and nobody owns the list.
On Mondays the agent lists PRs nobody has touched in a week, works out whether each one waits on its author, a reviewer or whoever merges, and suggests a move. Drafts get their own short section, since an abandoned draft is a different conversation than a stuck review.
gh pr list --repo acme/acme-web --state open --search "updated:<2026-10-09" --json number,title,author,updatedAt,isDraft,reviewDecision,mergeable,reviewRequests --limit 100, with the date set to 7 days ago.
reviewDecision: CHANGES_REQUESTED waits on the author; REVIEW_REQUIRED with open reviewRequests waits on those reviewers; APPROVED waits on whoever merges. A mergeable value of CONFLICTING always puts it back on the author.
updatedAt also moves on label changes and bot comments, so read gh pr view <n> --json commits,comments,reviews and use the newest commit, human comment or review as the last real activity.
Nudge whoever it waits on when idle for 7 to 29 days, propose merging when approved with green checks, and propose closing when idle for 30 days or more with conflicts. The skill does not comment or close anything.
Counts by who it waits on, then the PRs longest idle first with days idle and the suggested move. Drafts go last.
With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.
Pick your agent, where the data comes from and how to schedule it; the commands below follow.
One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.
shellcurl -fsSL https://briefkin.dev/skills/github-stale-pull-requests/install | shAsk Claude Code:
promptRun the github-stale-pull-requests skillOr paste the prompt instead of installing:
promptIn the GitHub repo acme/acme-web, find open pull requests with no activity for 7 days or more (gh pr list --state open --search "updated:<DATE"). For each, check the last commit, human comment or review to confirm it is really idle, then say who it waits on: the author (changes requested or merge conflicts), the requested reviewers, or whoever merges (approved with passing checks). List them longest idle first with number, title, author, days idle, who it waits on and a suggested move: nudge, merge, or close if idle 30+ days with conflicts. Put drafts in a separate list. Do not comment on or close anything.Mondays at 9:30, from cron on any machine where Claude Code is signed in:
crontab30 9 * * 1 claude -p "Run the github-stale-pull-requests skill"Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.
Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a report card. How setup works
SKILL.md---
name: github-stale-pull-requests
description: "Every Monday: open PRs with no commits, comments or reviews in 7 days, who each one waits on, and whether to nudge, merge or close it. Use when the user asks for this, or when it runs on a schedule."
---
# GitHub stale pull requests
Every Monday: open PRs with no commits, comments or reviews in 7 days, who each one waits on, and whether to nudge, merge or close it.
An idle pull request gets more expensive every week it sits: it drifts from main, its author moves on to something else, and the conflict at the end is bigger than the change. Most repos have a few, and nobody owns the list.
On Mondays the agent lists PRs nobody has touched in a week, works out whether each one waits on its author, a reviewer or whoever merges, and suggests a move. Drafts get their own short section, since an abandoned draft is a different conversation than a stuck review.
## Two ways to get the data
Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.
## Route A: API or MCP server
### What you need
- Read access to the repo with `gh` signed in, or a GitHub MCP server or connector.
- On private repos, a token that can read pull requests, their reviews and their checks.
If something is missing, say what and stop; do not invent numbers.
### Steps
1. **List idle PRs** (GitHub): `gh pr list --repo acme/acme-web --state open --search "updated:<2026-10-09" --json number,title,author,updatedAt,isDraft,reviewDecision,mergeable,reviewRequests --limit 100`, with the date set to 7 days ago.
2. **Work out who it waits on**: `reviewDecision: CHANGES_REQUESTED` waits on the author; `REVIEW_REQUIRED` with open `reviewRequests` waits on those reviewers; `APPROVED` waits on whoever merges. A `mergeable` value of `CONFLICTING` always puts it back on the author.
3. **Confirm it is really idle** (GitHub): `updatedAt` also moves on label changes and bot comments, so read `gh pr view <n> --json commits,comments,reviews` and use the newest commit, human comment or review as the last real activity.
4. **Suggest a move**: Nudge whoever it waits on when idle for 7 to 29 days, propose merging when approved with green checks, and propose closing when idle for 30 days or more with conflicts. The skill does not comment or close anything.
5. **Write the list**: Counts by who it waits on, then the PRs longest idle first with days idle and the suggested move. Drafts go last.
## Route B: the browser
### What you need
- Signed in to GitHub with read access to the repository, including its checks.
If something is missing, say what and stop; do not invent numbers.
### Steps
Start at https://github.com/pulls. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.
1. **List idle PRs**: In the search box, replace the query with `is:pr is:open draft:false repo:acme/acme-web updated:<2026-10-09 sort:updated-asc`, with the date set to 7 days ago. Run it again with `draft:true` for the drafts list. The icons at the right of each row show the review state and check status.
2. **Work out who it waits on**: Open each PR. The merge box reads **Changes requested** (waits on the author), **Review required** with names under **Reviewers** in the sidebar (waits on them) or **Approved** with green checks (waits on whoever merges). "This branch has conflicts that must be resolved" always puts it back on the author.
3. **Confirm it is really idle**: The `updated` qualifier also moves on labels and bot comments, so scroll the **Conversation** timeline and take the newest commit, human comment or review as the last real activity.
4. **Suggest a move**: Nudge whoever it waits on at 7 to 29 days idle, propose merging when approved with green checks, and propose closing at 30 days or more with conflicts. Do not comment on or close anything.
5. **Write the list**: Counts by who it waits on, then the PRs longest idle first with days idle and the suggested move, drafts last.
Note: The list shows 25 PRs per page. Add `-author:app/renovate -author:app/dependabot` to the query to leave bot PRs out.
## The report
- **Idle PRs**: the count, split by waiting on the author, reviewers or a merge.
- **The list**, longest idle first: number, title, author, days idle, who it waits on and the suggested move.
- **Approved and green** PRs nobody merged, called out on their own.
- **Drafts** idle for 7 days or more.
## Post it to Briefkin
When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.
```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
-H "authorization: Bearer $BRIEFKIN_TOKEN" \
-H "content-type: application/json" \
-d @- <<'JSON'
{
"v": 1,
"event_id": "github-stale-pull-requests/<date of this run, e.g. 2026-10-16>",
"item_key": "github-stale-pull-requests",
"project": "acme-web",
"source": "GitHub stale pull requests skill",
"kind": "update",
"title": "9 pull requests idle for a week or more",
"summary": "**4 wait on reviewers**, 3 on their authors, and 2 are approved with passing checks but not merged.",
"widget": [
{
"type": "Table",
"props": {
"columns": [
"PR",
"Idle",
"Waiting on",
"Suggested"
],
"align": [
"left",
"right",
"left",
"left"
],
"rows": [
[
"#1188 Replace moment with date-fns",
"34d",
"Author, conflicts",
"Close or rebase"
],
[
"#1231 Webhook signature v2",
"15d",
"@acme/security",
"Nudge reviewers"
],
[
"#1240 Lazy-load dashboard charts",
"12d",
"Merge",
"Merge: approved, green"
],
[
"#1246 Pagination on the audit log",
"11d",
"jlee",
"Nudge reviewer"
],
[
"#1252 Cache org settings in KV",
"9d",
"Author",
"Nudge author"
],
[
"#1255 Bump eslint to v9",
"8d",
"Merge",
"Merge: approved, green"
],
[
"#1260 Retry failed exports",
"8d",
"mo",
"Nudge reviewer"
],
[
"#1262 Remove the legacy billing flag",
"7d",
"@acme/billing",
"Nudge reviewers"
],
[
"#1259 Keyboard nav in the org switcher",
"7d",
"Author",
"Nudge author"
]
]
}
},
{
"type": "Callout",
"props": {
"text": "#1240 and #1255 only need someone to press merge.",
"tone": "info"
}
}
]
}
JSON
```
Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.
## Run it on a schedule
Suggested: Mondays at 9:30 (`30 9 * * 1`). From cron, with the agent signed in on that machine:
```bash
30 9 * * 1 claude -p "Run the github-stale-pull-requests skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```
Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/github-stale-pull-requests#schedule
Source: https://briefkin.dev/skills/github-stale-pull-requests
Read access to the repo with gh signed in, or a GitHub MCP server or connector.
On private repos, a token that can read pull requests, their reviews and their checks.
https://api.githubcopilot.com/mcp/. Sign in with OAuth or a personal access token; add /readonly to the URL, or use a toolset URL such as https://api.githubcopilot.com/mcp/x/pull_requests/readonly, to expose only read tools. It also runs locally (source).gh CLI. Run gh auth login once, or set GH_TOKEN for scheduled runs. gh pr list --search "review-requested:@me" --json number,title,url,createdAt and gh api repos/{owner}/{repo}/dependabot/alerts cover most reports.GITHUB_TOKEN, limit it to the repositories in the report, and grant Read on Metadata, Contents, Pull requests and Issues, plus Dependabot alerts if you report on them.With every permission on a fine-grained token set to Read, the agent can't push, merge, comment or close anything.
Not by default. It reads and suggests, because a bot comment on a teammate's PR lands differently than a word at standup. If you want nudges, let it run gh pr comment only on PRs waiting on reviewers, and keep the threshold at 7 days or more.
Add -author:app/renovate -author:app/dependabot to the search to leave them out, or give them their own section. A bot PR that sits for weeks usually means the update needs a human decision anyway.
No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a report card, so you can glance at it instead of asking again.
Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.
Yes. Switch the data source to "Your browser" and the steps change to the GitHub pages themselves: the agent opens github.com/pulls in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.
Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.
Free during the open beta. No card.