Catalyst Code
Coding-Agent Harness
Open Source · GPL-3.0

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 — ~/my-project
$ catcode
Catalyst Code v1.0.0 · Umans · glm-5.2
> refactor src/auth.rs to use anyhow + ?
reading src/auth.rs
⚠ APPROVE? edit src/auth.rs
- .unwrap() .context("decode")?
[y]es [n]o [a]lways
y applied 3 edits
running cargo check
compiles — 0 errors
Providers
4
Umans · OpenAI · Gemini · Anthropic
Subagents
8
Built-in agents + intercom
Platforms
3
Linux · macOS · Windows
Tools
12+
read · edit · grep · bash…
Provider Status
Ready
Umans (GLM-5.2)
default · API key
OpenAI (Codex)
API key
Google Gemini
OAuth · PKCE
Anthropic Claude
OAuth · PKCE
Simultaneous loginsupported

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.

Approval gate
Catalyst Code
Human-in-the-loop · 3 modes
Raw loop
None — you hope it's fine
Sandboxing
Catalyst Code
firejail + --no-network
Raw loop
Whatever you bolt on
Providers
Catalyst Code
4 native + simultaneous login
Raw loop
One vendor, locked in
Subagents
Catalyst Code
8 built-in + intercom bus
Raw loop
Roll your own
Sessions
Catalyst Code
Per-workspace · crash-safe
Raw loop
Lost on restart
Context
Catalyst Code
Auto-compaction at 70%
Raw loop
Manual · overflow crash
License
Catalyst Code
GPLv3 · self-host
Raw loop
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.

One commandLinux · macOS · WindowsEmbedded coreNo admin needed
  1. 1Install: catcode + catcode-core to PATH.
  2. 2/login — pick a provider (key or OAuth).
  3. 3/model 3, then type a prompt. Approve destructive calls as they come.
bash
$curl -fsSL catalyst-code.dev/install.sh
→ installs catcode + catcode-core to /usr/local/bin
$catcode
⚡ Catalyst Code — Umans · glm-5.2 (default)
>/login
pick: Umans · OpenAI · Gemini · Anthropic
authed — token stored (0600)
>/model 3
model set: glm-5.2
>ship the auth refactor
✦ reading 4 files …

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.

Centerpiece

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.

orchestratorworkerreviewer·scoutplanner

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.

ProviderKindEndpointAuth
Umans (GLM-5.2)
Default provider. GLM reasoning_effort=high clamp + reasoning_content replay.
OpenAIapi.code.umans.ai/v1UMANS_API_KEY
OpenAI (Codex)
Standard chat-completions. Subscription OAuth not yet wired.
OpenAIapi.openai.com/v1OPENAI_API_KEY
Google Gemini
OAuth via authorization-code + PKCE + loopback redirect. gcloud token reused.
OpenAI compatgenerativelanguage.googleapis.com/v1beta/openaiGEMINI_API_KEY
Anthropic Claude
OAuth via authorize + PKCE + loopback redirect. claude CLI token reused.
Anthropicapi.anthropic.com/v1ANTHROPIC_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.

CoreRust
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.

JSONL
TUIGo · Bubble Tea
tui/

Spawns the core, streams events, shows metrics, and handles approval prompts. Slash commands, session picker, model switcher, settings modal.

JSONL
WebNext.js
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.

CoreRust
  • 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
TUIGo · Bubble Tea
  • Spawns core, streams JSONL events
  • Approval prompts: y / n / always
  • /login · /model · /sessions · /stats
  • Vision via /attach
WebNext.js
  • SSE bridge to the core
  • Markdown + tool-call rendering
  • Intercom & subagent panels
  • Memory & plugin UI
protocol · stdio
# stdin → command
{"type": "send", "prompt": "refactor auth", "model": "umans-glm-5.2"}
# stdout → events (one per line)
{"type": "approval_request", "tool": "edit"}
{"type": "metrics", "tps": 87.4, "tokens_out": 1204}

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.