Show HN:一个用于并行 Claude Code 代理的本地合并队列
Show HN: A local merge queue for parallel Claude Code agents

原始链接: https://github.com/funador/claude-code-merge-queue

**Claude Code Merge Queue** 是一款零成本的本地工具,旨在序列化并行智能体(agent)任务,从而避免推送冲突、冗余构建以及测试不稳定性。与 GitHub 仅限企业版使用的合并队列不同,该工具在本地机器上运行,消除了云端构建的成本和延迟。 该系统通过一个简单的 `claude-code-merge-queue.config.mjs` 文件来管理分支、构建产物和测试需求。主要功能包括: * **序列化合并:** 先进先出(FIFO)队列确保智能体按顺序提交代码,保持历史记录整洁。 * **工作树集成:** 通过钩子(Hooks)允许智能体创建隔离的“通道”用于测试和构建。 * **安全防护:** 通过预推送(pre-push)钩子防止直接向受保护分支推送代码,并提供用于手动覆盖的“紧急出口”。 * **崩溃安全锁:** 利用 PID 活跃度监测来管理锁,确保不会因僵尸进程导致队列阻塞。 * **自动化:** 与 `CLAUDE.md` 集成,使智能体能够自主解决冲突、运行测试并在通过后合并代码。 该工具专为提升效率而设计,而非针对对抗性安全。它是一种基于规范的强大工具,旨在简化自动化开发工作流,无需人工干预或消耗昂贵的 CI 时长。

开发者“funador”发布了一款本地合并队列工具,专为在资源受限的硬件上运行多个并行 Claude Code 代理的用户设计。 该创作者在 8GB 内存的 MacBook Air 上处理每天 90 次提交时遇到了困难,并发的构建和测试导致系统频繁崩溃,并产生了高昂的持续集成(CI)成本,因此开发了该方案。通过将提交按顺序排队并在本地进行测试,该工具在无需持续依赖云端 CI 反馈的情况下,有效防止了系统过载。 在讨论中,有评论指出,虽然本地队列是解决资源限制的巧妙方法,但他们更倾向于使用 CI 进行独占锁定,因为这样可以避免占用开发者机器资源,且扩展性更好。不过,对于使用轻量级硬件的用户来说,这款本地合并队列提供了一种应对高频 AI 驱动开发的实用替代方案。
相关文章

原文

Claude Code Merge Queue — the local, zero-cost merge queue for parallel Claude Code agents

npm version npm downloads CI License: MIT TypeScript Node Runtime deps

The local, zero-cost merge queue for parallel Claude Code agents. Several agents land, build, and test at the same time — this serializes it so push races, redundant heavy builds, and shared-resource test flakiness can't happen.

npm install --save-dev claude-code-merge-queue   # or: pnpm add -D / yarn add -D / bun add -d
npx claude-code-merge-queue init

Terminal demo: npm install --save-dev claude-code-merge-queue, then npx claude-code-merge-queue init — writes the config, CLAUDE.md, the WorktreeCreate hook, and land/sync/promote/preview scripts

Everything lives in one file — see examples/claude-code-merge-queue.config.mjs for every field with comments. The short version:

export default {
  branchPrefix: "lane/",               // lane/1, lane/2, ...
  worktreeSuffix: "-lane-",            // ../your-repo-lane-1
  portBase: 3000,                      // lane n gets portBase + n
  integrationBranch: "main",           // where agents land — see below
  productionBranch: null,              // set this for a two-stage model — see below
  protectedBranches: [],               // extra branches beyond the two above; most repos need none
  regenerableFiles: [],                // files a build tool rewrites — never block a rebase on these
  symlinks: [".env", ".env.local", "node_modules"],
  buildOutputDirs: ["dist", "build", ".next"], // preview never copies these onto your checkout
  checkCommand: "npm run check",       // what actually gates a landing — see below
  checksRequired: true,                // false = deliberately run with none; see below
};

A malformed config (empty branch names, a negative port, productionBranch equal to integrationBranch, ...) fails loud with every problem listed, the moment any command loads it — not a mysterious failure three steps later.

🆚 vs. GitHub's Merge Queue

GitHub Merge Queue Claude Code Merge Queue
Private repo Enterprise Cloud only Any plan, any repo
Cost per landing GitHub Actions minutes, every queue attempt $0 — runs on your own machine
Requires A pull request Nothing — direct rebase + push

Same idea — serialize landings, test before merge, keep history clean — run locally instead of in someone else's billed cloud.

Command What it does
claude-code-merge-queue hook worktree-create A Claude Code WorktreeCreate hook. Plugs Claude Code Merge Queue's numbered lanes into Claude's native worktree creation.
claude-code-merge-queue build-lock -- <cmd> Runs <cmd> — your build — serialized across every lane, machine-wide.
claude-code-merge-queue land Rebases and pushes your lane onto the integration branch through a FIFO queue, so two lanes are never mid-push at once. Agents run this themselves.
claude-code-merge-queue sync Fast-forwards your main checkout so a dev server actually sees what just landed — and re-installs dependencies if the lockfile changed.
claude-code-merge-queue promote Ships the integration branch to production. Human-only — never in an agent's instructions, never automated.
claude-code-merge-queue preview Instantly mirrors a lane's live working tree — uncommitted changes included — onto the main checkout, so you can look at it without a build.
claude-code-merge-queue port Prints a lane's dev-server port, derived from its own directory name.
claude-code-merge-queue prune Removes already-landed sibling lane worktrees on demand.

A pre-push hook makes land non-optional: a direct git push straight to the integration branch is rejected, with the actual command to run instead, and the same hook runs checkCommand before allowing a landing through — no checkCommand configured means every push fails by default. There's a way out for every block (see 🚨 The emergency hatch), but it takes naming the specific branch, not a generic flag.

  • claude-code-merge-queue.config.mjsintegrationBranch and checkCommand auto-detected.
  • CLAUDE.md (or appends to yours) — tells Claude Code to land its own work once green, without being asked.
  • .claude/settings.json — the WorktreeCreate hook wired in, without touching anything else already there.
  • .husky/pre-push — created or appended to, if you already have Husky. If you don't, init tells you rather than silently writing to the untracked .git/hooks/pre-push.
  • package.json scriptsland, sync, promote, preview, preview:restore, skipping any you've already defined yourself.
  • claude-code-merge-queue-preflight.mjs — a self-contained safety net that runs before land/sync, so a stale branch fails with a real diagnosis instead of a bare command not found.

Every blocked push — the integration branch, productionBranch, anything in protectedBranches — has a real way through it. One env var, no prompts, no second factor to remember:

CLAUDE_CODE_MERGE_QUEUE_EMERGENCY_PUSH=1 git push origin HEAD:main

This is a convention, not a hard guarantee: it stops mistakes and stray pushes, not an adversarial agent that sets the var itself.

  • 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.
  • Locks are crash-safe by PID liveness, not a timeout. kill -9 anything mid-claim and the next process notices the PID is dead and reclaims it — no stale locks, no timeout to tune.
  • One machine, not a fleet. The FIFO queue lives in local temp storage — two machines landing at once just get git's ordinary non-fast-forward rejection.
  • Not a security boundary. Every guardrail here stops mistakes and convention drift, not an adversarial agent — shell access always means git push --no-verify or editing the config on purpose.
  • A slow checkCommand is a real throughput ceiling. The FIFO lock holds for its entire duration — a 3–4 minute suite caps you well under 20 landings/hour.
  • Rebase conflicts abort, they never guess. git rebase --abort on any conflict, working tree left clean — CLAUDE.md tells the agent to resolve it and re-run land.

MIT. Fork it, rename it, argue with the config shape — that's the point.

联系我们 contact @ memedata.com