The problem: your agent workflow lives in your head
Getting good output from a coding agent is rarely one prompt. It is plan, implement, review, fix, and you sit in the middle copying text between tools and deciding when to let the next step run.
SignalBox moves that process into a YAML file. You describe a pipeline of agents, point each one at a runtime (Codex, Claude, Copilot, or any OpenAI-compatible API), and SignalBox runs the chain. It pauses at approval gates so you can review in a web UI or the terminal, sends rejected work back for revision, and can start runs automatically from command-based watchers.
It is a single Go binary with the web UI embedded. The agent CLIs and script interpreters you use are installed separately, as they are today.
Try it in a minute
You can run a full pipeline without any AI credentials, because the scaffolded default uses a mock runtime. You need Go 1.25 or newer.
go install github.com/kaladinstorm84/SignalBox/cmd/signalbox@latest signalbox init my-project # creates signalbox.yaml + pipelines/default.yaml cd my-project signalbox validate # checks config and every pipeline signalbox serve # web UI on http://127.0.0.1:8484 signalbox run default --input "Hello SignalBox" # or run in the terminal Open the UI, start a run, and watch the diagram light up as agents finish. When the run reaches the approval gate it waits for you.
In the terminal, signalbox run prompts for approvals; pass --yes to auto-approve every gate, which is handy in scripts and CI.
A first real pipeline
Runtimes are named in signalbox.yaml, and agents refer to them by name. A pipeline is a list of agents plus the handoffs between them. This one plans with Claude, stops for a human, then implements with Codex:
name: plan-then-build
entry: planner
agents: - id: planner runtime: claude prompt: Turn the request into a short implementation plan. handoff: [review] - id: review type: approval description: Human review of the plan. handoff: [implementer] - id: implementer runtime: codex prompt: Implement the approved plan. An agent with no handoff ends its chain, and its output becomes the result of the run. The approval node passes the payload through unchanged when you approve. If you reject it, the planner reruns with your reviewer notes appended to its input, so the feedback is not lost.
Agents are not limited to AI. A code node runs a local script with its input on stdin and hands stdout downstream, so a plain Python or PowerShell check can sit between two agents.
Let your agent write the pipeline
You do not have to hand-write the YAML. The project that signalbox init creates includes an AGENTS.md, packaged to help an AI coding agent create pipelines itself. Open the project in your agent of choice, describe the workflow you want in plain English, and let it draft the pipeline.
The agent does not have to get it right first time. signalbox validate catches unknown handoff targets, normal handoff cycles, unreachable agents, missing runtimes or script files, and invalid code exit mappings, so the agent can run it, read the errors and fix its own YAML.
Review loops that do not run forever
The interesting part is what happens on rejection. Approval and gate nodes can route by decision, and build the next agent's input from a small template:
- id: human_review type: approval handoff: - to: publish condition: on_approve input: "{{ output }}" - to: revise condition: on_reject input: | {{ input }} Reviewer feedback: {{ comment }} Templates support only {{ input }}, {{ output }} and {{ comment }}. It is plain text substitution, not an expression language.
You can also put a model in the reviewer's seat. An llm_gate asks its runtime for an approve or reject decision with feedback, and the rework count is capped:
- id: quality_review type: llm_gate runtime: codex prompt: Check factual accuracy and completeness. max_reworks: 2 reject-to: writer handoff: [publish] If the gate rejects past max_reworks, the execution ends with a clear rework limit error instead of looping. A malformed verdict fails loudly and is never treated as an approval. The run view shows LLM verdicts separately from human approvals, so you can tell which was which.
A useful pattern is to put an llm_gate in front of the human gate, so you only spend attention on work that has already passed an automated check.
Fan-out, discussions and triggers
Once a linear chain works, the same YAML scales up.
• Parallel work. An orchestrator waits for every inbound handoff, then runs stages in order. Each stage dispatches to agents in parallel and collects their results. A stage can define a prompt to synthesise what came back.
• Joins. When several agents hand off to the same node, it waits for all of them and runs once on the combined input.
• Sessions. A session node is a multi-round discussion between participant agents who each see the transcript. It ends on consensus or at the round limit, and can route differently on each outcome.
• Chaining. A pipeline node runs another pipeline as a linked child execution. Approvals waiting in a child show up on the parent's page.
• Parameters. Declare params once and reference them as ${{ params.topic }}, so one pipeline serves several variants.
A session looks like this:
- id: design_review type: session participants: [architect, security_reviewer, delivery_lead] turn_order: round_robin max_rounds: 4 consensus: method: vote require: majority handoff: - to: sign_off condition: on_consensus - to: escalate condition: on_no_consensus Pipelines can also start themselves. A watcher runs a command on an interval, and when its output changes it starts the named pipeline with that output as input:
watchers: - name: jira-queue command: jira args: [issues, list, --jql, "project = OPS AND status = 'To Do'", --output, json] interval: 5m pipeline: default When a run breaks halfway
Agent runs fail, and the expensive part is rerunning everything before the failure. SignalBox treats that as a first-class case.
Runtime errors can retry automatically with a fixed delay:
- id: researcher runtime: codex retry: count: 2 backoff: 500ms When retries run out, the call pauses as waiting_retry with a Retry button, and parallel branches keep running. Nothing downstream of the failure proceeds until you retry or cancel.
A finished execution can also be restarted from any top-level run, or from a stage of an orchestrator:
signalbox restart --node coordinator --stage verify
Restarting creates a new execution and leaves the original untouched. Completed work that is not downstream of the restart point is copied across and marked as reused, so it is not paid for twice. Each execution stores a fingerprint of its resolved pipeline, and if the definition has changed since, the restart is refused and the changes are listed. Pass --force to restart on the current definition anyway. One limitation to know about: changes to script files used by code steps are not detected.
Execution history lives in .signalbox/executions.db, so it survives restarts. In-flight runs are marked interrupted and offer Retry from here.
Sharing pipelines, granting tools, and the security model
Registry. A registry is a directory, often on a file share, that holds versioned pipeline packages. Publishing bundles a pipeline with its imports and the scripts its code steps use, and records a SHA-256 for every file. Install verifies the hashes first, validates the pipeline against your project's runtimes in a staging copy, and records the result in signalbox.lock.json.
signalbox registry publish release-notes --version 1.1.0 signalbox registry install release-notes@latest MCP servers.
Tool access is opt-in at two levels. The project registers servers and the tools they may expose. Each agent then names the servers, and optionally a subset of tools, it needs. SignalBox does not run the servers itself. It passes only the granted ones to the codex, claude or copilot CLI for that call. Secrets are never written in YAML: env_from names an environment variable that is read at call time.
Security.
SignalBox is a local, single-user tool, and the server has no authentication. Keep it bound to loopback, which is the default. Code steps run with your user's permissions and are not sandboxed, and MCP servers do too. Run only pipelines and scripts you trust. The docs also call out that Codex and Copilot still load your own global MCP servers alongside the granted ones, while Claude is told to ignore them.
What it is not, and who it is for
SignalBox is not a general automation platform. It has no catalogue of integrations, no multi-user auth, and no hosted option. It is also not a library for building LLM apps: pipelines are YAML, and the custom logic you can add is a code step. Other tools cover those jobs, and some of them cover pipelines of coding agents too, so try a few and pick what fits how you work.
Where SignalBox aims to be good is a narrower job: chaining the agent CLIs you already use, with review points you control, on your own machine, and with a way back when step four of six fails.
It is early in it's life and MIT licensed. The repo includes a test project with demo pipelines for conditional handoffs, gates, sessions, chaining, MCP, recovery and the registry, so the fastest way in is to clone it and run them with the mock runtime.
• Repo: github.com/kaladinstorm84/SignalBox
• Bugs, ideas and awkward YAML are all welcome as issues.
If you chain coding agents by hand today, I would like to hear which pipeline you would build first.


