About babysit-pr
babysit-pr is a skill that monitors one GitHub pull request until it is merged, closed, or requires user input. It cycles through review items and CI failures, applies or proposes fixes under explicit limits, and keeps polling rather than treating a green run as completion.
Key features
- 01Poll PR state and fresh review items
- 02Classify CI failures before acting
- 03Fix real failures or rerun flaky checks
- 04Require confirmation before replying to human reviews
- 05Track attempt limits and terminal states
Use cases
- 01Monitor a pull request through review and CI updates
- 02Address bot feedback and verified CI failures
- 03Hold a green pull request open for late reviews
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ timschoch/ skilly --skill babysit-prAfter installing, type/babysit-prin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
README.mdscripts/classify-failure.shclassify-failure.test.shpr-state.shpr-state.test.shresolve-thread.shwatch.shwatch.test.shDetails
From the project READMEHold one PR until it is merge-ready: poll, classify, fix, push, poll again. Terminal states are merged, closed, needs-user. Nothing else ends the loop, not a push, not a green run, not a report.
Loop
Each pass:
- Snapshot.
bash scripts/pr-state.sh <pr> [--since <lastPushAt>]. Carry the previous pass'slastPushAtinto--since, so only review items newer than your last push surface. - Terminal first.
stateisMERGEDorCLOSED: report it and stop. - Review items before CI. A fix commit retriggers CI, so answering review first avoids spending a rerun on a SHA you are about to replace.
- CI. For each check with a failing
conclusion, runbash scripts/classify-failure.sh <check-url>before touching code. - Push. Commit on the PR head branch, push, then return to step 1 on the new SHA.
- Wait.
bash scripts/watch.sh <pr>blocks until the checks settle, then prints a fresh snapshot. Use it instead of sleeping. Cap it withBABYSIT_MAX_MINUTES, default 60.
Rules
- Published and fresh only. Act on review items whose
submittedAtorcreatedAtis newer thanlastPushAt.pr-state.shdropsPENDINGreviews: a reviewer still drafting has not spoken yet. An item answered before the last push stays answered. - Classify a failure, then act on the class.
classify-failure.shprintsflakyorrealfrom log evidence, then the first 20 failing lines.real: patch the branch.flaky: rerun it withgh run rerun <run-id> --failed. While a failure readsflaky, leave tests, build scripts, CI config and dependency pins as they are. A patch that only silences infra hides the signal for everyone downstream. - CI budget: 3 attempts per PR. An attempt is one fix push or one rerun made for a red check; a review-fix push is none. It fails when the checks settle red again.
- Third failed attempt: stop at needs-user, even with ideas left.
- Tell the user the failing checks, what each attempt changed, and the first 20 failing lines.
- Humans get the user's words, not yours. A human reviewer is any
reviews[].authorthat is neither the PR author nor flaggedisBot. Surface their item to the user with a suggested reply, and wait for explicit confirmation before posting anything to GitHub. Bot items you act on and resolve yourself. - Resolve what you fixed. Once the fix is pushed:
bash scripts/resolve-thread.sh <threadId>, usingthreads[].idfrom the snapshot. - Merge is the user's call. The done rule (
.claude/rules/workflow-done.md): committed means done, pushed means signed off. Merge mode starts only with--merge, or when the user says merge in this session. Without it, stop at green and report. - Merge mode merges at green, never before. Run
gh pr merge <pr> --squash --match-head-commit <headSha>,--mergein place of--squashfor--merge=merge. Then take one more snapshot:MERGEDends the loop.headShacomes from the green snapshot: a push that lands after it blocks the merge.- Never
--auto: on a repo without required checks it merges at once, before CI settles. - Never
--delete-branch.
- Green is a milestone, not an exit. No failing check,
mergeable: MERGEABLE, no unresolved thread: report "ready to merge", then keep polling. Late review items still land while the PR is open. Merge mode merges here instead.
Reviewer set
pr-state.sh reads bot logins from .skilly/config.json at the git root:
{ "review": { "bots": ["chatgpt-codex-connector[bot]", "some-reviewer"] } }
A login ending in [bot] also counts. Missing key or missing file means an empty list, and every reviewer but the PR author reads as human. Read the config each run; keep no login in your head.
CI
Checks are whatever the PR reports. The repo's tier in .skilly/config.json decides the set (the verify skill explains tiers). verify is the one check every tier runs, so a red verify is always a statement about this branch.
Commits
Conventional commit, prefix by content: fix: when a check was red, chore: for a lint or config nit. Add one body line, so the origin of the change stays greppable:
Babysit-pr: fixes review thread <thread-url>
Report
Close every pass with: head SHA, check tally, mergeability, what was pushed, CI attempts spent out of 3, what is still open.