Personal Claude Code configuration. The headline piece is the PR babysitter: an always-on service that sweeps my open pull requests in the mention-me organisation and, for each one, checks CI, review comments and merge conflicts, fixes what it safely can in a git worktree, pushes, and reports to Slack. Modelled on haacked/dotfiles, adapted to my workflow.
ai/skills/
babysit-prs/ orchestrator: enumerate, classify, dispatch, state, notify
scripts/classify-pr.sh quiet/active classification seam (the tested core)
ci-monitor/ CI arm: triage flaky vs legit, rerun, fix, push
address-pr-reviews/ reviews arm: Greptile + human comments (agree-auto, disagree-held)
resolve-conflicts/ conflicts arm: merge main in, mechanical-safe resolves only
ai/agents/
report-flake.md records genuine flakes as deduplicated Linear issues
bin/
babysit-prs-worker.sh one headless sweep (fired by launchd)
babysit-prs-service.sh manage the LaunchAgent (install/start/stop/status/logs/run/resume)
detect-pr.sh, gh-resolve-threads, slack-notify.sh, linear-flake.sh
lib/ git-worktree, github, reviews, logging, launchd-service, test helpers
macos/LaunchAgents/ the com.joesaunderson.babysit-prs LaunchAgent plist
config.sh non-secret configuration (channel, team, cadence, allowlist)
install.sh tier 1: symlink skills/agents into ~/.claude, install deps
setup.sh tier 2: collect secrets, validate, enable the service
docs/pr-babysitter/ the design record (spec, decisions, ADRs, architecture diagram)
Two tiers, separable. Tier 1 installs the skills and dependencies; tier 2 configures and enables the always-on service.
git clone git@github.com:joesaunderson/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
./install.sh # symlink skills/agents into ~/.claude, install mergiraf, set git conflictStyle
./setup.sh # collect Slack bot token + Linear API key, validate, optionally enable the serviceYou can stop after install.sh to use the skills by hand without the background service.
Each sweep enumerates my open pull requests updated within the recency window (--since, default 7 days), and classifies each as quiet or active via classify-pr.sh. Quiet pull requests are skipped almost for free. Active ones are dispatched to the arms the classifier names:
- CI (
ci-monitor): re-run flaky failures (recorded as deduplicated Linear issues byreport-flake), fix legitimate ones and push. - Reviews (
address-pr-reviews): fix legitimate findings; handle Greptile threads fully automatically; auto-acknowledge fixed human comments; hold any disagreement reply for me. - Conflicts (
resolve-conflicts): mergemainin, auto-resolve mechanically-safe conflicts, flag migrations and logic conflicts for me.
State in ~/.local/state/babysit-prs/state.json makes sweeps idempotent: while a commit is unchanged, no expensive work is repeated. It never merges, closes, marks ready, or force-pushes. See docs/pr-babysitter/SPEC.md.
bin/run-tests.sh # run every test-*.sh (classify-pr, git-worktree, conflict-status, categorize)GitHub Actions (.github/workflows/ci.yml) runs two jobs on every push to main and every pull request: shellcheck (all shell scripts, warning severity) and test (bin/run-tests.sh).
/babysit-prs --dry-run # report what a sweep would do, change nothing
/ci-monitor 123 # run a single arm on one PR
bin/babysit-prs-service.sh status # service state and last run
bin/babysit-prs-service.sh logs # tail the launchd log- Headless permission posture: the service worker runs
claude --printwith an explicit tool allowlist (BABYSIT_ALLOWED_TOOLSinconfig.sh), notbypassPermissions, because sweeps read untrusted pull-request and comment text. Broaden the allowlist if a fix needs a command it denies (project-specific test runners, for example). SetBABYSIT_PERMISSION_MODE=bypassPermissionsonly if you accept turning the approval gate off. - Workflow files: the
ghtoken deliberately lacks theworkflowscope, so the babysitter cannot modify.github/workflows/. Fixes that would touch a workflow file are flagged for me instead of pushed. - Cadence: launchd fires every 10 minutes; the worker no-ops outside working hours (08:00-19:00, Mon-Fri), so sweeps run only during the day and never overlap.
- Secrets live in
~/.config/babysit-prs/env(chmod 600, git-ignored), never in this repo.