PR Monitor Skill
SkillCommunicationMonitor open GitHub PRs across all repos in ~/Dev. Checks PR age, flags stale PRs, and optionally alerts via Aivena/Telegram. Uses `gh pr list` for accurate GitHub data.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the PR Monitor Skill skill
What this skill tells your AI
The instructions your AI receives, as published by espennilsen/pi in skills/pr-monitor/SKILL.md and read by ahel’s review.
Scan all GitHub-hosted repos in ~/Dev for open pull requests. Flag stale PRs and report status.
Procedure
Step 1: Scan all repos for open PRs
Run this exact command to collect all open PRs:
for dir in ~/Dev/*/; do
if [ -d "$dir/.git" ]; then
remote=$(git -C "$dir" remote get-url origin 2>/dev/null)
if echo "$remote" | grep -q github.com; then
repo=$(echo "$remote" | sed 's/.*github.com[:/]\(.*\)\.git/\1/' | sed 's/.*github.com[:/]\(.*\)/\1/')
prs=$(timeout 30s gh pr list --repo "$repo" --state open --json number,title,createdAt,headRefName,author,isDraft,reviewDecision)
pr_count=$(echo "${prs:-[]}" | jq 'length' 2>/dev/null)
if [ "${pr_count:-0}" -gt 0 ]; then
echo "=== $(basename "$dir") ($repo) ==="
echo "$prs" | jq -r '.[] | " #\(.number) [\(.headRefName)] \(.title) (by \(.author.login), created \(.createdAt[:10]), draft: \(.isDraft), review: \(.reviewDecision // "none"))"'
echo ""
fi
fi
fi
done
Step 2: Calculate PR age
For each PR, calculate age from createdAt to today. Classify as:
- 🟢 Fresh — 0–1 days old
- 🟡 Aging — 2–3 days old
- 🔴 Stale — 4+ days old
Step 3: Format the report
Output a table with columns:
| Repo | PR | Branch | Title | Author | Age | Status | Review |
|---|
Group by repo. Show age badge (🟢/🟡/🔴). Include draft status and review decision.
Step 4: Summary
End with:
- Total open PRs across all repos
- Stale count (4+ days) — these need attention
- Aging count (2–3 days) — these are approaching stale
- Action items — specific PRs that need review or merge
Step 5: Deduplication check (before alerting)
Before sending any Telegram alert, check today's daily memory log for PRs already covered. Optionally, write a lightweight per-PR "alert sent" timestamp (e.g., pr-monitor: [repo] #[number] — <date>) to memory so overlapping executions don't duplicate alerts.
memory_read(target: "daily")
Scan the result for PR references matching [repo] #[number]. Any stale PR already mentioned in today's standup or a prior pr-monitor alert today should be excluded from the new alert.
- If all stale PRs were already reported today → skip the alert entirely (no noise)
- If some are new → send alert only for the new ones
- If none were previously reported → send the full alert
Step 6: Alert (only for net-new stale PRs)
If net-new stale PRs remain after dedup, send an alert to Aivena via a2a_send:
Hey Aivena — PR staleness alert for Espen. Please relay to Telegram.
⚠️ [N] stale PR(s) found (4+ days old, not yet reported today):
- [repo] #[number]: [title] ([age] days)
...
These need review or merge.
— Fury
If no stale PRs exist, or all were already covered today, do nothing (no noise).
Notes
- Requires
ghCLI authenticated (gh auth status) - Requires
jqfor JSON parsing - Only scans repos with GitHub remotes
- Draft PRs are included but noted — they're expected to age longer
- The
reviewDecisionfield shows: APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED, or none
Signals
- GitHub stars
- 118
- Forks
- 13
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
pr-monitor- Source
- github.com/espennilsen/pi