Generate a daily code review report showing stale PRs, items needing your attention, and active work for your team. Use whenever the user asks for a PR report, code review status, daily standup prep, team PR overview, "what needs review", "what's stale", "show me open PRs", "daily review", "PR check", "review report", "what should I look at today", or any question about tracking pull request activity across a team or pod. Also trigger when the user mentions a specific pod name that matches a ...
Scanned 5/28/2026
Install via CLI
openskills install Flagrare/agent-skills---
name: daily-code-review
description: Generate a daily code review report showing stale PRs, items needing your attention, and active work for your team. Use whenever the user asks for a PR report, code review status, daily standup prep, team PR overview, "what needs review", "what's stale", "show me open PRs", "daily review", "PR check", "review report", "what should I look at today", or any question about tracking pull request activity across a team or pod. Also trigger when the user mentions a specific pod name that matches a saved config.
---
# Daily Code Review Report
Generate a team-wide pull request status report focused on actionable next steps. The report surfaces stale PRs, items needing the runner's personal attention, and a quick FYI on active work — so the reader knows exactly what to do when they open GitHub.
## Setup (first run only)
Check for config files matching `{skill_directory}/teams/*.json`. If none exist, run the setup flow.
### First-time setup
Use `AskUserQuestion` to collect:
1. **GitHub org** — the GitHub organization to search (e.g., `acme-corp`)
2. **Team name** — a human label for the report header (e.g., `Platform Team`)
3. **Team members** — for each person, their GitHub login and display name. Ask in a single prompt, one member per line, format: `github_login / Display Name`
Save to `{skill_directory}/teams/{team-name-slug}.json`:
```json
{
"org": "acme-corp",
"team_name": "Platform Team",
"members": [
{ "github_login": "aturing", "display_name": "Alan Turing" },
{ "github_login": "ghopper", "display_name": "Grace Hopper" },
{ "github_login": "dknuth", "display_name": "Don Knuth" }
]
}
```
Confirm the config with the user before proceeding.
### Returning user
If exactly one team config exists, use it. If multiple exist, ask which team to report on.
If the user says "add a team" or "edit team," update or create the relevant config file and re-confirm.
## Detect "Me"
Run:
```bash
gh api user --jq '.login'
```
Match against the team members list by `github_login`. If no match, ask the user which member they are — they might be authenticated with a personal account that differs from their team login.
## Data Collection
Use **only** these GitHub API endpoints. The comments API is noisy and `mergeable_state` is unreliable — skip both. Staleness comes from `updated_at` alone.
### Open PRs per member
The search/issues endpoint does NOT return draft status reliably (it comes back null). Run two searches per member to separate drafts from non-drafts:
```bash
gh api "search/issues?q=org:{org}+is:pr+is:open+-is:draft+author:{login}&per_page=100" \
--jq '.items[] | {number, title, html_url, updated_at, draft: false, repo: (.repository_url | split("/") | last), user: .user.login}'
```
```bash
gh api "search/issues?q=org:{org}+is:pr+is:open+is:draft+author:{login}&per_page=100" \
--jq '.items[] | {number, title, html_url, updated_at, draft: true, repo: (.repository_url | split("/") | last), user: .user.login}'
```
Run all searches in parallel across team members. Deduplicate by PR number + repo.
### Reviews and requested reviewers
For each PR:
```bash
gh api "repos/{org}/{repo}/pulls/{number}/reviews" \
--jq '[.[] | select(.user.login | test("\\[bot\\]$") | not) | {user: .user.login, state}]'
```
```bash
gh api "repos/{org}/{repo}/pulls/{number}/requested_reviewers" \
--jq '{users: [.users[].login], teams: [.teams[].slug]}'
```
Filter out bot reviews (logins ending in `[bot]`) — they're noise from CI integrations, not human review activity.
Run these in parallel across PRs where possible. If you hit rate limits, back off and retry.
## Classification
### Staleness thresholds
| Category | Threshold |
|----------|-----------|
| Stale (pod-wide) | `updated_at` > 24 hours ago |
| Needs attention | `updated_at` > 12 hours ago |
| Parked draft | draft + `updated_at` > 30 days ago |
Calculate hours (or days for parked drafts) since `updated_at` relative to now. Round to the nearest whole number.
### Review state
Determine per-PR by reading the reviews list chronologically:
- **Approved** — at least one `APPROVED` review, no subsequent `CHANGES_REQUESTED`
- **Changes requested** — most recent non-dismissed review is `CHANGES_REQUESTED`
- **Pending** — has requested reviewers who haven't submitted a review
Show reviewer names in each state (e.g., "approved by Alice, Bob").
## Report Format
```
# {team_name} Code Review Report — {YYYY-MM-DD}
> Generated for **{display_name}** | {n} open PRs across {m} members
```
### Section 1 — Stale PRs (>24h no action)
All open PRs across the team (including drafts) where `updated_at` > 24h. Only exclude drafts older than 30 days — those go in the "Parked Drafts" section instead. Label draft PRs with a `[Draft]` tag so they're visually distinct.
For each PR, show:
| Owner | PR | Hours stale | Review state | Next action |
|-------|-----|-------------|--------------|-------------|
| Display name | [Title](url) | N hours | Approved by X / Changes requested by Y / Pending: Z | One-line recommendation |
Sort by staleness descending. "Next action" should be specific and direct: "Merge — already approved," "Address feedback from Carol," "Needs a reviewer assigned."
If no stale PRs: *"No stale PRs — the team is on top of reviews."*
### Section 2 — Needs My Attention (>12h no action)
Two sub-sections:
**PRs I need to review**
PRs where I'm a requested reviewer and haven't submitted a review yet. Show: author, title+URL, hours waiting.
**My PRs needing action**
My own PRs that are approved (merge them!) or have changes requested (address feedback). Show: title+URL, state, hours since last update.
If nothing in either sub-section: *"Nothing needs your attention right now."*
If the user has stale PRs in Section 1 but none qualify here (e.g., all are drafts or pending first review), add a brief note pointing them back: *"Your 3 open PRs are stale but waiting on reviewers or still in draft — see Section 1 above."* This bridges the gap so Section 2 doesn't feel disconnected when all the user's action items are upstream.
### Active (FYI)
My open PRs or pending review requests updated within the last 12 hours. One line each: title, URL, current state. No action needed — just awareness.
If nothing active: omit this section entirely.
### Parked Drafts
Draft PRs from any team member untouched for 30+ days. Show: owner, title+URL, days since update. These are informational — the team may want to close or revive them.
If none: omit this section.
## Output
Always render the full report as formatted markdown in the conversation.
If the user asks to save to a file, write to the path they specify. If they say "save it" without a path, default to `./pr-report-{YYYY-MM-DD}.md`.
## Edge cases
- A PR can appear in both Section 1 (pod-wide stale) and Section 2 (needs my attention). That's expected — different audiences for the same PR.
- If a team member's PRs can't be fetched (permissions, API error), note it in the report footer and continue with the rest.
- If `gh` is not installed or not authenticated, tell the user to run `gh auth login` first.
No comments yet. Be the first to comment!