claude-code-merge-queue serializes landings for parallel Claude Code agents

claude-code-merge-queue serializes landings for parallel Claude Code agents

A developer using the handle funador posted a Show HN for claude-code-merge-queue, a local, zero-cost merge queue built for setups where several Claude Code agents run in parallel worktrees, build, and test at the same time. The pitch is the same idea as GitHub's hosted Merge Queue, serialize landings, test before merge, keep history clean, but run entirely on one machine instead of in someone else's billed cloud. It installs with npm install --save-dev claude-code-merge-queue (or the pnpm, yarn or bun equivalents) and is set up with npx claude-code-merge-queue init. Everything is controlled from a single config file. Key fields include branchPrefix (default lane/, so agents work on lane/1, lane/2 and so on), worktreeSuffix, portBase (each lane gets portBase plus its number), integrationBranch (default main), an optional productionBranch for a two-stage promotion model, protectedBranches, regenerableFiles that should never block a rebase, symlinks and buildOutputDirs to keep out of preview copies, and checkCommand plus checksRequired, which together define the single gate a landing must pass. A malformed config, an empty branch name, a negative port, productionBranch equal to integrationBranch, fails immediately and lists every problem at once rather than surfacing them one at a time later. The init command wires in a pre-push git hook that makes going through the tool non-optional: a direct git push straight to the integration branch is rejected, with the exact command to run instead printed back, and the same hook runs checkCommand before allowing any landing through; leaving checkCommand unset means every push fails by default. init also writes or appends to CLAUDE.md so Claude Code knows to land its own work once checks are green without being asked, wires a WorktreeCreate hook into .claude/settings.json without touching anything else already there, creates or appends a Husky pre-push hook (or warns rather than silently writing into an untracked .git/hooks/pre-push if Husky is not present), adds package.json scripts for land, sync, promote, preview and preview:restore while skipping any the project already defines, and installs a self-contained preflight script that runs before land or sync so a stale branch fails with a real diagnosis instead of a bare command-not-found error. Every blocked push, whether to the integration branch, the production branch or anything listed in protectedBranches, has an escape hatch: setting the environment variable CLAUDE_CODE_MERGE_QUEUE_EMERGENCY_PUSH=1 before the git push bypasses the block with no prompt and no second factor, though the README frames this as a convention that stops mistakes, not a barrier against an agent that deliberately sets the variable itself. The README lists explicit limits: nothing here is reviewed by a human before landing, a passing checkCommand is the sole gate and a real test suite looks identical to an echo ok script to the tool by design; locks are crash-safe by PID liveness rather than a timeout, so killing a process mid-claim with kill -9 lets the next process notice the dead PID and reclaim the lock with no stale locks and nothing to tune; the FIFO queue lives in local temp storage and covers one machine only, so two machines landing at once just hit git's ordinary non-fast-forward rejection; it is explicitly not a security boundary, since shell access always means a developer or agent can run git push --no-verify or edit the config directly; a slow checkCommand is a real throughput ceiling, since the FIFO lock holds for its entire run, so a 3 to 4 minute test suite caps throughput well under 20 landings an hour; and rebase conflicts always abort cleanly rather than being guessed at, with git rebase --abort leaving the working tree clean and CLAUDE.md instructing the agent to resolve the conflict and re-run land. The project is released under the MIT license. At the time of the post it had 25 points and 8 comments on Hacker News about five hours after posting.

Key facts

  • claude-code-merge-queue is a local, zero-cost npm package that serializes git landings when multiple Claude Code agents build and test in parallel worktrees.
  • Setup is one command, npx claude-code-merge-queue init, which wires a pre-push hook that blocks direct pushes to the integration branch and requires a passing checkCommand before a landing goes through.
  • An emergency hatch, the environment variable CLAUDE_CODE_MERGE_QUEUE_EMERGENCY_PUSH=1, bypasses any blocked push with no prompt, but the author calls it a convention against mistakes, not a security control.
  • The README states plainly that no human reviews a landing before it merges, checkCommand passing is the only gate, and the tool covers one machine only, not a fleet.
  • A slow checkCommand caps throughput directly: a 3 to 4 minute test suite holds the FIFO lock long enough to limit landings to well under 20 per hour.

Why it matters

Running several Claude Code agents in parallel worktrees creates a specific class of problems: agents racing to push to the same branch, redundant heavy builds firing at once, and flaky tests caused by agents sharing resources like ports or databases. claude-code-merge-queue targets exactly that gap by serializing landings locally, offering the same discipline as GitHub's hosted Merge Queue (serialize, test before merge, keep history clean) without routing anything through billed cloud infrastructure.

Who it affects

Developers and teams running multiple Claude Code agents concurrently against the same repository, particularly setups that use git worktrees per agent lane. It is aimed at people who want GitHub-Merge-Queue-style discipline without paying for or depending on a hosted service, and who are comfortable running the coordination logic on a single local machine rather than across a fleet.

How to use it

Install with npm install --save-dev claude-code-merge-queue (or the pnpm, yarn or bun equivalent), then run npx claude-code-merge-queue init. Init auto-detects integrationBranch and checkCommand, writes or appends CLAUDE.md instructions telling Claude Code to land its own work once checks pass, adds a WorktreeCreate hook to .claude/settings.json without disturbing existing settings, sets up a Husky pre-push hook (or warns if Husky is missing rather than writing silently into .git/hooks/pre-push), adds package.json scripts (land, sync, promote, preview, preview:restore) skipping any already defined, and installs a preflight script that runs before land or sync. Configuration lives in one file covering branch naming, ports per lane, the integration and optional production branch, protected branches, files exempt from blocking a rebase, and the checkCommand that gates every landing. A blocked push can be forced through with the CLAUDE_CODE_MERGE_QUEUE_EMERGENCY_PUSH=1 environment variable, naming the specific branch rather than a generic override flag.

How solid is it

The project is MIT licensed, so it can be forked and modified freely. Its config loader fails loud on malformed setup, listing every problem the moment any command loads it rather than surfacing them one at a time. Locks are crash-safe by PID liveness rather than a timeout, so a killed process does not leave a stale lock behind. Rebase conflicts always abort cleanly, leaving the working tree untouched, rather than the tool attempting to guess a resolution. As a Show HN submission it had drawn 25 points and 8 comments roughly five hours after posting, a modest but active early reception typical of a niche developer-tooling launch.

Risks and caveats

The README is explicit about what the tool does not do. No human reviews a landing before it merges; a passing checkCommand is the only gate, and the tool cannot distinguish a real test suite from a script that just prints ok. It coordinates one machine only: the FIFO queue lives in local temp storage, so two separate machines pushing at once fall back to git's ordinary non-fast-forward rejection rather than any queue logic. It is explicitly not a security boundary, since anyone or anything with shell access can run git push --no-verify or edit the config directly. Throughput is capped by the check itself: since the lock holds for the full run of checkCommand, a 3 to 4 minute test suite limits the whole setup to well under 20 landings per hour. And the emergency-push environment variable that unblocks any protected branch is, by the author's own framing, a guardrail against accidental mistakes rather than protection against an agent that sets the variable on purpose.

“No human reviews any of this before it lands. checkCommand passing is the only gate, a real test suite and echo ok look identical to this tool. Want a human on every change? This is missing that step on purpose.”

— claude-code-merge-queue project README