.cursor/skills/merge-dependabot-prs/SKILL.md
Treat each blocked PR as its own small diagnosis, not one "just merge it" action.
Confirm before anything consequential. Approving, closing, pushing to a PR
branch, merging main into someone's branch, and rerunning CI all touch shared
state. Triage everything into buckets first, then confirm the plan per bucket
with AskUserQuestion — not per PR, and not after the fact. Re-confirm if a
genuinely new kind of problem appears mid-flight (e.g. a real regression where
a mechanical fix was expected).
main merges exclusively through the merge queue ("Main Protection"
ruleset). Enqueue with gh pr merge <pr> --auto — no strategy flag; the
queue picks the method. --squash/--merge/--rebase will be rejected.quality-checks, playwright-required, database-tests,
backend-check, mypy-check, Jest Tests, required.required (in pr-integration-tests.yml) and playwright-required (in
pr-playwright-tests.yml) are aggregate needs: [...] + if: always()
jobs over the slow integration/playwright matrices. If either is absent
from gh pr checks, its matrix is still running — the PR isn't blocked.
(merge-group.yml provides instant-pass stubs of the same names inside the
queue itself.)mergeStateStatus/autoMergeRequest are unreliable for "is it actually
queued" — query the queue directly: references/graphql-queries.md.gh pr list --search "is:open author:app/dependabot assignee:<user>" \
--json number,title,headRefName,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup
PRs are labeled by ecosystem (dependabot:python, dependabot:javascript,
dependabot:docker, dependabot:actions, plus dependabot:sandbox) and
assigned per .github/dependabot.yml. Flag duplicates: two PRs bumping the
same package, or a manual bump PR overlapping a bot one.
These PRs aren't in a rush. Wait for every check to complete — required and
advisory alike (e.g. storybook-build on web/** changes, which never gates
the queue but pages Slack if broken post-merge) — and treat any red check as
a failure to classify, never as noise to skip.
Independent of bucket, assess compatibility: note each PR's semver jump and whether the package is production or dev-only. Major bumps (and 0.x minors, which semver allows to break) are never covered by a blanket "enqueue the green ones" — green CI proves the build, not the behavior. Surface each one individually in the confirmation with a one-line breaking-changes summary from the release notes Dependabot embeds in the PR body, and let the user opt in per PR.
Summarize buckets and proposed actions, confirm with AskUserQuestion, then act.
gh pr review <pr> --approve
gh pr merge <pr> --auto
If a PR falls out of the queue (e.g. head_ref_force_pushed after a Dependabot
rebase), re-running gh pr merge <pr> --auto is routine, not a failure.
gh pr closeOnce the bucket is approved, individual stale-generated-file fixes don't need per-PR confirmation. Known Onyx cases:
dependabot:python): the exported backend/requirements/*.txt
files go stale when only pyproject.toml/uv.lock were bumped. Regenerate
via the same pre-commit hooks CI uses:
pre-commit run --files pyproject.toml uv.lock backend/requirements/*.txt
dependabot:javascript): stale bun.lock — run
bun install in the bumped directory (repo root or web/).Getting the branch: prefer the harness's isolated-worktree feature if it has
one (Claude Code: EnterWorktree). Otherwise, if the current checkout is
clean, work in place — gh pr checkout <pr>, fix, push, and return to the
previous branch. If neither applies (e.g. dirty checkout), ask the user where
to resolve (AskUserQuestion) rather than picking a spot — and steer away
from tmpfs paths like /tmp, which can hit "Disk quota exceeded"
mid-post-checkout hook (uv sync/bun install) even when they look roomy.
gh run rerun <runId> --failed). If the same
failure recurs, stop and ask — a persisting "flake" may not be one.@dependabot rebase (or
recreate) — Dependabot owns the branch and will redo it properly.@dependabot rebase discards
non-Dependabot commits. Instead rebase onto origin/main yourself, rerun
the step 5 regeneration if lockfiles conflicted, push with
--force-with-lease, and verify git diff origin/main...HEAD --stat still
shows only the intended bump. If a pre-push hook trips on a stale local
cache (e.g. dev type-gen referencing a file deleted upstream), clear the
cache and retry — don't skip the hook.Prefer one polling loop (e.g. Monitor) over repeated manual checks: watch
both queue state and PR state (MERGED/CLOSED), and surface new failures as
they appear rather than staying silent until success.
Merged (N): #A, #B, #C
Closed as superseded (N): #D (superseded by #E)
Left for you (N): #F — <specific unresolved reason>