An agent runtime built for transparency. All state lives in the filesystem. Everything is observable with standard Unix tools. Nothing is hidden.
Early development. Most features described here are not yet implemented. Expect frequent breaking changes.
Agent frameworks today are opaque. State is buried in memory, hidden behind abstractions, and impossible to inspect without framework-specific tooling. When an agent fails, you get a stack trace at best. You rarely get the full picture of what it was doing, what it knew, and where it went wrong.
They are also heavy. Hundreds of transitive dependencies ship with every install. Each one is an attack surface. For software that has access to your tools, your files, and your APIs, that is a problem.
loom takes a different approach: agents should be transparent, secure, and easy to understand. State is plain files on disk. You can inspect everything with cat, tail, grep, and ls — no special tooling, no dashboards, no SDKs. The dependency tree is kept as small as possible because every package you don't ship is a vulnerability you don't have.
Nothing fancy. Just processes and files.
Every agent has an identity, a status, an inbox, and an outbox — all stored as plain files. Agents communicate by writing files. The supervisor watches them and restarts on crash. You can observe, debug, and understand the entire system with cat, tail, grep, and ls.
- Observable.
tail -f logs/my-agentworks.ls inbox/works.cat statusworks. No proprietary dashboards required. - Minimal dependencies. A small dependency tree means a small attack surface. Every package you don't ship is a vulnerability you don't have.
- Language-agnostic. The filesystem is the interface. Runners, plugins, and tools can be written in any language — Go, Python, Rust, shell scripts — they all just read and write files.
- Crash-resilient. State lives on disk, not in memory. Inbox messages are not lost when a process dies.
- Composable. Works with the Unix tools you already know:
watch,grep,jq,cron. No SDK required.
loom relies on Unix process semantics (POSIX signals, PID-based supervision, file descriptor inheritance). It runs on:
- Linux -- x64, arm64
- macOS -- x64, arm64
- Windows -- via WSL (use the Linux binary inside WSL)
Native Windows is not supported.
- Bun 1.3+
git clone https://github.com/lorenzh/loom
cd loom
bun install
bun run buildLocal development: use
bun run loom <command>instead ofloom <command>when running from the source repo. Theloombinary is only available after installing the published npm package.
Agents are Unix filters in foreground mode — stdin in, stdout out:
# Foreground (interactive, stdin/stdout/stderr)
loom agent start my-agent --model qwen3.5:9b
# Background (supervised, restarts on crash)
loom agent start my-agent --model qwen3.5:9b --detach
# Multi-agent weave from loom.yml
loom upCompose agents with standard Unix pipes:
# Chain models together
echo "extract action items" | loom agent start my-agent --model qwen3:8b --stdin
cat report.md | loom agent start summarizer --model qwen3:8b --stdin \
| loom agent start prioritizer --model qwen3:32b --stdin --system "prioritize by urgency"Supporting commands:
loom agent ps # list agents and their status
loom agent stop <name> # stop a specific agent
loom agent logs <name> # view agent logs
loom agent send <name> <msg> # send a message to an agent's inbox
loom down # stop all agents started by loom up| Mode | Supervisor | Restart on crash | Routing | I/O |
|---|---|---|---|---|
loom agent start (foreground) |
No | No | No | stdin/stdout/stderr |
loom agent start --detach |
Yes | Yes | Yes | Filesystem only |
loom up |
Yes | Yes | Yes | Filesystem only |
- Any language can read a file. No SDK required to observe an agent.
tail -f logs/my-agentworks.ls inbox/works.cat statusworks.- State survives process crashes. Inbox messages are not lost.
- Works offline. No cloud dependency. No API key required to run locally.
- Composable with Unix tools:
watch,grep,jq,cron.
The system has three main components:
Runner — one per agent. A self-sufficient OS process that polls its inbox, calls the LLM, executes tools, writes responses to the outbox, and maintains its own state files. Runners work standalone without a supervisor.
Pipes — named, reusable message processors. Each pipe is an array of operators — shell commands (operator: command) for stateless work (filter, transform, split) and built-in operators for stateful work (window, dedupe, throttle, accumulate). Pipes have the same filesystem layout as agents (inbox, outbox, steps, state). Every operator step writes its output as a .msg file to steps/N/, making the entire chain observable.
Supervisor — a process manager and message router. Spawns runners and pipes, detects crashes, restarts with exponential backoff. Routes messages between agents and pipes by watching outbox directories and copying .msg files to inbox directories per a routes table. If the supervisor dies, runners and pipes keep running — they just lose restart protection and routing.
Filesystem — the source of truth. All state is plain files. The CLI writes to the filesystem; the supervisor reads it. A SIGHUP signal nudges the supervisor to re-scan immediately.
Messages flow agent → (optional pipe) → agent. Agents declare their inputs with from:
agents:
- name: writer
from:
- agent: researcher
pipe: finding-filter
- agent: editoragent outbox ──→ [supervisor routes] ──→ pipe inbox ──→ pipe outbox ──→ agent inbox
│ ▲
└──────────── direct (no pipe) ──────────────────────┘
Each agent has a restart policy: always (default), on-failure, or never. Exponential backoff with jitter prevents runaway restart loops:
delay = min(1s * 2^restartCount, 5m) + jitter(0..500ms)
After 10 failures within one hour, the agent is marked dead and the supervisor stops restarting it.
Architecture decision records live in docs/adrs/.
| ADR | Title |
|---|---|
| ADR-001 | Unix process model for agents |
| ADR-002 | Filesystem as process table |
| ADR-003 | Inbox watcher via polling |
| ADR-004 | Supervisor and restart policy |
| ADR-005 | Runner architecture |
| ADR-006 | CLI and agent lifecycle |
| ADR-007 | Garbage collection and archival |
| ADR-008 | Ollama model availability |
| ADR-009 | Message origin tracking |
| ADR-010 | Pipe runner — named reusable message processors |
| ADR-011 | loom.yml — declarative weave configuration |
| ADR-012 | Filesystem as state store |
| ADR-013 | Model routing and provider abstraction |
| Proposal | Title |
|---|---|
| plugin-model | Plugin and extension model |
| plugin-protocol | Plugin protocol -- tools as executables |
MIT