A coding-agent harness that asks before it acts.
Stream from any provider — Umans, OpenAI, Gemini, or Anthropic — run an agentic tool loop in a Rust core, and approve every destructive action through a human-in-the-loop gate. Open source. One terminal.
Catalyst Code vs a plain agent loop, side by side.
Most coding agents are a model with a tool-calling loop bolted on. Catalyst Code is the production layer underneath — safety, persistence, and orchestration you'd otherwise build yourself.
| Concern | Catalyst Code | Raw tool-calling |
|---|---|---|
| Approval gate | Human-in-the-loop · 3 modes | None — you hope it's fine |
| Sandboxing | firejail + --no-network | Whatever you bolt on |
| Providers | 4 native + simultaneous login | One vendor, locked in |
| Subagents | 8 built-in + intercom bus | Roll your own |
| Sessions | Per-workspace · crash-safe | Lost on restart |
| Context | Auto-compaction at 70% | Manual · overflow crash |
| License | GPLv3 · self-host | Proprietary · cloud-only |
One command. Then a prompt.
No dependency hell, no cloud account. The installer drops catcode on your PATH; the Rust core can be embedded right into the binary. Log in, pick a model, type a prompt.
- 1Install:
catcode+catcode-coreto PATH. - 2
/login— pick a provider (key or OAuth). - 3
/model 3, then type a prompt. Approve destructive calls as they come.
The production layer underneath the model.
A safety floor, an orchestration layer, and the persistence to survive a crash — so the agent can actually run unattended.
Subagents that talk to each other.
A port of pi-subagents is built into the core. Delegate to focused child agents in single, parallel, or chained runs — and let them talk back over an in-process intercom bus. Workers ask reviewers; children prompt the orchestrator for unapproved decisions. Eight built-in agents, zero glue code.
Human-in-the-loop approval
Destructive tools (bash, write, edit) require consent under the default destructive mode. Approve once, or escalate only the matched tool kind — not the whole session.
Workspace confinement
Every file op resolves against a workspace root. Absolute paths and .. escapes are rejected; symlink escapes are caught via canonicalization. bash runs with cwd locked to the workspace.
Firejail sandbox
--sandbox firejail wraps bash in a generated profile that whitelists only the workspace + shell paths and drops caps/seccomp. --no-network adds unshare -n so bash can't phone home.
Context compaction
A token estimate triggers compaction at 70% of the model's window — oldest tool results dropped, system + recent turns kept. Orphaned-call sanitization never sends a tool_calls without a result.
Persistent sessions
Sessions live per-workspace as append-only JSONL. On restart the most-recent session replays. A mid-turn crash loses at most the in-flight turn. /undo, /compact, /sessions, /stats.
Multi-provider + OAuth
Log into several providers at once. /models lists every model tagged [openai], [gemini], [anthropic]. Mix subscription models in one session. Gemini & Claude use OAuth — no API key.
Memory & skills
A persistent memory store is injected into the system prompt — facts survive across sessions. Opt-in skills (.catalyst-code/skills/) encode reusable workflows. The harness self-learns.
Plugin system
Hooks at pre_/post_/lifecycle/pre_turn points. A pre_write linter, a vision-handoff that reroutes image turns, or a session logger — each a self-contained directory with a plugin.json manifest.
Metrics & debug log
TTFT, elapsed, tokens in/out, and TPS emitted per turn and shown in the TUI status bar. Structured JSONL debug log (init, tool, turn_done, http_retry, turn_error) for post-mortem.
Four providers. One terminal. Any login.
The core is OpenAI-compatible, so any OpenAI-shaped endpoint works. Four providers ship as first-party presets — log into several at once and mix models from different vendors in a single session.
| Provider | Kind | Endpoint | Auth |
|---|---|---|---|
Umans (GLM-5.2) Default provider. GLM reasoning_effort=high clamp + reasoning_content replay. | OpenAI | api.code.umans.ai/v1 | UMANS_API_KEY |
OpenAI (Codex) Standard chat-completions. Subscription OAuth not yet wired. | OpenAI | api.openai.com/v1 | OPENAI_API_KEY |
Google Gemini OAuth via authorization-code + PKCE + loopback redirect. gcloud token reused. | OpenAI compat | generativelanguage.googleapis.com/v1beta/openai | GEMINI_API_KEY |
Anthropic Claude OAuth via authorize + PKCE + loopback redirect. claude CLI token reused. | Anthropic | api.anthropic.com/v1 | ANTHROPIC_API_KEY |
Gemini and Claude support OAuth login —/login runs the authorization-code + PKCE flow in your browser and captures the token via a local callback, so your Google One AI or Claude Pro subscription works with no API key. An explicit key always takes precedence over OAuth.
Three layers, one JSON protocol.
The Rust core reads commands from stdin and writes events to stdout — one JSON object per line. The Go TUI spawns it and streams the events; the optional Next.js web frontend bridges the same protocol over SSE.
core/Async engine. Streams from any OpenAI-compatible /chat/completions, discovers models live, runs the agentic tool loop with an approval gate, and speaks a newline-delimited JSON protocol over stdio.
tui/Spawns the core, streams events, shows metrics, and handles approval prompts. Slash commands, session picker, model switcher, settings modal.
web/An optional Next.js frontend that bridges to the core over SSE — the same loop, in a browser. Ships as a systemd service that stays online.
- ›main.rs — turn loop, compaction, metrics
- ›provider.rs — streaming, retry/backoff, idle timeout
- ›subagent.rs — single/parallel/chain, forked context
- ›intercom.rs — peer bus, contact_supervisor
- ›plugins.rs — hook manager, pre_turn handoff
- ›workspace.rs — path confinement
- ›Spawns core, streams JSONL events
- ›Approval prompts: y / n / always
- ›/login · /model · /sessions · /stats
- ›Vision via /attach
- ›SSE bridge to the core
- ›Markdown + tool-call rendering
- ›Intercom & subagent panels
- ›Memory & plugin UI
Common questions, plain answers.
What is Catalyst Code?
A production-grade, OpenAI-compatible coding-agent harness. A Rust core streams from any provider, a Go TUI runs the agentic tool loop, and a human-in-the-loop gate approves every destructive action. It's the engine behind a coding agent — bring your own model.
Which providers does it support?
Four, natively: Umans (GLM-5.2, the default), OpenAI (Codex), Google Gemini, and Anthropic Claude. You can log into several at once — /models lists every model tagged by provider, and you can mix subscription models in a single session. Gemini and Claude support OAuth login, so no API key is required.
Is it safe to let the agent run bash?
That's the whole point of the approval gate. Under the default destructive mode, bash, write_file, and edit require consent — the TUI shows the call and prompts yes / no / always. For a hard boundary, pass --sandbox firejail --no-network: bash runs in a generated firejail profile with caps/seccomp dropped and the network namespace removed. The denylist is a tripwire on top.
What are subagents and the intercom?
A port of pi-subagents is built into the core. The orchestrator delegates to focused child agents (scout, researcher, planner, worker, reviewer, and more) in single, parallel, or chained runs. Children talk back over an in-process intercom bus — a worker can ask a parallel reviewer, or a child can prompt the orchestrator for an unapproved decision with contact_supervisor.
Do I need an API key?
Not always. Gemini and Claude support OAuth login — /login runs the authorization-code + PKCE flow in your browser and captures the token via a local callback, so your ChatGPT Plus, Google One AI, or Claude Pro subscription works with no key. Umans and OpenAI use API keys (env vars or pasted via /login).
Is it free and open source?
Yes. Catalyst Code is released under GPLv3. The entire codebase — Rust core, Go TUI, Next.js web frontend, and documentation — is open. There are no paid tiers or feature gates. Self-host everything.
What platforms does it run on?
Linux, macOS, and Windows. Each ships a native installer (AppImage, .dmg, MSI) and a standalone executable with the Rust core embedded via go:embed — run it from any directory with no install. The agent's bash tool needs bash on PATH (default on macOS/Linux; Git Bash or WSL on Windows).
How does context management work?
A token estimate (~4 chars/token) triggers compaction at 70% of the model's context window: the oldest tool results are dropped, the system prompt and recent turns are kept, and a compaction marker is inserted. Orphaned-tool-call sanitization inserts synthetic results so a compacted history never sends an assistant tool_calls without matching results.
Ready to ship with a guardrail?
Free, open-source, GPL-3.0. Install in one command and bring your own model — or your own subscription.