A terminal coding agent written in sw on the swarmrt runtime. Bring your own OpenAI-compatible endpoint — local (llama.cpp / vLLM) or hosted — and get structured tool calls, real subagents, vision, session search, skills, cron, and MCP in one headless or interactive REPL. Single native binary, no Python or Node.
https://github.com/skyblanket/swarm-code/raw/main/docs/assets/swarm-code-film.mp4
58 seconds, sound on — the whole idea: one 1.9 MB binary, workflows that fan out real agent processes, any model you point it at.
$ swarm
> /paste # PNG from clipboard → LLM multimodal block
ok: attached /tmp/swarm_paste_175324.png
> what's wrong with this button?
> /search "docker compose" # FTS5 across every past conversation turn
search: docker compose (3 hits)
[session-175300.jsonl assistant]
"docker compose up -d" builds the …
> recall_skill deploy-mally-otp # pull full playbook from ~/.swarm-code/skills/
SKILL.md loaded. Building burrito binary …
> /schedule "1h" "review open PRs" # heartbeat-driven cron (or "hourly", "daily 09:00")
✓ scheduled job 3 (1h): review open PRs
swarm-code builds against the swarmrt runtime, cloned alongside it:
git clone https://github.com/skyblanket/swarmrt ../swarmrt
git clone https://github.com/skyblanket/swarm-code
cd ../swarmrt && make swc libswarmrt
cd ../swarm-code && make
./bin/swarm-codeOr grab a prebuilt binary (macOS / Linux, arm64 + x86_64):
curl -fsSL https://raw.githubusercontent.com/skyblanket/swarm-code/main/scripts/install.sh | shOn Windows, run the same installer inside WSL2 — the Linux binaries work as-is. There is no native Windows build yet.
Run a one-shot headless query (pipe-friendly for scripts and CI):
swarm-code -p "summarize the open TODOs in this repo"
swarm-code -p --json "list the test files" | jq .Point it at any OpenAI-compatible endpoint via ~/.swarm-code/settings.json. Profiles let you switch models/providers per task:
{
"endpoint": "http://localhost:8000",
"model": "your-model",
"profiles": {
"local": { "vision": "true" },
"hosted": { "endpoint": "https://api.example.com/v1/chat/completions",
"model": "your-hosted-model", "api_key": "...", "vision": "true" }
}
}Remote endpoints are opt-in — set SWARM_CODE_ALLOW_REMOTE=1 (local-network-only by default; an API key alone is not an opt-in). The check applies to every URL the LLM layer dials — primary, fallback, providers, and /profile switches. Optional semantic memory recall uses SWARM_CODE_EMBED_ENDPOINT.
A repo-local ./.swarm-code.json is untrusted (it ships with whatever you cloned): it may set model, max_tokens, vision, chat_template_kwargs and llm_timeout_ms, and may only tighten permissions. Its hooks, MCP servers, endpoints, API keys, providers and profiles are ignored, with a one-line notice. To let a repo you trust apply its file in full, run swarm-code trust in it (or /trust in the REPL; swarm-code untrust reverses it, swarm-code trust --list shows the list). That adds the directory to "trusted_projects" in ~/.swarm-code/settings.json, which you can also edit by hand.
settings.json can run shell commands around tool calls; a PreToolUse hook that exits non-zero (or times out after 60s, or cannot be started) blocks the call, and the hook's output is shown to the model:
{ "hooks": {
"PreToolUse": [ { "matcher": "bash", "command": "./scripts/check-cmd.sh" } ],
"PostToolUse": [ { "matcher": "edit|write", "command": "make fmt" } ] } }A matcher is * or |-separated, case-insensitive alternatives, each matching a tool whose name contains it — plus tool families: bash also fires for every other tool that runs a shell command (background, bg_server, run_tests, file_watch, log_wait), and edit also for multi_edit. The tool arguments arrive as JSON on the hook's stdin and in the private file $SWARM_CODE_ARGS_FILE; $SWARM_CODE_ARGS carries them inline only when under 100KB (else $SWARM_CODE_ARGS_OMITTED=1), so a hook that must see every call should read stdin. $SWARM_CODE_EVENT / $SWARM_CODE_TOOL name the event and tool. Executable scripts in ~/.swarm-code/hooks/ (pre_tool.sh, post_tool.sh, pre_llm.sh, post_llm.sh) get the same treatment via stdin / $SWARM_HOOK_DATA_FILE — see src/Hooks.sw.
| Capability | Support |
|---|---|
| Profiles / BYOM | JSON profiles, any OpenAI-compatible endpoint |
| Tools | bash, read/write/edit, glob, grep, web fetch/search, git, browser automation, background jobs, todos, code search |
| Reusable skills | SKILL.md playbooks, recalled on demand |
| Vision | Clipboard paste and image paths |
| Session search | SQLite FTS5 across every past conversation |
| Scheduling | Heartbeat-driven interval and daily jobs |
| MCP | Client and stdio server |
| Multi-agent | Real subagents and /flows parallel workflows |
| Council | Bounded read-only panel plus judge synthesis (experimental) |
| Memory | Persistent journal with optional semantic embedding |
| Trajectory export | Fine-tuning JSONL |
| Modes | Interactive REPL and headless -p / --json |
| Distribution | Single native binary |
Subagents are real isolated swarmrt processes linked to their parent — not threads or coroutines — each running under its own tool-execution policy. /flows runs multiple agents in parallel from a JSON workflow definition with a live TUI.
The experimental council runs several repository-reading agents in parallel, then synthesizes their independent findings with a no-tools judge:
scripts/council.sh "What are the highest-risk production gaps in this repository?"
SWARM_COUNCIL_PROFILES=local,hosted \
SWARM_COUNCIL_PANEL_TIMEOUT=60 \
scripts/council.sh "Review the current architecture"Panel agents run under the fail-closed council_panel context: they may inspect repository files and diffs, but cannot use shell, write, background, browser, memory-mutation, or nested-agent tools. (Tool-level read-only isolation, not yet a filesystem sandbox.) See docs/FUSION.md for the pipeline and findings. Ready-made starting points — a sample skill and a parallel-review flow — live in examples/.
swarm-code runs shell commands, reads and writes files, and can reach the network — so it is built fail-closed:
- Local-network-only by default; remote endpoints require an explicit
SWARM_CODE_ALLOW_REMOTE=1. - A cloned repo's
./.swarm-code.jsoncannot run hooks, start MCP servers, redirect the endpoint/key, or loosen permissions unless you trust the directory (swarm-code trust). - The
write/edittools refuse swarm-code's own control files (~/.swarm-code/hooks, schedule, settings, sessions, profile override;.swarm-code.json) — only~/.swarm-code/memory/andskills/are writable — and credential dirs (.ssh,.aws,.gnupg, …) case-insensitively. - Every tool runs through one
ToolExecutorpolicy boundary — context allow-lists, argument-rewriting hooks, guardrails, and permissions — before any raw handler executes, and fails closed on a missing or unknown execution context. - Headless runs (
-p, cron jobs,/flowschildren) never auto-approve a call that needs permission — a dangerous command, an explicit"ask"setting, or an MCP tool — unless you setSWARM_CODE_HEADLESS_APPROVE=1. - A hardline command blocklist (
rm -rf /,mkfs,ddto a disk, halt/reboot, fork bombs, …) cannot be bypassed by environment overrides. It covers every tool that runs a shell command (bash,background,bg_server,run_tests), and commands are parsed likeshdoes — respellings such asrm -fr /,dd of=/dev/sda if=…orsh -c '…'are caught, while words inside quotes,echo/greparguments or heredoc bodies are not flagged. Denials name the matched pattern. - Subagents, MCP, and council contexts run under restricted (often read-only) policies.
- Secrets are redacted from session logs and trajectory exports.
See SECURITY.md for the model and how to report a vulnerability.
A single sw program compiled by swc and linked against libswarmrt. The agent loop (Agent.run) reads stdin, calls the LLM (LLM.chat), and routes structured tool_calls through the shared ToolExecutor boundary before raw handlers run. State lives in in-memory ETS tables and ~/.swarm-code/ (persistent). The runtime is BEAM-shaped: subagents are isolated, linked processes, so a crashing tool or subagent never takes the session down.
Key modules:
src/main.sw— CLI flags, headless mode, local-network gate, heartbeat spawnsrc/agent.sw— REPL loop, context compaction, session save/resume, permissionssrc/ToolExecutor.sw— shared context, hook, guardrail, and permission boundarysrc/ToolRegistry.sw— tool identity and execution-context policysrc/tools.sw— raw tool handlers (shell, file, http) over swarmrt builtinssrc/llm.sw— OpenAI wire format, streaming parse, structured tool_calls, multimodalsrc/Scheduler.sw— heartbeat-driven cron jobs that shell outswarm-code -p
Plus Vision.sw, SessionSearch.sw (FTS5), Skills.sw, Trajectory.sw, and Mcp.sw.
See CONTRIBUTING.md for the project layout, build commands, how to add a tool, and coding conventions. make check runs the full verification gate (unit, smoke, integration, module checks).
- claude-code — the structured tool_call pattern, permission tiers, and REPL UX this agent emulates.
- Hermes 3 / NousResearch — the skill / function-calling playbook format and agent-recallable procedures.
MIT — see LICENSE.
