开源项目 GitHub Trending 2026-08-07T12:01 正文 ok 2515 words

SwarmForge:基于 tmux 的多 AI Agent 协作编排平台

英文标题:🔥 unclebob/swarm-forge

SwarmForge 是一个在本地运行、基于 tmux 的 AI Agent 协作系统,通过 Git worktree、角色提示词、消息交接和共享规则,让多个 Agent 能在同一项目中协同开发。项目提供 `two-pack`、`four-pack` 和 `six-pack` 三种可运行工作流,分别覆盖快速双 Agent 开发、紧凑型规格驱动开发,以及将规格、编码、重构、架构、加固和 QA 分离的完整流程。系统支持 `claude`、`codex`、`copilot`、`grok` 等后端,并通过本地脚本和守护进程协调任务交接,而非让 Agent 直接发送 tmux 消息。对开发者而言,它提供了一种轻量、自托管且可观察的多 Agent 工程化协作方案,但需要在本地准备 `zsh`、Git、tmux、Babashka 等运行环境。
打开原文相关 3 · 机会 4
media107.7 KB

中文

不要在 bankrbot 的 SWARM 代币上花任何钱。

这是一个纪律严明、基于 tmux 的 Agent 编排平台,可将 AI Agent 群体转化为可靠、专业的软件工程师。

该 main 分支用于文档说明:它解释系统,并承载共享的运行脚本和默认宪法条款。可运行的工作流分支则包含面向项目的配置、角色提示词和本地宪法条款,用于定义具体工作流。

SwarmForge 是一个 Agent 协调系统,可促进在不同 Git worktree 中工作的 Agent 之间通信。

它为角色专属提示词、worktree 分配、tmux 会话和消息传递提供共享结构,使多个 Agent 能够在同一项目上协作而不会互相干扰。

可运行的 SwarmForge 配置位于专用分支中。每个分支均包含某一工作流的 swarmforge/swarmforge.conf、本地宪法条款和角色提示词。启动时,如果共享运行脚本和共享宪法条款尚不存在,其 ./swarm 包装器会从 main 复制它们,随后启动该分支的本地配置。

two-pack 是快速后端工作流。对于能够受益于快速编码、又不需要承担 Gherkin 和验收测试开销的小型任务,可使用该工作流;同时它仍保留后端重构与加固环节。

  • coder 通过 TDD 和单元测试实现所需行为。
  • cleaner 批量处理 coder 的交接任务,并执行清理、CRAP 和 DRY 审查、架构审查、封装与关注点分离修复,以及语言变异加固。

常规流程为 coder -> cleaner -> coder。当你希望拥有紧凑的实现/优化循环,而不需要规格、QA、属性测试或验收测试角色时,可使用该分支。

four-pack 是紧凑型规格工作流。适用于需要 Gherkin 规格和一定架构考量、但不希望将每个质量关卡拆分给独立 Agent 的中等规模项目:

  • specifier 将用户意图转化为精确的 Gherkin 验收规格,并在交接前请求批准。
  • coder 通过 TDD、单元测试和生成的验收测试,实现已获批准的行为切片。
  • refactorer 执行保持行为不变的清理、覆盖率改进、CRAP 和 DRY 审查、变异点扫描及属性测试支持。
  • architect 负责高层结构、依赖方向、变异加固、DRY 审查、软 Gherkin 变异,以及最终完成通知。

常规流程为 specifier -> coder -> refactorer -> architect -> specifier。当你希望进行纪律严明的开发,但不想将清理、架构、加固和 QA 拆分为独立 Agent 时,可使用该分支。

six-pack 是完整工作流。适用于需要完整规格、前期 QA、后端验证以及重大架构考量的大型项目。它将每项主要质量关卡分配给独立角色:

  • specifier 将用户意图转化为已接受的 Gherkin 规格和端到端 QA 流程。
  • coder 通过 TDD、单元测试和生成的验收测试,实现已获批准的行为切片。
  • cleaner 执行局部的保持行为不变清理、覆盖率改进、CRAP 和 DRY 审查,以及变异点扫描。
  • architect 审查模块结构、边界、依赖方向和属性测试覆盖率。
  • hardender 执行变异加固、语言变异、CRAP 和 DRY 验证,以及软 Gherkin 变异。
  • QA 将 specifier 的 QA 流程转换为可执行脚本,执行最终用户界面验证,检查交接一致性,并发送完成通知。

常规流程为 specifier -> coder -> cleaner -> architect -> hardender -> QA -> 完成。当你希望每项审查和验证事项均由独立 Agent 负责时,可使用该分支。

SwarmForge 在本地运行。启动可运行分支前,请确保目标机器具备:

  • zsh
  • git
  • tmux
  • Babashka(bb)
  • 至少一个已配置的 Agent 后端,例如 codex、claude、copilot 或 grok

在希望使用 SwarmForge 的目录中,选择一个可运行分支,并在不创建 Git 远程仓库的情况下拉取其内容:

BRANCH=four-pack
curl -L "https://github.com/unclebob/swarm-forge/archive/refs/heads/${BRANCH}.tar.gz" | tar -xz --strip-components=1

使用 BRANCH=two-pack 可启用快速双 Agent 工作流,使用 BRANCH=four-pack 可启用紧凑型规格工作流,使用 BRANCH=six-pack 可启用完整六 Agent 工作流。不要在此命令中使用 main;main 用于文档说明并存放共享运行脚本,而可运行分支则提供面向项目的配置和提示词。

复制可运行分支后,从目标项目启动 swarm:

./swarm 包装器让可运行分支保持精简。首次使用时,如果 swarmforge/scripts/ 缺失,它会下载 main 分支归档,从 swarmforge/scripts/ 复制共享运行脚本,从 swarmforge/constitution/articles/ 暂存共享宪法条款,然后启动 swarmforge/scripts/swarmforge.sh。后续运行会复用已有的本地脚本目录,而不会覆盖它。

窗口应会自动打开。

要停止 swarm,请关闭 swarmforge/swarmforge.conf 中列出的第一个窗口。这个清理窗口会关闭 tmux 会话及其余被跟踪的窗口。

当 swarm 处于活动状态时,SwarmForge 会尝试阻止主机进入睡眠状态。在 macOS 上,它使用 caffeinate;在 Linux 上,如果可用则使用 systemd-inhibit。显示器锁定或手动休眠仍可能因操作系统而中断 Agent。请在运行 ./swarm 前设置 SWARMFORGE_PREVENT_SLEEP=0,以禁用此行为。

SwarmForge 是一个轻量级、基于 tmux 的编排层,其功能包括:

  • 从项目本地 swarmforge/swarmforge.conf 启动由配置驱动的 swarm

  • 为每个已配置角色创建一个 tmux 会话;当所选后端支持时,为每个角色打开一个终端界面

  • 从项目本地 swarmforge/roles/<role>.prompt 文件和分层的 swarmforge/constitution.prompt 读取行为定义

  • 支持按角色使用 claude、codex、copilot 或 grok 等后端

  • 将共享 swarmforge/scripts/ 目录加入每个 Agent 的 PATH,其中包括用于活跃 swarm 通信的交接辅助工具

  • 为分配了专属 worktree 名称的角色,在 .worktrees/ 下创建 Git worktree

  • 必要时在新的工作目录中初始化 Git 仓库

  • 将所有 swarm 状态保存在工作目录内的 .swarmforge/ 中

  • 配置驱动拓扑 —— swarm 的形态来自 swarmforge/swarmforge.conf,而非硬编码的 Shell 变量。

  • 项目本地角色 —— 每个角色均由被编排工作树中的 swarmforge/roles/<role>.prompt 定义。

  • 分层宪法 —— swarmforge/constitution.prompt 指示 Agent 读取 swarmforge/constitution/articles/ 下的条款文件。

  • 按角色选择后端 —— 角色可启动 claude、codex、copilot 或 grok。

  • 可观测的 swarm —— 每个角色打开一个终端窗口,并可实时观察会话。

  • 自托管且轻量 —— 以最少的机制在本地 tmux 和终端中运行。

每个可运行分支均包含一个 swarmforge/ 目录,其一般布局如下:

swarmforge/
  swarmforge.conf
  constitution.prompt
  constitution/
    articles/
      project.prompt
      local-engineering.prompt
      local-workflow.prompt
      ...
  roles/
    <role>.prompt
    ...

constitution.prompt 是入口文件。可运行分支通常使用它来指示 Agent 读取 swarmforge/constitution/articles/ 中的每个文件。

共享默认条款位于 main 分支下:

swarmforge/constitution/articles/
  engineering.prompt
  handoffs.prompt
  workflow.prompt

启动时,SwarmForge 会在创建角色 worktree 之前,将缺失的共享条款安装到可运行分支的 swarmforge/constitution/articles/ 目录中。在脚本同步期间,它还会将缺失的共享条款安装到每个角色 worktree 中。已存在的本地文件会被跳过,因此可运行分支可以通过提交同名条款文件来覆盖共享条款。

特定 pack 的补充内容和例外规则应使用明确的本地文件名,而不是修改共享条款。当前约定为:

  • project.prompt 用于描述工作流的项目形态和本地拓扑。
  • local-engineering.prompt 用于描述工作流专属的工程规则。
  • local-workflow.prompt 用于描述工作流专属的流程规则。

local-*.prompt 命名约定的含义是:“为此可运行分支补充或专门化共享默认条款”。当共享条款仍然有效,而分支仅需要额外要求、例外或更狭窄的指令时,应使用这一约定。不要将 local-*.prompt 用于完整替换;如果分支有意覆盖共享条款,请改用共享文件名。

例如,main 可以提供共享的 workflow.prompt,而 six-pack 可以添加 local-workflow.prompt 来定义 QA 专属的交接行为。如果某个分支需要完全替换共享工作流条款,它可以提交自己的 workflow.prompt;启动时会将该本地文件视为覆盖版本,不会再复制共享文件覆盖它。

swarmforge/swarmforge.conf 中的每个角色都会映射到对应的 swarmforge/roles/<role>.prompt 文件。

在可运行分支中:

  1. SwarmForge 读取 swarmforge/swarmforge.conf。
  2. 当共享辅助脚本、终端适配器和共享宪法条款尚不存在时,根目录的 ./swarm 包装器会从 main 分支复制它们。
  3. 启动过程会将缺失的共享宪法条款安装至 swarmforge/constitution/articles/,跳过任何已存在的本地条款文件。
  4. 启动过程验证已配置的角色提示词、辅助脚本和终端适配器。
  5. 如果目标目录尚不是 Git 仓库,启动过程会初始化一个仓库并创建首次提交。
  6. 启动过程会在 .worktrees/ 下为每个已配置角色创建一个 Git worktree,除非该角色被分配到 master 或 none。
  7. 启动过程会将 swarmforge/scripts/ 及缺失的共享宪法条款同步到每个角色 worktree,并将这个本地脚本目录加入每个 Agent 的 PATH,使 Agent 使用本地交接辅助工具,而无需回溯到 master 检出目录。
  8. SwarmForge 创建 tmux 会话、打开终端窗口,并在其指定 worktree 中启动每个已配置后端。
  9. 当存在可用的操作系统专属睡眠抑制器时,启动过程会启动它;清理时则会随 swarm 一同停止它。
  10. 角色通过守护进程投递的交接文件进行通信。Agent 使用 swarm_handoff.sh 创建经验证的草稿,使用 ready_for_next.sh 接受工作,并使用 done_with_current.sh 完成工作。

启动过程会将共享辅助脚本同步到每个角色 worktree 下的 swarmforge/scripts/,并将该本地目录加入 Agent 的 PATH。Agent 不会直接发送 tmux 消息。启动器会启动 handoffd.bb,该程序负责访问 tmux socket、监视每个 Agent 的发件箱、将经验证的交接文件复制到收件人的收件箱,并且只发送通用唤醒通知。

Agent 通过三个辅助脚本与交接任务交互:

  • swarm_handoff.sh <draft-file> 用于验证并将出站交接任务加入队列。
  • ready_for_next.sh 使用角色已配置的接收模式接受工作。
  • done_with_current.sh 使用角色已配置的接收模式完成当前任务或批次。

出站草稿使用两种消息类型之一。Git 交接会将收件人指向一个已提交状态。提交缩写必须恰好为 10 个十六进制字符;swarm_handoff.sh 会验证其能解析为单个提交,并在将交接任务入队前对其进行规范化。

type: git_handoff
to: <role>[,<role>...]
priority: NN
task: <short-stable-task-name>
commit: <10-character-commit-abbrev>

备注是一条简短的自由格式消息:

type: note
to: <role>[,<role>...]
priority: NN
message: <one line, max 80 chars>

辅助工具会生成实际投递的负载。Agent 不会编写冗长的交接正文、分支名称、队列文件名或 tmux 命令。

收件 Agent 在收到通知后或重启后运行 ready_for_next.sh。它会分派至为该角色配置的任务或批次辅助程序。如果其输出 NO_TASK,Agent 将停止等待工作。如果其输出 TASK: <path>,Agent 会将打印出的 TASK_NAME 和 PAYLOAD 视为任务。如果其输出 BATCH: <path>,Agent 会按辅助工具投递的顺序处理打印出的 BATCH_ITEM 条目。如果 Agent 已在工作时收到唤醒通知,可以忽略该通知;done_with_current.sh 会在完成当前工作后检查下一个任务或批次。

持久化交接文件和生命周期头部取代了旧的日志簿与重发队列。运行时交接状态位于每个 worktree 的 .swarmforge/handoffs/ 下,其中包含 outbox、sent、failed 和 inbox 子目录。Agent 不应手动编辑、合并、暂存或提交交接运行时状态。完整协议请参阅 swarmforge/handoff-protocol.md。

swarmforge/swarmforge.conf 逐窗口定义 swarm。每一行采用以下形式:

window <role> <agent> <worktree> [task|batch] [extra-cli-args...]

可选的接收模式默认为 task。对于应将当前队列中所有同等优先级交接任务作为一个批次消费的角色,请使用 batch。

接收模式之后的所有字段都会作为额外参数直接传递给 Agent CLI。如果省略接收模式,额外

English / 原文

Do not spend any money on a bankrbot SWARM token.

A disciplined tmux-based agent orchestration platform that turns swarms of AI agents into reliable, professional software engineers.

This main branch is documentary: it explains the system and carries the shared operational scripts and default constitution articles. The runnable workflow branches carry the project-facing configurations, role prompts, and local constitution articles that define specific workflows.

SwarmForge is an agent coordination system that facilitates communication between agents working in different git worktrees.

It provides a shared structure for role-specific prompts, worktree assignment, tmux sessions, and message passing so multiple agents can collaborate on the same project without stepping on each other.

The runnable SwarmForge configurations live on dedicated branches. Each branch contains the swarmforge/swarmforge.conf, local constitution articles, and role prompts for one workflow. At startup, its ./swarm wrapper copies the shared operational scripts and shared constitution articles from main when they are not already present, then launches that branch's local configuration.

two-pack is the quick backend workflow. Use it for small tasks that benefit from fast coding without the overhead of Gherkin and acceptance testing, while still preserving backend refactoring and hardening.

  • coder implements requested behavior with TDD and unit tests.
  • cleaner batches coder handoffs and performs cleanup, CRAP and DRY review, architectural review, encapsulation and separation-of-concerns fixes, and language mutation hardening.

The normal flow is coder -> cleaner -> coder. Use this branch when you want a tight implementation/refinement loop without specification, QA, property-test, or acceptance-test roles.

four-pack is the compact specification workflow. Use it for moderate projects that require Gherkin specification and some architectural consideration without splitting every quality gate into its own agent:

  • specifier turns user intent into precise Gherkin acceptance specifications and asks for approval before handoff.
  • coder implements approved behavior slices with TDD, unit tests, and generated acceptance tests.
  • refactorer performs behavior-preserving cleanup, coverage improvement, CRAP and DRY review, mutation-site scans, and property-test support.
  • architect owns high-level structure, dependency direction, mutation hardening, DRY review, soft Gherkin mutation, and final completion notification.

The normal flow is specifier -> coder -> refactorer -> architect -> specifier. Use this branch when you want disciplined development without splitting cleanup, architecture, hardening, and QA into separate agents.

six-pack is the full workflow. Use it for major projects that require full specification, up-front QA, backend verification, and significant architectural consideration. It separates each major quality gate into its own role:

  • specifier turns user intent into accepted Gherkin specifications and end-to-end QA procedures.
  • coder implements approved behavior slices with TDD, unit tests, and generated acceptance tests.
  • cleaner performs local behavior-preserving cleanup, coverage improvement, CRAP and DRY review, and mutation-site scans.
  • architect reviews module structure, boundaries, dependency direction, and property-test coverage.
  • hardender performs mutation hardening, language mutation, CRAP and DRY verification, and soft Gherkin mutation.
  • QA converts the specifier's QA procedures into executable scripts, runs final user-interface verification, checks handoff consistency, and sends completion notifications.

The normal flow is specifier -> coder -> cleaner -> architect -> hardender -> QA -> completion. Use this branch when you want each review and verification concern owned by a separate agent.

SwarmForge runs locally. Before starting a runnable branch, make sure the target machine has:

  • zsh
  • git
  • tmux
  • Babashka (bb)
  • At least one configured agent backend, such as codex, claude, copilot, or grok

In the directory where you want to use SwarmForge, choose a runnable branch and pull its contents without creating a Git remote:

BRANCH=four-pack
curl -L "https://github.com/unclebob/swarm-forge/archive/refs/heads/${BRANCH}.tar.gz" | tar -xz --strip-components=1

Use BRANCH=two-pack for the quick two-agent workflow, BRANCH=four-pack for the compact specification workflow, or BRANCH=six-pack for the full six-agent workflow. Do not use main for this command; main is documentary and stores the shared operational scripts, while the runnable branches provide the configurations and prompts intended for projects.

After copying a runnable branch, start the swarm from the target project:

The ./swarm wrapper keeps the runnable branch small. On first use, if swarmforge/scripts/ is missing, it downloads the main branch archive, copies the shared operational scripts from swarmforge/scripts/, stages shared constitution articles from swarmforge/constitution/articles/, and then launches swarmforge/scripts/swarmforge.sh. Later runs reuse the existing local scripts directory instead of overwriting it.

The windows should open automatically.

To stop the swarm, close the first window listed in swarmforge/swarmforge.conf. That cleanup window shuts down the tmux sessions and closes the remaining tracked windows.

While a swarm is active, SwarmForge tries to prevent the host from sleeping. On macOS it uses caffeinate; on Linux it uses systemd-inhibit when available. Display lock or manual sleep can still interrupt agents depending on the OS. Set SWARMFORGE_PREVENT_SLEEP=0 before ./swarm to disable this behavior.

SwarmForge is a lightweight, tmux-based orchestration layer that:

  • Launches a config-driven swarm from a project-local swarmforge/swarmforge.conf

  • Creates one tmux session per configured role and opens a terminal surface for each role when the selected backend supports it

  • Reads behavior from project-local swarmforge/roles/<role>.prompt files plus a layered swarmforge/constitution.prompt

  • Supports per-role backends such as claude, codex, copilot, or grok

  • Puts the shared swarmforge/scripts/ directory on each agent's PATH, including handoff helpers for active swarm communication

  • Creates git worktrees under .worktrees/ for roles assigned to dedicated worktree names

  • Initializes a git repository in a new working directory when needed

  • Keeps all swarm state local to the working directory in .swarmforge/

  • Config-Driven Topology — The swarm shape comes from swarmforge/swarmforge.conf, not hardcoded shell variables.

  • Project-Local Roles — Each role is defined by swarmforge/roles/<role>.prompt in the working tree being orchestrated.

  • Layered Constitution — swarmforge/constitution.prompt directs agents to read article files under swarmforge/constitution/articles/.

  • Backend Selection Per Role — A role can launch claude, codex, copilot, or grok.

  • Observable Swarm — Open one Terminal window per role and watch the sessions in real time.

  • Self-Hosted & Lightweight — Runs locally in tmux and Terminal with minimal machinery.

Each runnable branch contains a swarmforge/ directory with this general layout:

swarmforge/
  swarmforge.conf
  constitution.prompt
  constitution/
    articles/
      project.prompt
      local-engineering.prompt
      local-workflow.prompt
      ...
  roles/
    <role>.prompt
    ...

constitution.prompt is the entry point. Runnable branches normally use it to tell agents to read every file in swarmforge/constitution/articles/.

Shared default articles live on main under:

swarmforge/constitution/articles/
  engineering.prompt
  handoffs.prompt
  workflow.prompt

At startup, SwarmForge installs missing shared articles into the runnable branch's swarmforge/constitution/articles/ directory before creating role worktrees. It also installs missing shared articles into each role worktree during script synchronization. Existing local files are skipped, so a runnable branch can override a shared article by committing an article with the same filename.

Pack-specific additions and exceptions should use explicit local filenames rather than editing shared articles. Current conventions are:

  • project.prompt for the workflow's project shape and local topology.
  • local-engineering.prompt for workflow-specific engineering rules.
  • local-workflow.prompt for workflow-specific flow rules.

The local-*.prompt naming convention means "add to or specialize the shared default article for this runnable branch." Use it when the shared article remains valid and the branch only needs extra requirements, exceptions, or narrower instructions. Do not use local-*.prompt for a full replacement; use the shared filename instead when the branch intentionally overrides the shared article.

For example, main can provide a shared workflow.prompt, while six-pack can add local-workflow.prompt for QA-specific handoff behavior. If a branch needs to replace the shared workflow article completely, it can commit its own workflow.prompt; startup will treat that local file as an override and will not copy the shared one over it.

Each role in swarmforge/swarmforge.conf maps to a corresponding swarmforge/roles/<role>.prompt file.

In a runnable branch:

  1. SwarmForge reads swarmforge/swarmforge.conf.
  2. The root ./swarm wrapper copies shared helper scripts, terminal adapters, and shared constitution articles from the main branch when they are not already present.
  3. Startup installs missing shared constitution articles into swarmforge/constitution/articles/, skipping any local article file that already exists.
  4. Startup validates the configured role prompts, helper scripts, and terminal adapters.
  5. If the target directory is not already a git repository, startup initializes one and creates the first commit.
  6. Startup creates one git worktree per configured role under .worktrees/, unless the role is assigned to master or none.
  7. Startup syncs swarmforge/scripts/ and missing shared constitution articles into each role worktree and puts that local scripts directory on each agent's PATH, so agents use local handoff helpers without reaching back into the master checkout.
  8. SwarmForge creates tmux sessions, opens terminal windows, and launches each configured backend in its assigned worktree.
  9. Startup starts an OS-specific sleep inhibitor when one is available, and cleanup stops it with the swarm.
  10. Roles communicate through daemon-delivered handoff files. Agents create validated drafts with swarm_handoff.sh, accept work with ready_for_next.sh, and complete work with done_with_current.sh.

Startup syncs the shared helper scripts into every role worktree under swarmforge/scripts/ and puts that local directory on the agent's PATH. Agents do not send tmux messages directly. The launcher starts handoffd.bb, which owns tmux socket access, watches each agent outbox, copies validated handoff files into recipient inboxes, and sends only generic wake-up notifications.

Agents interact with handoffs through three helper scripts:

  • swarm_handoff.sh <draft-file> validates and queues outbound handoffs.
  • ready_for_next.sh accepts work using the role's configured receive mode.
  • done_with_current.sh completes the current task or batch using the role's configured receive mode.

Outbound drafts use one of two message types. A git handoff points the recipient at a committed state. The commit abbreviation must be exactly 10 hexadecimal characters; swarm_handoff.sh validates that it resolves to a single commit and canonicalizes it before queuing the handoff.

type: git_handoff
to: <role>[,<role>...]
priority: NN
task: <short-stable-task-name>
commit: <10-character-commit-abbrev>

A note is one short freeform message:

type: note
to: <role>[,<role>...]
priority: NN
message: <one line, max 80 chars>

The helper generates the delivered payload. Agents do not write long handoff bodies, branch names, queue filenames, or tmux commands.

Recipient agents run ready_for_next.sh when notified or after restart. It dispatches to the task or batch helper configured for that role. If it prints NO_TASK, they stop waiting for work. If it prints TASK: <path>, they treat the printed TASK_NAME and PAYLOAD as the task. If it prints BATCH: <path>, they process the printed BATCH_ITEM entries in helper-delivered order. If a wake-up arrives while an agent is already working, it can ignore the wake-up; done_with_current.sh checks for the next task or batch after completing the current work.

The durable handoff files and lifecycle headers replace the old logbook and resend queue. Runtime handoff state lives under .swarmforge/handoffs/ in each worktree, with outbox, sent, failed, and inbox subdirectories. Agents should not hand-edit, merge, stage, or commit handoff runtime state. See swarmforge/handoff-protocol.md for the full protocol.

swarmforge/swarmforge.conf defines the swarm window-by-window. Each line has this form:

window <role> <agent> <worktree> [task|batch] [extra-cli-args...]

The optional receive mode defaults to task. Use batch for roles that should consume all currently queued equal-priority handoffs as one batch.

Any fields after the receive mode are passed directly to the agent CLI as additional arguments. If you omit the receive mode, extra arguments may start at the fifth field:

window coder copilot wt-coder --yolo
window architect claude wt-arch task --dangerously-skip-permissions

You can define as many windows as your project needs. Each role maps to a corresponding prompt file at swarmforge/roles/<role>.prompt, so a config containing architect, coder, reviewer, research, and release windows would expect:

  • swarmforge/roles/architect.prompt
  • swarmforge/roles/coder.prompt
  • swarmforge/roles/reviewer.prompt
  • swarmforge/roles/research.prompt
  • swarmforge/roles/release.prompt

This lets each project choose its own swarm shape instead of being locked to a fixed set of roles.

Example config:

window coordinator codex master
window coder codex coder
window refactorer codex refactorer
window architect codex architect

In the example above, the agents run in these worktrees:

  • coordinator -> main working directory on master, and is the cleanup window because it is listed first
  • coder -> .worktrees/coder
  • refactorer -> .worktrees/refactorer
  • architect -> .worktrees/architect

If a window uses master as its worktree name, SwarmForge does not create .worktrees/master; that role runs in the main working directory on the master branch.

SwarmForge uses a project-specific tmux socket recorded in .swarmforge/tmux-socket, so each project swarm is isolated from other tmux sessions. It also honors tmux base-index and pane-base-index settings when launching agents and sending notifications, so configurations that number windows or panes from 1 work without requiring users to change their tmux preferences.

SwarmForge opens trackable terminal windows or tabs through a small terminal backend adapter.

Default detection:

  • If AppleScript is available, SwarmForge opens macOS Terminal.app windows.
  • Otherwise, if wt.exe is available, SwarmForge opens Windows Terminal windows.
  • Otherwise, SwarmForge attaches the cleanup tmux session in the current shell.

After copying a runnable branch, set SWARMFORGE_TERMINAL to override detection:

SWARMFORGE_TERMINAL=ghostty ./swarm
SWARMFORGE_TERMINAL=terminal-app ./swarm
SWARMFORGE_TERMINAL=windows-terminal ./swarm
SWARMFORGE_TERMINAL=none ./swarm

Use ghostty when you want SwarmForge to open Ghostty tabs instead of the default Terminal.app windows. Use windows-terminal when you want SwarmForge to open Windows Terminal windows from WSL. Use none when you want SwarmForge to skip terminal automation and attach the cleanup tmux session in the current shell.

Adding A Terminal Backend

The shared terminal backends are carried on main under swarmforge/scripts/terminal-adapters/. Runnable branches copy those scripts at startup. To add a new backend, update main by creating one file named after the backend:

swarmforge/scripts/terminal-adapters/wezterm.sh

The file must define this small contract:

terminal_backend_label() {
  echo "WezTerm"
}

terminal_backend_can_open_sessions() {
  return 0
}

terminal_backend_tracks_windows() {
  return 0
}

terminal_open_session() {
  local session="$1"
  local title="$2"
  local sibling_id="${3:-}"

  # Open a terminal surface that runs:
  # cd "$WORKING_DIR" && exec tmux -S "$TMUX_SOCKET" attach-session -t "$session"
  #
  # Print a stable window/tab id to stdout.
}

terminal_window_exists() {
  local window_id="$1"

  # Return 0 if the id from terminal_open_session still exists.
  # Return nonzero otherwise.
}

terminal_close_window() {
  local window_id="$1"

  # Close the id from terminal_open_session.
}

If the terminal can open sessions but cannot return stable ids for open/check/close, keep terminal_backend_can_open_sessions as return 0 and set terminal_backend_tracks_windows to return 1. SwarmForge will open one surface per session and skip the watchdog for that backend. swarmforge/scripts/terminal-adapters/windows-terminal.sh is an example of this launch-only style.

If the backend cannot open sessions at all, set both capability functions to return 1; SwarmForge will attach the cleanup tmux session in the current shell. Only edit swarmforge/scripts/swarm-terminal-adapter.sh when adding aliases or changing default auto-detection.

Each visible agent window is attached to a tmux session. That means terminal selection, copy, and paste may follow tmux and terminal-emulator rules rather than ordinary text-field behavior. If copy or paste feels unusual, check whether tmux copy mode is active before assuming the agent is stuck.

The first window in swarmforge.conf is the cleanup window. Closing that top configured window is the intentional shutdown path: SwarmForge tears down the tmux sessions, closes the remaining tracked windows, and shuts down the swarm.

Closing any other tracked window is non-destructive. The watchdog reopens that window and attaches it back to the same tmux session, so the agent state and terminal history remain intact. This is often the simplest way to recover a window that has landed in an unfamiliar tmux mode or otherwise feels stuck.