Finishing a Development Branch
obra/superpowers
Walks the last step of a branch: confirm tests pass, detect the git environment, ask how to integrate, carry out your choice and clean up the worktree.
Land every open PR the user has not excluded — resolve merge conflicts, get stale approvals re-cast by the agent reviewer, and squash-merge each PR once it is approved and green — then report…
$ npx skills add vfarcic/dot-agent-deck --skill land-prs -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install vfarcic/dot-agent-deck land-prs --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/vfarcic/dot-agent-deck.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/land-prs .claude/skills/land-prs && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "land-prs" agent skill from https://github.com/vfarcic/dot-agent-deck/tree/main/.claude/skills/land-prs into .claude/skills/land-prs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "land-prs", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/vfarcic/dot-agent-deck/tree/main/.claude/skills/land-prsType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add vfarcic/dot-agent-deck --skill land-prs -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install vfarcic/dot-agent-deck land-prs --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vfarcic/dot-agent-deck.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/land-prs .agents/skills/land-prs && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "land-prs" agent skill from https://github.com/vfarcic/dot-agent-deck/tree/main/.claude/skills/land-prs into .agents/skills/land-prs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "land-prs", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add vfarcic/dot-agent-deck --skill land-prs -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install vfarcic/dot-agent-deck land-prs --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vfarcic/dot-agent-deck.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/land-prs .cursor/skills/land-prs && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "land-prs" agent skill from https://github.com/vfarcic/dot-agent-deck/tree/main/.claude/skills/land-prs into .cursor/skills/land-prs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "land-prs", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/vfarcic/dot-agent-deck.git --path .claude/skills/land-prs--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add vfarcic/dot-agent-deck --skill land-prs -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install vfarcic/dot-agent-deck land-prs --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vfarcic/dot-agent-deck.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/land-prs .gemini/skills/land-prs && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "land-prs" agent skill from https://github.com/vfarcic/dot-agent-deck/tree/main/.claude/skills/land-prs into .gemini/skills/land-prs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "land-prs", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install vfarcic/dot-agent-deck land-prsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add vfarcic/dot-agent-deck --skill land-prs -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/vfarcic/dot-agent-deck.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/land-prs .github/skills/land-prs && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "land-prs" agent skill from https://github.com/vfarcic/dot-agent-deck/tree/main/.claude/skills/land-prs into .github/skills/land-prs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "land-prs", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add vfarcic/dot-agent-deck --skill land-prs -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install vfarcic/dot-agent-deck land-prs --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/vfarcic/dot-agent-deck.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/land-prs .opencode/skills/land-prs && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "land-prs" agent skill from https://github.com/vfarcic/dot-agent-deck/tree/main/.claude/skills/land-prs into .opencode/skills/land-prs/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "land-prs", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
land-prsLand every open PR the user has not excluded — resolve merge conflicts, get stale approvals re-cast by the agent reviewer, and squash-merge each PR once it is approved and green — then report…
Land PRs is an agent skill from vfarcic/dot-agent-deck. Land every open PR the user has not excluded — resolve merge conflicts, get stale approvals re-cast by the agent reviewer, and squash-merge each PR once it is approved and green — then report exactly what is left and why. Use when asked to merge the open PRs, land what is ready, clear the PR backlog before a release, or as the first step of "make a release" (tag-release calls it). It never approves anything, and merges an unapproved PR only in the one admin case Step 6 describes, on the user's explicit instruction.
Its SKILL.md is about 7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development, covering Git workflow. The repository describes itself as: A rich terminal dashboard for monitoring and controlling multiple AI coding agent sessions. The licence is MIT.
8 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit fc72b05. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitghcargopnpmFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
github.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Land PRs loads about 7k tokens when it runs. Until then it costs about 132 tokens; SKILL.md has 4,190 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from vfarcic/dot-agent-deck at commit fc72b05, republished under its MIT licence (© vfarcic). 4,190 words, ~6,963 tokens.
.claude/skills/land-prs/SKILL.md (or your agent's skills folder).The goal is every open PR merged, except the ones the user excludes. A PR that cannot merge yet is a problem to fix, not a row to skip: a conflict gets resolved, a dismissed approval gets re-requested, a pending check gets waited for. What this skill does not do is decide on the user's behalf — the stops in Step 6 go back to them.
This skill is project-local and owned here (CLAUDE.md rule 13). Edit it when a new scenario turns up; that is expected.
--admin.APPROVED can still have an agent pushing to it.gh api repos/{owner}/{repo}/rules/branches/main --jq '.[]|{type, p:.parameters}'At the time of writing that says: one approving review, dismiss_stale_reviews_on_push: true, required_review_thread_resolution: true, five required contexts (build, build-macos, build-windows, security, e2e-deterministic), and strict_required_status_checks_policy: false. Two consequences shape everything below:
main. Only a real conflict blocks a merge — not being behind. That is the ruleset; this skill adds the overlap check on top of it (Step 3), because a branch that is behind can still break main when main changed its files.If what you read back differs, trust the API over this paragraph and update it.
gh pr list --state open --limit 100 --json number,title,reviewDecision,mergeStateStatus,mergeable,author,headRefName,headRefOidFor each PR, also read its unresolved thread count (GraphQL reviewThreads { isResolved }), its required checks (gh pr checks <n> --required), and its non-required checks (gh pr checks <n>). Then put every PR, minus the user's exclusions, in exactly one bucket:
| Bucket | Test | Action |
|---|---|---|
| Ready | APPROVED, CLEAN, 0 unresolved, required checks pass, every failing or pending non-required check explained | merge (Step 3) |
| Conflicting | mergeable: CONFLICTING | resolve (Step 4), then re-review |
| Needs review | REVIEW_REQUIRED, green, 0 unresolved | request review (Step 5) |
| Checks running | a required check pending | wait, then re-bucket |
| Unresolved threads | any unresolved thread | Step 6 |
| Failing CI | a required check failed | Step 6 |
| Changes requested | CHANGES_REQUESTED | Step 6 |
A non-required check is not a formality. UNSTABLE in mergeStateStatus means one is failing, and GitHub will merge past it. Read why before merging: on 2026-09-27 #1363's advisory desktop-driver failure was the only sign that merging it would re-break the desktop build (Step 3, "main also moves under you"). Merge past a failing or pending non-required check only once you can say it is unrelated to this PR — the same failure on main, a known flake re-run green — and say so in the report. "Unrelated" clears this PR, not the red (CLAUDE.md rule 6): a flake that re-ran green is still a red with no owner unless it is already quarantined or an open PR fixes it. So give it one before you merge past it — hand it to a unit or to the user (Step 6) — and name the owner in the report. The PR itself does not wait for that fix to land: the red is not on its required path, and holding every PR behind every flake is how a backlog stops moving. CLAUDE.md rule 8 covers the same trap for auto-merge.
Address every PR by its PR ref, never by origin/<headRefName>. A fork PR's branch is not on origin, and an origin branch can share a fork's branch name while pointing at unrelated code. Fetch the head the PR will actually merge — with a leading +, so the ref follows a force-push instead of silently keeping the old commit: git fetch origin +pull/<n>/head:refs/remotes/origin/pr-<n>, then confirm git rev-parse origin/pr-<n> equals gh pr view <n> --json headRefOid --jq .headRefOid, and use origin/pr-<n> everywhere below. It also covers the case where git fetch origin <branch> simply fails (seen with a Renovate branch) — never read a failed fetch as "no conflicts".
UNKNOWN is not a bucket. GitHub recomputes mergeability after main moves and reports UNKNOWN for seconds to minutes. Poll until it settles; never read it as blocked or as clean.
Show the user the table before acting, with the exclusions and what you will do per bucket.
When several PRs were dispatched from the same base, they often carry the same fix for a red they each met — measured on 2026-09-26, four PRs carried their own variant of the same remote_tunnel probe-test isolation. The first to merge makes every other copy a conflict. Recognise the pattern up front (the same file conflicting in several PRs), so Step 4 resolves them the same way.
Merge one PR at a time, and re-read every remaining PR's mergeable after each merge — a merge can turn a clean PR into a conflicting one.
Decide the order by simulating it, not by guessing from file lists. Two PRs editing the same file usually merge cleanly; guessing from overlap held six approved PRs back for no reason on 2026-09-26. git merge-tree answers it exactly and touches no working tree:
git fetch origin
c=$(git rev-parse origin/main)
# stack EVERY PR you intend to land, in the order it will merge — the ready
# ones first, then the ones awaiting review — so the awaiting ones are tested
# against each other too
for x in <PRs, in merge order>; do
git fetch -q origin "+pull/$x/head:refs/remotes/origin/pr-$x"
h=$(git rev-parse "origin/pr-$x")
[ "$h" = "$(gh pr view "$x" --json headRefOid --jq .headRefOid)" ] || { echo "#$x: fetched ref is not the PR head"; exit 1; }
# capture first, then test merge-tree's OWN exit status: piping it into
# `head` would test head's status and let a conflict read as clean
if out=$(git merge-tree --write-tree "$c" "$h"); then
c=$(git commit-tree "$(printf '%s\n' "$out" | head -1)" -p "$c" -p "$h" -m "sim #$x")
echo "#$x stacks cleanly"
else
echo "#$x conflicts with what is stacked before it" # do not stack it; it goes to Step 4
fi
done
git update-ref refs/heads/sim/integration "$c"Simulate the awaiting-review PRs in the same stack, not just against the ready ones. Checking each only against the ready stack misses two awaiting PRs that conflict with each other — on 2026-09-26 #1338 and #1331 each merged cleanly on top of the ready stack, and #1331 went CONFLICTING the moment #1338 landed.
A clean merge is not a green merge. merge-tree finds textual conflicts only. Two approved PRs can merge cleanly and still break each other's behaviour — #1340's voice deck-switch test failed after #1334 changed how desktop settings save, with no conflict marker anywhere. Step 4's gates catch that; run them on every branch you merged main into, including the desktop frontend's tests when desktop/ is touched.
Then build and test the stacked result before anyone reviews or merges anything. Check sim/integration — every PR that stacked cleanly, awaiting-review ones included — out detached in the land worktree, and run the full gates on it — rule 2's clippy, cargo test-fast, and the desktop pnpm test plus typecheck. This is the merge queue this repository cannot have (a user-owned repo rejects the merge_queue rule, #1088), run once for the whole batch. It finds the clashes merge-tree cannot see while every PR still has its approval.
Batch what the simulation clears, serialise what it does not. Merging one PR never dismisses another's approval — only a push to that PR does. So every PR that stacks cleanly and passes on the integration build can be reviewed in one sweep and merged back to back with no further pushes. Only the PRs the simulation flags need a push: resolve those one at a time after the PR they collide with, or stack them onto it beforehand so the resolution is done and gated once — after the base lands, one mechanical merge of main and a re-review still remain (item 4 below). Finding collisions during merging instead — what happened on 2026-09-26 — turns every one into a push, a CI run and a re-review, and the next merge can surface the next one.
Then:
main holds A's version of every hunk A touched while B's branch holds the combined version, and git sees two different edits of the same lines wherever both PRs edited them — measured on 2026-09-27, #1346 went CONFLICTING the moment #1347 (its base) landed. What stacking buys is that the resolution is already known: merge main into B keeping B's side in those hunks (B already contains A's content), check that git diff origin/main HEAD now shows only B's own changes, and re-review B. When main's tree is byte-identical to A's final head (check git rev-parse origin/main^{tree} against git rev-parse <A-head>^{tree} — true when nothing else landed in between), B's current tree already is the right result: git merge -s ours origin/main records main as a parent without changing a file, and cmp <(git diff origin/main HEAD) <(git diff <A-head> <B-head-before>) proves the diff is exactly B's. Nothing was edited, so the gates that passed on that tree still hold. It does not buy a push-free merge. And a stacked PR's diff shows the base's changes, so a reviewer's findings about the base's code land on the upper PR — four of #1346's six threads were about #1347. Route those to the base PR while it is open, or to a follow-up issue once it has merged (#1365), and resolve them on the upper PR with a pointer.REQUEST_CHANGES, a late finding — means re-merging A's new head into B and re-reviewing B, and so on up the stack. So review the stack bottom-up and hold B's review until A is approved: on 2026-09-27 #1347 drew a REQUEST_CHANGES while #1346 (stacked on it) and #1342 (stacked on #1346) were queued behind it, and reviewing them first would have spent two reviews on heads about to change.main into the sweep once more, re-run its gates so the rename covers what just arrived, and merge it then.Run the overlap check right before each merge. The rule is /issue-queue's "The overlap check before a merge" (.claude/skills/issue-queue/SKILL.md), and it applies here as written: list the commits main gained since the PR branched off that touch the files it changes, and when it lists any, update the branch, let CI run on the combined head, get the approval again (Step 5), and check again. One narrowing applies in this skill only: a listed commit that is the squash of a PR stacked before this one in the sim/integration build above, and merged in this run, does not count, because that build already ran the gates on the two together. Any other listed commit counts — one from another session, from Renovate, from the user, or from a PR this run merged without stacking it. The trade is stated rather than hidden: the integration build runs rule 2's clippy, cargo test-fast and the desktop tests on the combined code, not build-macos, build-windows or e2e-deterministic, and the build of main after every batch (below) is what checks the result.
Merge with a squash, matching the repository's history, pinned to the head you checked:
gh pr merge <n> --squash --match-head-commit <sha> # the sha on the overlap check's `head` line
gh pr view <n> --json state --jq .state # read it back: MERGEDTake <sha> from the check's output rather than reading the head again now, so a push after the check makes the merge refuse instead of landing a head nobody checked. Decide on the read-back, not on the exit code.
After every batch of merges, build main before doing anything else: git fetch origin, check out origin/main detached in the land worktree, and run rule 2's clippy command (it compiles every target), cargo test-fast, and the desktop tests. Because the ruleset does not require branches to be up to date, two PRs that are each green can merge cleanly and still not compile together. Measured on 2026-09-26: #1335 added a two-argument call in a src/main.rs test, #1341 then gave the function a third parameter, and main stopped compiling its bin tests with neither PR ever red. When it happens, fix main first with its own small PR (it is a red on main, CLAUDE.md rule 6) — every branch you merge main into inherits the break, so its gates prove nothing until then. So does every PR's CI, even on a branch you never touched: a pull_request run builds the PR merged into its base, so a PR whose checks were green goes red on its next push with the same error. Review the fix PR on its own (pr_number=<fix>) rather than in a sweep and merge it. Then merge the fixed main into each affected PR and push — gh run rerun does NOT help, because a re-run rebuilds the same merge commit it built the first time, which still carries the break. Only then sweep; the reviewer will not vote on a PR whose checks are red.
main also moves under you from outside this run — another deck, another session, the user merging by hand. Re-read main before each merge, and when a PR's premise is about main's state (a revert, a fix for a red), re-check that premise first: on 2026-09-27 #1363 was approved to revert the Rust half of a Tauri bump, but #1360 had meanwhile moved the npm half to match, so merging the revert would have re-broken the desktop build. A non-required check that fails on the PR but passes on main is the tell. Rework or close the PR rather than merge it.
Renovate merges some updates itself (its pull_request bypass, CLAUDE.md rule 8), so a Renovate PR can vanish from the list mid-run and change main under you. Re-list open PRs after every batch rather than working from the first listing. On 2026-09-26 #1358 moved the Rust tauri crate to 2.12.0 through that bypass while the npm @tauri-apps/* packages stayed at 2.11 — the npm half is held by pnpm's 24-hour release-age gate and Renovate's 3-day npm delay — and tauri build refuses the mismatch, which breaks the desktop-driver job and the release's desktop bundle. Check that the Tauri crate and npm versions agree on the same minor before cutting a release; do not paper over it with a minimumReleaseAgeExclude without the user's say-so.
Work in a sibling worktree (CLAUDE.md rule 14), never in the main checkout — every dispatched unit is cut from its HEAD. The unit that wrote the PR has usually closed its tab by now, and its worktree went with it, so do not count on finding one.
Work on a detached checkout of the PR's head, so it does not matter whether a local branch exists or is checked out in another worktree (the #714 team's still was), and push the result back to the PR's branch by name:
git fetch origin
[ -d ../<repo>-land ] || git worktree add --detach ../<repo>-land origin/main
cd ../<repo>-land
git fetch -q origin "+pull/<n>/head:refs/remotes/origin/pr-<n>"
git switch --detach "origin/pr-<n>"
git merge origin/main # resolve the conflicts (rules below)
git add <each resolved file>
git diff --name-only --diff-filter=U # must print nothing
git commit --no-edit # completes the merge; nothing is pushed without it
# gates (below), then:
# same-repository PR only (isCrossRepository is false) — see below for a fork
git push origin "HEAD:$(gh pr view <n> --json headRefName --jq .headRefName)"That push is a fast-forward of the PR branch, so it is refused rather than overwriting anything if the branch moved meanwhile — fetch again and redo the merge. Never push a fork PR's resolution to origin: origin is the base repository, so HEAD:<headRefName> there creates or moves an unrelated same-named branch and leaves the PR untouched. Check gh pr view <n> --json isCrossRepository,maintainerCanModify first. For a fork, and only when maintainerCanModify is true, push to the head repository itself — gh pr view returns the owner and repository as objects, so build the URL from their fields: git push "$(gh pr view <n> --json headRepositoryOwner,headRepository --jq '"https://github.com/\(.headRepositoryOwner.login)/\(.headRepository.name).git"')" "HEAD:<headRefName>". Otherwise ask its author.
Resolution rules, from cases met so far:
CONTRACT_BREAKS in src/daemon_protocol.rs is append-only (CLAUDE.md rule 12). When both sides appended, keep main's entries first and the branch's after them, and never drop or edit one.main's copy of the file with git checkout origin/main -- <file>, but only after confirming the branch's hunks in that file are nothing but the duplicate, and that nothing else in the branch calls a helper the branch added there (git grep the branch, excluding that file).git merge -X theirs as a shortcut. It resolves only the conflicting hunks and keeps the branch's non-conflicting ones, which half-applied a fix on 2026-09-26 and left an unused variable behind.main, and port the branch's additions onto it (constants, extra env, call-site changes). Read both sides before editing.None for the parameter #1341 added, and #1346's bare return; became AppliedEvent::Rejected once #1347 gave the function a return value, because #1347 defines Rejected as "nothing on any card moved". Say which definition decided it in the commit. Anything that needs judgement about behaviour goes to a unit.Then run the gates on the merged branch before pushing — cargo xtask affected-checks --run, which for a PR with any Rust, build input or unmapped path in it runs CLAUDE.md rule 2's cargo fmt --check and cargo clippy --workspace --all-targets --features e2e,e2e-live -- -D warnings and rule 5's cargo test-fast, and for a PR that is only mapped text runs the tests that read those files; then the tests covering whatever the conflict touched, and the desktop frontend's pnpm test and typecheck whenever the PR or the merged-in main touches desktop/ (cargo test-fast does not run vitest). A gate that fails after a clean merge is a semantic clash between two PRs: that is code, not conflict resolution, so it goes to a unit (Step 6). The push dismisses the approval, so the PR moves to "Needs review".
Several PRs can share one worktree: switch between detached heads, but finish (commit or git merge --abort) one merge before switching.
If an edit is refused by the permission classifier, stop on that PR, leave the merge in progress, and tell the user which file and what the resolution would be. Do not reach the same edit by another tool.
The approving actor is the agent reviewer, pr-review-batch.yml (CLAUDE.md rule 8). Its mechanics decide how to call it:
It only votes on a PR whose required checks have all concluded. Dispatching it right after a push produces skip #<n>: required context '…' has not concluded and no vote. Wait for CI first.
Its concurrency group holds one running and one pending run. A second dispatch replaces the pending one, so dispatching once per PR in a burst cancels all but the last. After CI is green on every PR you need reviewed, dispatch one sweep instead:
gh workflow run pr-review-batch.yml -f dry_run=falsedry_run defaults to true on a manual dispatch, which produces verdicts and casts no vote. With pr_number set it reviews one PR; dispatch those one at a time, each after the previous run finishes.
It reviews three PRs in parallel (max-parallel: 3), so a sweep over many PRs takes several rounds.
A sweep also covers PRs you are not landing. That is its normal job — an approval is not a merge, and the exclusions are still yours to hold.
For a stack, review bottom-up one PR at a time (pr_number=<n>), each after the previous review has finished and the previous PR has merged: an upper PR's review is wasted if its base draws a change request. A small loop that waits for CI, dispatches the review, waits for it, and merges only when the PR reads MERGEABLE APPROVED with no unresolved thread, a clean merge-tree against main and an overlap check (Step 3) that lists nothing — stopping at the first PR that does not — keeps this unattended without ever merging past a problem.
Wait for CI on the PR's current head SHA, not for gh pr checks to read green. Right after a push gh pr checks can still report the previous head's results, and a review dispatched then skips the PR (required context 'build' has not concluded). Read the head with gh pr view <n> --json headRefOid and wait for gh run list --commit <sha> --workflow ci.yml to report completed first.
Every push brings a fresh Qodo review, including a push that only merges main in. Its new findings land as threads and block the reviewer's vote, so after each push read the threads again before expecting a vote.
When a vote arrives, go back to Step 3. A REQUEST_CHANGES from the reviewer goes to Step 6.
Report these; do not work around them.
CHANGES_REQUESTED. Theirs to lift. Say what they asked for, and check whether it still applies on the current main — a blocker about files main no longer carries may have resolved itself (#1252: two fragments it "deleted" had since been consumed by a release). If it no longer applies and the reviewer is unavailable, the user decides. Do not dismiss the review and do not reopen the PR as a new one — the second has the effect of a dismissal with less of a record. The agent reviewer does not help here: it skips a PR with an open change request by rule (skip #<n>: changes requested by a reviewer), so there is no approval to get. What worked for #1252: on the user's explicit instruction, confirm the required checks are green, no thread is unresolved and the PR merges cleanly, run the overlap check (Step 3) and, when it lists anything, update the branch, wait for CI on the new head, run the check again, and ask the user again before merging, since the code they told you to merge has changed and no approval can be got back on this path; write the reason to a file — which blocker it was, why it no longer applies, and that the review was left standing — and pass it as the squash body: gh pr merge <n> --squash --admin --match-head-commit <sha> --body-file <reason.md>, with <sha> from the check's head line. Without --body-file the reason is lost, which defeats the point of recording it. That is the one sanctioned use of --admin in this skill.REQUEST_CHANGES naming a manual obligation (for example rule 12's cross-version test) — addressed to a person; a green check is not an answer to it./pr-review-queue composes that task — or, for a single PR, tell the user. A unit that already finished cannot be sent more input from here. A unit fixing an existing PR must not open a new one: its worktree is cut from main, so tell it to git fetch origin +pull/<n>/head:refs/remotes/origin/pr-<n> && git switch --detach origin/pr-<n>, commit there, and git push origin HEAD:<headRefName> — for a same-repository PR; a fork PR's push goes to the fork as Step 4 describes. The detached form also works when the branch is checked out in some other worktree. Tell it to stop after the push without requesting review; this skill runs the re-review.main too. Search first (gh pr list --search '<test name>'): an open PR that fixes it is its owner, and a second unit would only produce the duplicate fix Step 2 then has to untangle. CLAUDE.md rule 6 puts it in scope whoever caused it, and a fix or a quarantine is a code change beyond Step 4's narrow adaptations, so it goes to a unit whose task says to fix it or quarantine it (a named owner, an expiry issue, and #[ignore = "quarantined: <owner>, #<issue>"] on the test) and to say which. Name it in the report either way; "re-ran green" alone is not an outcome.Per PR: merged (with the squash SHA), or the bucket it is still in and the one thing it is waiting on. Then the totals, and whether anything left blocks a release. If tag-release called this skill, say plainly whether it should proceed.
© vfarcic, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/land-prs of vfarcic/dot-agent-deck.
Open the folder on GitHubat commit fc72b05
Land PRs next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Land PRs this skillvfarcic/dot-agent-deck | 109 | — | ~7k | Automated safety check: Pass | MIT | |
| Finishing a Development Branchobra/superpowers | 297k | 5 repos | ~1.9k | Automated safety check: Pass | MIT | |
| Code Design Rationale Investigatorcursor/plugins | 10k | 9 repos | ~2.6k | Automated safety check: Pass | None | |
| Contributor-First PR MergeHKUDS/OpenHarness | 16k | 1 repos | ~847 | Automated safety check: Pass | MIT | |
| Migrate Internal Package into GhostTryGhost/Ghost | 56k | — | ~3.8k | Automated safety check: Pass | MIT | |
| Create Pull Requestcline/cline | 70k | 1 repos | ~1.6k | Automated safety check: Pass | Apache-2.0 |
obra/superpowers
Walks the last step of a branch: confirm tests pass, detect the git environment, ask how to integrate, carry out your choice and clean up the worktree.
cursor/plugins
Digs into why code is shaped the way it is by checking git history, pull requests and connected tools in parallel, then reporting a cited read on the tradeoffs.
HKUDS/OpenHarness
Merges external GitHub pull requests while keeping the original author credited, and fixes conflicts after the merge instead of rewriting the contribution.
TryGhost/Ghost
Moves a package from another TryGhost repository into Ghost as an internal workspace package while keeping its Git history, with checkpoints for the steps that need an administrator.
cline/cline
Opens a GitHub pull request from your current branch with the gh CLI, after reviewing the commits and diff and gathering the details the PR needs.
yamadashy/repomix
Writes Conventional Commits whose bodies carry action lines recording the intent, decisions and constraints behind a change, not only what changed.
vfarcic/dot-agent-deck
Choose the shape of a unit you are about to dispatch in this repo — one agent (--single) or a team (--orchestration '<name') — from divisibility criteria instead of asking, and report the shape you…
vfarcic/dot-agent-deck
Check that a change to the user-facing docs covers both clients (the TUI and the desktop app) unless the feature exists in only one, and decide whether it needs a new or updated screenshot, then…
vfarcic/dot-agent-deck
Generate a feature request prompt for another dot-ai project.
vfarcic/dot-agent-deck
Take committed work from a branch to a verified pull request — push, open the PR, settle CI and the automated review, answer and resolve every finding, and hand off.
vfarcic/dot-agent-deck
Publish the docs site to GHCR with a main-<sha tag and bump site/helm/values.yaml so Argo CD picks it up — without cutting a SemVer release.
vfarcic/dot-agent-deck
Run, build, smoke-test, and screenshot the dot-agent-deck binary against an isolated sandbox.
Categories
Land every open PR the user has not excluded — resolve merge conflicts, get stale approvals re-cast by the agent reviewer, and squash-merge each PR once it is approved and green — then report…. Land PRs is an agent skill from vfarcic/dot-agent-deck. Land every open PR the user has not excluded — resolve merge conflicts, get stale approvals re-cast by the agent reviewer, and squash-merge each PR once it is approved and green — then report exactly what is left and why.
Land PRs fits situations like: asked to merge the open PRs; land what is ready; clear the PR backlog before a release; as the first step of make a release (tag-release calls it).
Run `npx skills add vfarcic/dot-agent-deck --skill land-prs -a claude-code`. Or copy the skill folder (.claude/skills/land-prs in vfarcic/dot-agent-deck) into .claude/skills/land-prs in your project. Claude Code loads it when a task matches its description.
Run `npx skills add vfarcic/dot-agent-deck --skill land-prs -a codex`. Or copy the skill folder (.claude/skills/land-prs in vfarcic/dot-agent-deck) into .agents/skills/land-prs in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add vfarcic/dot-agent-deck --skill land-prs -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/land-prs, .gemini/skills/land-prs, .github/skills/land-prs and .opencode/skills/land-prs in your project.
Going by SKILL.md and its folder, Land PRs needs the command-line tools its instructions call (git, gh, cargo and pnpm).
SKILL.md names 1 domain. In commands or code: github.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Land PRs is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 7k tokens (SKILL.md is roughly 28k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Land PRs: Finishing a Development Branch (obra/superpowers, 297k stars), Code Design Rationale Investigator (cursor/plugins, 10k stars), Contributor-First PR Merge (HKUDS/OpenHarness, 16k stars) and Migrate Internal Package into Ghost (TryGhost/Ghost, 56k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
vfarcic (a GitHub user) maintains it in vfarcic/dot-agent-deck, which has 109 GitHub stars. The repository holds 23 skills in this directory. The repository was last updated on October 9, 2026.
Source: vfarcic/dot-agent-deck on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.