Agent skill
pr-merge-watcher
Checks for merged PRs and updates Notion to Done. Use daily or on-demand to close out completed tickets after PR merge.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/pr-merge-watcher
SKILL.md
PR Merge Watcher
Scans open pipeline runs for merged PRs and updates Notion status to Done. Handles the common case where the agent is closed before PR merge.
When to Use
- Daily maintenance check
- After you know PRs have merged
- Resume pipeline-tracker shows stale "In Review" tickets
Workflow
1. Find Open Runs
Scan for runs in "pr-created" or "in-review" status:
find runs/ -name "status.json" -exec jq -c \
'select(.status | test("pr-created|in-review|ci-passed")) |
{id: .ticketId, status: .status, prNumber: .prNumber, prUrl: .prUrl}' {} \; \
2>/dev/null | grep -v '^$'
2. Check PR Merge Status
For each open run with a PR:
PR_NUMBER=123
gh pr view $PR_NUMBER --json state,mergedAt --jq '{state, mergedAt}'
Possible states:
OPEN- PR still open, skipMERGED- PR merged, update NotionCLOSED- PR closed without merge, mark as abandoned
3. Update Notion for Merged PRs
⚠️ Follow Notion Write Safety rules.
For each merged PR:
# Get ticket page ID from status.json
PAGE_ID=$(jq -r '.notionPageId' "runs/$TICKET_ID/status.json")
# Update via Notion MCP
# Status: In Review → Done
Log the write:
{
"notionWrites": [
{
"field": "Status",
"value": "Done",
"previousValue": "In Review",
"at": "...",
"skill": "pr-merge-watcher",
"success": true
}
]
}
4. Update Local Status
jq '.status = "done" | .completedAt = now | .mergedAt = .prMergedAt' \
"runs/$TICKET_ID/status.json" > tmp && mv tmp "runs/$TICKET_ID/status.json"
5. Handle Closed (Not Merged)
If PR was closed without merging:
⚠️ PR #123 was closed without merging
Ticket: {ticket title}
PR: {pr url}
Options:
1. Mark ticket as abandoned (Status → Not Started)
2. Keep current status (investigate later)
3. Archive run locally only
Your choice:
6. Generate Report
# PR Merge Watcher Report
**Scanned:** {timestamp}
**Runs checked:** {N}
## Merged PRs (Updated to Done)
| Ticket | PR | Merged At |
| ------- | ---- | ---------- |
| ABC-123 | #456 | 2024-01-15 |
| DEF-456 | #789 | 2024-01-16 |
## Still Open
| Ticket | PR | Status | Age |
| ------- | ---- | --------------- | ------ |
| GHI-789 | #101 | Awaiting review | 3 days |
## Closed Without Merge
| Ticket | PR | Action Taken |
| ------- | ---- | ---------------- |
| JKL-012 | #102 | Marked abandoned |
## Summary
- **Completed:** 2 tickets marked Done
- **Open:** 1 PR awaiting review
- **Abandoned:** 1 closed PR
Batch Mode
Run without prompts for automation:
# Auto-update all merged PRs, skip closed ones
amp -c "/skill pr-merge-watcher --batch"
In batch mode:
- Merged PRs → Auto-update to Done
- Closed PRs → Log warning, don't modify
- Open PRs → Skip silently
Scheduled Execution
Add to daily workflow:
# Morning check
0 9 * * * cd ~/repos/ticket-to-pr-pipeline && amp -c "/skill pr-merge-watcher --batch" >> logs/merge-watcher.log 2>&1
Or integrate with pipeline-tracker:
When running `/skill pipeline-tracker`:
1. Show dashboard
2. Auto-run pr-merge-watcher check
3. Report any newly completed tickets
GitHub Webhook Alternative
For real-time updates, set up a GitHub webhook:
- Create webhook on repo for
pull_requestevents - Filter for
action: closedwithmerged: true - Trigger Notion update via API
This is more complex but provides instant updates.
Edge Cases
PR Merged to Different Branch
If PR merged to non-main branch (e.g., staging):
- Check if eventually merged to main
- Or mark as "partial" completion
Multiple PRs per Ticket (Stacked)
Check stack.json for multi-PR tickets:
- All PRs merged → Done
- Some merged → Keep In Review
- Track individual PR states
Notion Page Deleted
If ticket page no longer exists:
- Log error
- Archive run locally
- Don't retry
Integration with Pipeline
Trigger Points:
- Manual:
/skill pr-merge-watcher - Via pipeline-tracker dashboard
- Scheduled cron job
- GitHub webhook (advanced)
Status Transitions:
in-review+ PR merged →donein-review+ PR closed →abandoned
Output Artifacts
| File | Location | Description |
|---|---|---|
| status.json | runs/{ticket-id}/status.json |
Updated with done/abandoned |
| merge-watcher-log.md | runs/merge-watcher-log.md |
Historical report |
Didn't find tool you were looking for?