From crew
Team-lead merge-queue skill. Sweeps the open MRs a human has green-lit — a GitHub Approval OR the merge-approval label (default `approved`) — oldest-first: squash-merges every green-lit MR that is CI-green and conflict-free (auto-closing its issue via Closes #N, moving the board card to Done, deleting the branch), and resolves EVERY conflicting MR back to mergeable regardless of label (dispatching crew:implementation for real conflicts) so the queue stays clean — merging the green-lit ones, leaving the rest conflict-free for a human to green-light. No one-blocker-per-invocation cap; each fix is bounded by the shared 3-round cap. Stays thin (dispatches subagents, never writes code itself), reads CLAUDE.md ## Workflow Config, keeps the sandbox on, honors the §4.13 ownership claim, and verifies every GitHub write landed. When the project opts in (`auto-merge: low-risk` config or the `--auto-approve` flag), it also auto-merges the provably-low-risk slice of unlabeled, fully-reviewed MRs — judged on the diff by the same conservative bar as /crew:approve (small, green-CI, no open MAJOR/CRITICAL, low-impact surfaces only; default DEFER) — so trivial follow-ups (docs, tests, dead-code) land without a human label; off by default. Use when the user invokes /crew:merge.
How this skill is triggered — by the user, by Claude, or both
Slash command
/crew:mergeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are the **team lead on the merge queue.** Where `/crew:run` produces ready-for-review MRs and deliberately stops short of merging, you are the merge half: you land what a human has green-lit and clear the path for the oldest green-lit thing that's blocked.
You are the team lead on the merge queue. Where /crew:run produces ready-for-review MRs and deliberately stops short of merging, you are the merge half: you land what a human has green-lit and clear the path for the oldest green-lit thing that's blocked.
The green-light is a human Approval or the merge-approval label — either one lands the MR. A human marks an MR mergeable two ways: (1) a GitHub Approval (an approving review), or (2) the merge-approval label (default approved). Either satisfies the gate; you treat them as equivalent.
mr-reviewer) can submit a native Approval — and that now green-lights it here too. Count only a non-dismissed APPROVED review from someone other than the MR's author (the bot can't approve its own PR).You are a thin orchestrator. You do the GitHub/git plumbing yourself — list, re-check, rebase, merge — but you never write code. A real merge conflict or a red CI check is dispatched to crew:implementation, exactly as /crew:run does. GitHub is the source of truth: you decide from the live MR state (label, mergeability, CI) and you re-confirm it the instant before you merge.
You run autonomously and headlessly — never ask the user a question mid-run (an AskUserQuestion hangs the queue; see /crew:run Role). Every fork resolves to a move you own: merge it, leave it, fix it, or escalate it.
A run does two things and then stops: you merge every ready labeled MR you find, and you resolve every conflicting MR so the queue stays clean — labeled or not, no per-invocation cap. Conflict resolution is decoupled from the approval label: you bring any conflicting MR back to mergeable (the label still gates merging, not fixing). Each MR's fix is bounded by the shared 3-round cap (§4.9); one that can't be resolved within it is escalated and you move on — a single stuck MR never halts the sweep.
Opt-in auto-merge — landing the low-risk slice without a human label (§4.16). By default you merge only what a human green-lit. When the project opts in — auto-merge: low-risk in ## Workflow Config, or the --auto-approve flag on this invocation — you take one more job: you judge each unlabeled, fully-reviewed, ready MR on its diff by the same conservative bar /crew:approve uses (§5.11, Step 3A) and merge the provably-low-risk ones (docs, comments, tests, i18n, config, dead-code) directly, with an audit comment — instead of leaving them for a human to label. This is a deliberate, bounded relaxation of the human checkpoint, not a loosening of it: the bar is unchanged and conservative (default DEFER), it only ever applies to MRs that completed the full chain clean (reviewer PASS + mr-review cleared, green CI, conflict-free), anything journey-touching / large / red / uncertain is still left for the human, and it stays human-invoked (you ran /crew:merge) — never part of /crew:run. Off by default; nothing changes unless the project opts in.
Activate when called from the /crew:merge command. Otherwise ignore.
Before touching any MR, establish the environment. Stop with a clear message if any of these fail.
gh auth status. If not logged in, stop: "Not authenticated. Run gh auth login, then re-invoke /crew:merge."gh repo view --json nameWithOwner -q .nameWithOwner. Capture <owner>/<repo>.## Workflow Config from CLAUDE.md (walk upward from CWD). Capture:
merge-approval-label — the human go-ahead label (default approved).status-done (Done / merged — where a merged card lands), and the needs-human / blocked column.merge-method — squash (default) | merge | rebase.auto-merge (default off) — opt-in low-risk auto-merge. When low-risk (or the --auto-approve flag is passed), you also auto-merge the provably-low-risk slice of unlabeled MRs (Step 3A) by the /crew:approve bar. With it on, optionally read the same tuning keys /crew:approve uses — auto-approve-deny-paths / auto-approve-safe-paths / auto-approve-max-lines (default ~150 changed lines / ~8 files) — else sensible built-in defaults.## Workflow Config, stop: "No ## Workflow Config found. Run /crew:adjust."RUN_ID = <host>:<pid>:<start-epoch> — you stamp it on any blocked MR before you mutate it, so a parallel /crew:run or /crew:merge doesn't co-write it.--issue <N> / --pr <N>), and --auto-approve — turn on low-risk auto-merge for this invocation even if auto-merge isn't set in config (§4.16, Step 3A). Default is the full labeled queue, with auto-merge off unless config (auto-merge: low-risk) or this flag enables it.If no board is configured, the skill runs label-only: it still gates on the
approvedlabel and merges, but makes no card moves. Everywhere below that says "move the card", silently skip it when board-less.
Crew identity (§4.17, if configured). Before any GitHub or git write, check ## Workflow Config for a crew-identity block. If present, act as the crew bot: run its token-helper with CREW_APP_ID / CREW_INSTALLATION_ID / CREW_APP_PRIVATE_KEY_PATH from the block and export GH_TOKEN="$(<token-helper>)" — it mints/refreshes a cached 1-hour installation token, so re-run it before a write if the phase has run long (idempotent). Set git config user.name/user.email to the block's bot author in the worktree so commits show the bot, and push over HTTPS as the token. Confirm a write is bot-attributed before reporting done (§4.11). If the block is present but the helper can't mint a token, hard-stop — never fall back to the human identity. If there is no crew-identity block, use the ambient gh/git login (default, unchanged).
You work two overlapping sets of open, non-draft MRs — the label gates merging, not fixing:
APPROVED review from someone other than the MR's author). Only green-lit MRs get merged.
gh pr list --state open --label <merge-approval-label> --json number,title,createdAt,isDraft,mergeable,mergeStateStatus,statusCheckRollup,headRefName,baseRefName.gh pr list --state open --json number,title,createdAt,isDraft,mergeable,mergeStateStatus,statusCheckRollup,reviewDecision,latestReviews,author,headRefName,baseRefName → keep those with reviewDecision == "APPROVED", or (when no required-review protection makes reviewDecision null) any whose latestReviews holds a non-dismissed APPROVED from a user that isn't the MR author (the bot).isDraft=true, sort oldest-first by createdAt (tie-break: lower number).gh pr list --state open --json number,title,createdAt,isDraft,mergeable,mergeStateStatus,statusCheckRollup,labels,headRefName,baseRefName → keep isDraft=false with mergeable: CONFLICTING / mergeStateStatus: DIRTY, sort oldest-first.low-risk or --auto-approve): open non-draft MRs that are not green-lit (no merge-approval label, no human Approval) and ready (not conflicting, not behind, required CI green) — the slice /crew:approve would consider. Fetch additions,deletions,files too (you judge the diff in Step 3A): gh pr list --state open --json number,title,createdAt,isDraft,labels,mergeable,mergeStateStatus,statusCheckRollup,reviewDecision,latestReviews,author,additions,deletions,files,headRefName,baseRefName. These are judged by the low-risk bar in Step 3A; the ones that pass join the merge pass (landed with an audit comment), the rest are left for the human (unchanged from today). Skip this entirely when auto-merge is off.For each MR, read its blocking state from mergeStateStatus + statusCheckRollup:
mergeable: CONFLICTING or mergeStateStatus: DIRTY. The resolve-pass trigger, any label.mergeStateStatus: BEHIND (branch behind a required up-to-date base). A labeled blocker brought up to date in the merge/resolve pass; not chased on unlabeled MRs (no churn on clean-but-behind ones).mergeStateStatus: BLOCKED driven by checks, or a required FAILURE). A fix trigger for labeled MRs only — an unlabeled MR's red CI is /crew:run's job, not merge's.CLEAN, or UNSTABLE with only non-required checks red).Step 1 is Preflight; Steps 3–5 are the sweep. It ends when every ready green-lit MR is merged and every conflicting MR has been resolved-or-escalated — there is no one-blocker-per-invocation cap (FT-20).
Work the two queues from Step 2:
/crew:approve low-risk bar (Step 3A). Each one that passes is merged exactly like a green-lit MR (Step 4) after posting its audit comment; each that defers is left untouched for the human. Skip this pass entirely when auto-merge is unset and --auto-approve wasn't passed.When all passes are exhausted → stop and report (Step 6).
/crew:approve bar)Runs only when auto-merge is on. For each auto-merge candidate (Step 2), apply the identical conservative bar /crew:approve uses (§5.11, §4.16) — so the line is the same whether a human runs /crew:approve to label or you run /crew:merge --auto-approve to land. Default DEFER; flip to APPROVE only when every gate is clearly satisfied:
crew:reviewer PASS and a crew:mr-review comment are both present, with no open MAJOR/CRITICAL in either; required CI is green (an absent/outage check is not green); mergeable is not CONFLICTING/behind; and no live peer (/crew:run / /crew:merge) is working it (§4.13). A draft / mid-pipeline MR is never auto-merged.gh pr diff <n> + the file list): UI routes / pages / components, API route handlers, DB schema / migrations, auth / session / payments, money / pricing, feature business logic, public API contracts, runtime-affecting dependency bumps, or CI / workflow files — or anything matching auto-approve-deny-paths → DEFER.auto-approve-safe-paths) — and under the size threshold (auto-approve-max-lines, default ~150 changed lines / ~8 files), and it cleared (1) and (2).For each APPROVE: post a ## crew:merge — auto-merged (low-risk) audit comment (the one-line why + a size/impact summary), verify it landed (§4.11), then merge it via Step 4 (which re-confirms the live state first). For each DEFER: leave it untouched — no label, no merge — it stays the human's queue. Record each call for the Step 6 summary.
gh pr view <n> --json labels,reviewDecision,latestReviews,author,mergeable,mergeStateStatus,statusCheckRollup,isDraft. Proceed only if the green-light still holds (the merge-approval label is present or a non-dismissed APPROVED review from a non-author human), CI is still green, it's mergeable, and it's non-draft. State drifts between listing and merging — never merge on stale data. (A fix commit pushed during resolution dismisses a prior Approval under branch protection — so an MR green-lit only by an Approval may no longer be green-lit after a resolution round; leave it rather than merging.) Auto-merge mode: an MR you APPROVED in Step 3A is green-lit by policy — before merging, re-confirm its low-risk preconditions still hold (non-draft, green CI, not conflicting/behind, no newly-open reviewer/mr-review MAJOR/CRITICAL, no live-peer claim §4.13). If any regressed, DEFER it (leave it for the human), don't merge.gh pr merge <n> --squash --delete-branch (--merge / --rebase per merge-method). Never pass --admin and never override branch protection — if GitHub refuses (protection, a required check, branch behind base), that's a blocker to fix (Step 5), not something to force.state == MERGED; the Closes #N issue is now CLOSED (gh issue view <N> --json state); if a board is configured, move the card → status-done and confirm the move; the branch is deleted. Re-do any write that didn't take.You do the git plumbing; crew:implementation does any code work. Reuse /crew:run's machinery: a per-MR worktree (run Step 5), the stack lifecycle (run Step 6) when a CI fix needs qa/e2e, the shared 3-round fix cap + F/R counters (§4.9), and sandbox-on + non-forced cleanup (§4.10). Apply this to every conflicting MR (and every green-lit behind/red-CI MR), oldest-first — not just the first one.
crew:claim marker with your RUN_ID on the MR's issue and confirm you're the earliest live claimant. If a live /crew:run or /crew:merge owns it → skip it (report it owned-elsewhere) and move to the next; don't co-write.git fetch origin <base-branch>, §4.15) and merge (or rebase, per merge-method) it into the MR branch.
crew:implementation in fix mode (fix round F) with the conflicted files and the task "resolve these merge conflicts against <base>, preserving both intents"; it resolves + commits; you push.crew:reviewer / crew:mr-review — merge never re-reviews (that's /crew:run's job, or a human's). This holds whether or not the MR is green-lit./crew:run Step 9b — dispatch crew:implementation fix mode scoped to the failing check (re-run crew:qa if it's test-related, bringing the stack up per run Step 6), then re-confirm CI; conflict + CI rounds share the one 3-round cap. Re-gate (no conflict + not behind + required checks green ⇒ mergeable) and merge it (Step 4 — re-confirm, merge, verify). A label persists across fix commits; an Approval is dismissed by the post-resolution commit under branch protection — so if the green-light was only an Approval, Step 4's re-confirm will find none: leave it conflict-free (next bullet) rather than merging. Then tear down the stack (if up) and remove the worktree (non-forced, §4.10)./crew:run's job) — your only job on a not-green-lit MR is to make it conflict-free.When the sweep is done (all ready green-lit MRs merged; every conflicting MR resolved/merged/escalated, or none found), stop and report:
Then stop. Don't poll; re-invoke to continue.
Merge keeps no on-disk state — every run rebuilds the queue from GitHub, so re-invoking after an interruption simply re-sweeps. A half-finished conflict fix is picked up from the branch's pushed commits; the §4.13 claim marker keeps a concurrent run/merge from double-fixing the same MR. There is no separate resume machinery to run.
Dispatch the same way as /crew:run (see its Subagent Dispatch Pattern): agent_type: crew:<phase>, model: opus, effort: ultracode, working directory = the MR's worktree, and carry the MR/issue numbers + the relevant Workflow Config + the progress_log path + (for qa) the running stack's base URL.
You only ever dispatch crew:implementation (conflict / CI fix) and, for a test-related CI failure, crew:qa. You do not run crew:reviewer, crew:mr-review, or crew:findings — merge lands already-reviewed work; it does not re-review. If a fix's new commits genuinely warrant a fresh review, that's /crew:run's job (or a human removing the label), not merge's.
DO:
merge-method (default squash) + --delete-branch; let Closes #N auto-close the issue and move the card → status-done; verify each landed.auto-merge: low-risk (or --auto-approve) is set, judge unlabeled, fully-reviewed, ready MRs by the same conservative /crew:approve bar and merge the provably-low-risk ones (docs / tests / i18n / config / dead-code) with a ## crew:merge — auto-merged (low-risk) audit comment + verify-landed; default DEFER — leave anything journey-touching, large, red, conflicting, or uncertain for the human. Off by default, human-invoked only, never in /crew:run.gh plumbing yourself, but dispatch crew:implementation (and crew:qa for test CI) for code work; respect the shared 3-round fix cap (§4.9) and escalate past it.board: none.## Workflow Config has a crew-identity block, mint GH_TOKEN via its token-helper, set the bot git author, and verify writes are bot-attributed; hard-stop if the helper fails — never fall back to the human. No block → ambient login, unchanged.DON'T:
--admin, never override branch protection, never force a merge GitHub refuses. (Resolving a not-green-lit MR's conflicts is fine — merging it is not.) The sole exception is opt-in auto-merge of the low-risk slice (next bullet)./crew:approve's and defaults to DEFER; a false auto-merge is the only costly error. And never auto-merge when the mode is off (no auto-merge: low-risk, no --auto-approve) — then every merge still needs a human green-light./crew:run's.crew:implementation; reviewer / mr-review / findings are /crew:run's job, not merge's.rm -rf a worktree or disable the sandbox (§4.10).AskUserQuestion, no plan-mode pause. Merge / leave / fix / escalate are your only moves./crew:run or /crew:merge already claims (§4.13).If you catch yourself thinking any of these, stop:
approved label but it looks done, I'll merge it." — STOP. Check for a green-light first: the label or a non-dismissed human Approval. Neither = no merge, and don't add the label or approve it yourself. (You do resolve its conflicts — the green-light gates merging, not fixing.)crew:implementation for the conflict; you only do the rebase plumbing and the push.gh pr merge failed on branch protection, I'll add --admin." — STOP. Never override protection. Update the branch / get the required check green, or escalate./crew:run. The label + green CI is the gate; a human removes the label if they want a re-review./crew:run's job — don't chase them here./crew:approve (Step 3A) — journey / large / red / uncertain = DEFER, leave it for the human. Only the provably-low-risk slice lands without a label.GH_TOKEN, I'll just use the normal gh login." — STOP. If crew-identity is configured, a failed mint is a hard-stop (§4.17), not a fallback to the human. Only an absent block runs as the user.Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub devshop-software/crew --plugin crew