Skip to content
  • open source
  • AGPL-3.0
  • v0.2.0
  • Bun ≥ 1.3.14
  • TypeScript

A terminal coding agent with a cockpit, not a chat log.

Rovecode runs on Bun, speaks to 16 providers or any OpenAI-compatible endpoint, and passes every tool call through a deny-default policy before it touches your repository. Free software under AGPL-3.0.

$ rovecode "fix the failing test"
rovecode · atlas · feature/authreal frame
The sextant TUI at 160 by 44 cells: files tree with git statuses, the code panel showing src/auth/callback.ts with the edited lines highlighted, the messages panel with read and edit tool rows and an approval card asking to run bun test, the plan at 1 of 4 steps, usage at 13 percent context, and the rovecode cloud pet asking for a nod.
+4 −1 landedask first · approval cardcontext 13 % of 200k

Real frame: the approval card for bun test, the +4 −1 edit row, context at 13 % of 200k. Rendered through the sextant painters at a fixed clock.

  • 2,200+tests
  • 16built-in providers
  • 4policy layers
  • 15languages on this page
  • AGPL-3.0license

A coding agent for the terminal. TypeScript on Bun, 47 ported patterns, one deny-default policy in front of every tool.

teams running rovecode

  • Northwind Robotics
  • Harbourline Payments
  • Meridian Studio
  • Cobalt Grid
  • Larkspur Health
  • Tessellate
  • Ferrous Labs
  • Quill & Compass

Placeholder names, until the first customers agree to be listed.

02the cockpit

Six panels on one screen. The file you care about never scrolls away.

Files with git status, code with the highlight band and ± diff, compact tool rows, plan, usage and the pet. Rendered headlessly through the sextant painters at a fixed clock: the same code path the TUI paints with, not a mockup.

messages panel · row for row

One run, transcribed from the frame above.

Every tool call is one row: the verb, the file, and what changed. The edit landed as +4 −1. The shell command waits behind one card with three answers; Esc denies, and the answer is cached for the rest of the session.

Child agents cannot prompt. A forbidden argv never reaches the card at all.

03problems → solutions

Four things that go wrong with terminal agents, and what rovecode does about each.

Stated in the words you would use at the keyboard, answered with the mechanism and its limit. Every strip is a real frame crop or the real config file.

  1. ~/.rovecode/providers.json
    {
    "default": "kaesra/zai-org/glm-5.3-flash",
    "providers": {
    "kaesra": {
    "baseUrl": "https://api.kaesra.tech/v1",
    "protocol": "openai",
    "keyEnv": "KAESRA_API_KEY"
    },

    01problem

    Every agent ships welded to one vendor's API and one pricing page.

    what rovecode does

    One StreamFn seam and a live provider registry. 16 named providers, or any OpenAI-compatible or Anthropic endpoint from providers.json; a provider added in another terminal serves the very next call. Role fallback chains advance on a 429 or 5xx.

    rovecode provider add homelab http://10.0.0.7:8000/v1 --no-key
  2. The messages panel: a user line, the assistant's note, then compact tool rows for read and edit with +5 −2

    02problem

    A chat log scrolls the file you care about off the screen while the agent edits it.

    what rovecode does

    A panelled cockpit: files, code, messages, plan, usage and the weather-cloud pet. The messages panel keeps tool calls to one compact row each; the code panel shows the one hunk that landed.

    files · code · messages · plan · usage · rovecode
  3. The approval card: needs your permission, bash rm -rf node_modules && git checkout -- ., with deny selected

    03problem

    The model asks for rm -rf and the harness runs it because nobody said no in time.

    what rovecode does

    Deny-default wildcard rules, then execpolicy verdicts where forbidden never reaches execution or a human, then an approval card on revised args. 4 stacked layers, none of them pretending to be a sandbox.

    rules → execpolicy → approval → runtime denylist + cwd lock
  4. The /rewind picker: rewind to a turn, rows #38 to #41 with #40 selected

    04problem

    Turn 40 goes wrong and the only way back is a new conversation.

    what rovecode does

    An append-only JSONL session tree with a sha256 hash chain. /rewind opens the turn picker, branches from any turn and prefills the editor with that turn's full text; shadow-git checkpoints restore in 3 modes without touching your .git.

    /rewind /checkpoints /restore rovecode trace <session-id>
  1. 01sextant cockpit
  2. 02providers, hot-reloaded
  3. 03MCP client
  4. 04Safety ladder
  5. 05Session tree + checkpoints
  6. 06ACP for Zed + JetBrains
  7. 07Headless HTTP + SSE
  8. 08Background subagents
  9. 09Hooks
  10. 10OpenTelemetry

04capabilities

Ten capabilities, each one a port with a file:line trail.

Rovecode ports evidence-based patterns from pi, opencode, codex, cline, aider, gemini-cli and others. A port lands only after a fresh-context critic verifies it against a bar written before the work began.

surface

sextant cockpit

6 panels on a truecolor TTY of at least 100×30: files with git status, code with the highlight band and ± diff, compact tool rows, plan, usage, the pet. 3 palettes, /theme switches live; --classic keeps the pi-tui chat.

rovecode · ROVECODE_TUI=sextant|classic · /theme night|ember|contrast
Crop of the sextant frame: files tree and the code panel with the editing highlight band

providers

providers, hot-reloaded

16 built-ins plus anything you register in providers.json. Every call resolves the provider against the live snapshot: add one in another terminal and the running cockpit uses it on the next call. No restart.

rovecode provider add|list|test · rovecode model use provider/model
~/.rovecode/providers.json
{
"default": "kaesra/zai-org/glm-5.3-flash",
"providers": {
"kaesra": {
"baseUrl": "https://api.kaesra.tech/v1",
"protocol": "openai",
"keyEnv": "KAESRA_API_KEY"
},
"homelab": {
"baseUrl": "http://10.0.0.7:8000/v1",
"protocol": "openai",
"noKey": true,
"models": ["qwen3-coder-30b"]
}
}
}
  • context

    MCP client

    stdio and HTTP servers from .rovecode/mcp.json. Lazy disclosure through 2 registry tools, so an idle server costs close to zero tokens.

    mcp_list · mcp_call
  • safety

    Safety ladder

    Every tool call climbs four rungs before it runs. A forbidden argv is denied before any hook sees it; --yolo skips prompts, never deny rules.

    rules → execpolicy → approval → runtime

  • memory

    Session tree + checkpoints

    Append-only JSONL with a sha256 hash chain. /rewind branches, /resume picks up, shadow-git checkpoints restore in 3 modes and never touch your .git.

    /rewind · /checkpoints · /restore
  • ACP for Zed + JetBrains

    Agent Client Protocol v1 over stdio, official SDK.

    rovecode acp
  • Headless HTTP + SSE

    Sessions, one RunEvent stream, OpenAPI at /doc. Port 4100, loopback-only.

    rovecode serve
  • Background subagents

    Bounded FIFO child sessions, 3 concurrent by default; notes land on the parent's next turn.

    /tasks
  • Hooks

    9 typed hooks in .rovecode/hooks.ts, each bounded by a 5 s timeout. pre_tool can only deny.

    pre_tool · approval · on_event
  • OpenTelemetry

    One trace per run: run ⊃ turn ⊃ tool with tokens, latency, cost. Unset endpoint, no exporter.

    ROVECODE_OTEL_ENDPOINT

05security and deployment

Four layers in front of every tool call. Nothing leaves the machine you did not configure.

The safety model as the README states it, limits included. Each layer names what it decides and where it stops; none of them is a sandbox.

  1. layer 01

    01rules

    Deny-default wildcard policy rules over tool and argv. A forbidden pattern is denied before anything runs.

    limitPattern matching, not intent: a novel spelling of a dangerous command passes to the next layer.

  2. layer 02

    02execpolicy

    Verdicts on the parsed argv: allow, prompt, forbidden. Forbidden never reaches execution or a human.

    limitReads the command, not the shell it will run in; an alias or a script body is opaque to it.

  3. layer 03

    03approval

    One card on the revised args with allow, always and deny. Answers are cached per session; child agents cannot prompt.

    limitA human decision: --yolo skips this rung, never the deny rules above it.

  4. layer 04

    04runtime

    A bash denylist and a cwd lock at execution; Esc kills the running call and, on Windows, its whole process tree.

    limitDelegation, not isolation. Untrusted work belongs in a container or microVM.

deployment and data

  • 01

    Self-hosted by definition

    Runs from source on your machine or your CI. An account is optional: it unlocks the plans on the pricing page and never gates the CLI. Bun ≥ 1.3.14 is the one requirement.

  • 02

    No phone-home

    Outbound traffic goes only to the provider you configured, the MCP servers you listed and web_fetch when the model asks. Pricing catalog is an offline snapshot; there is no self-update.

  • 03

    Telemetry is opt-in

    OpenTelemetry export is off until ROVECODE_OTEL_ENDPOINT is set; even then it carries ids, sizes and outcomes — never prompts, arguments or output.

  • 04

    Audit trail by construction

    Sessions are append-only JSONL with a sha256 hash chain; every run exports one trace (run ⊃ turn ⊃ tool), including cancelled ones.

  • 05

    Platform status

    Windows-first: development and the release gate run on Windows 11. POSIX paths are tested, Linux and macOS are not yet CI-verified.

  • 06

    License

    AGPL-3.0-only. Modify and redistribute freely; running a modified build as a network service obliges you to offer its source to those users.

06from the terminal

Four real frames at 160×44, with the parts worth reading numbered.

Rendered headlessly through the sextant painters at a fixed clock: the same code path the TUI paints with, not a mockup. Hover a row, or tap it, and the frame zooms 2× on that spot.

rovecode · atlas · feature/auth · 160×44real frame
sextant frame after an edit: the code panel in diff mode shows one hunk, the messages panel lists read and edit tool rows

The edit landed. The code panel shows exactly that hunk.

Captured before an approved edit, rebuilt from the edit's own anchors after an ungated one.

  1. 1Switch to ± diff mode as the edit lands
  2. 2Read +4 −1 against the file on disk
  3. 3Follow the compact tool rows: read, then edit
  4. 4Watch context fill at 13 % of 200k
rovecode · atlas · feature/auth · 160×44real frame
sextant frame with the approval card open: bash bun test tests/auth.test.ts, allow always deny

A shell command waits for a nod. One card, three answers.

Approvals resolve on revised args and are cached per session; child agents cannot prompt.

  1. 1See the exact argv before it runs
  2. 2Choose allow, always or deny; Esc denies
  3. 3Header switches to waiting for you
  4. 4Pet asks for the nod, then remembers it
rovecode · atlas · feature/auth · 160×44real frame
sextant frame after the run finished: the code panel in run mode shows bun test output with 18 pass, plan 4/4 complete

Tests ran. The $ panel keeps the output; the header freezes the clock.

PASS and FAIL chips read the exit code from the tool's own header line.

  1. 1Read the run output in $ mode, 18 pass
  2. 2Plan closes at 4/4 steps
  3. 3Tool row carries the last line of output
  4. 4Cost lands at $0.071 from the offline catalog
rovecode · atlas · feature/auth · 160×44real frame
sextant frame with the crew board open: two lanes, write tests running and review done

Two background tasks, one lane each, on the crew board.

Child sessions share the one agent loop; quitting the TUI cancels every live child.

  1. 1Open the ∷ agents board with ⌃a
  2. 2Each lane shows label, elapsed and status
  3. 3Crew summary stays in the plan panel
  4. 4Parent run keeps editing meanwhile

07quickstart

Three commands from clone to a running agent.

Without a provider configured, one-shot runs use a scripted mock provider, which is also how the packaging smoke works.

  1. 01

    Clone and link (Bun ≥ 1.3.14)

    The CLI entry is TypeScript executed by bun; node cannot run it. bun link puts rovecode on PATH.

    $ git clone https://github.com/9Code-Labs/rovecode && cd rovecode && bun install && bun link
  2. 02

    Connect a model

    rovecode setup walks it: pick a provider, paste the key hidden, one tiny test call, done. Or store a key directly with rovecode auth set, or point ROVECODE_BASE_URL at any OpenAI-compatible endpoint.

    $ rovecode setup
    or
    $ rovecode auth set anthropic
  3. 03

    Run a task or open the cockpit

    Plain rovecode opens the sextant surface. A quoted prompt is a one-shot run; --output json returns exactly one result object.

    $ rovecode "fix the failing test"
    $ run · exit 0
    Run output: 18 pass, 0 fail, 41 expect() calls, Ran 18 tests across 1 files.
13
hosted apis
3
local runtimes

08providers

16 built-in providers, or any OpenAI-compatible URL.

Stored credentials beat <NAME>_API_KEY env vars; an explicit ROVECODE_BASE_URL / ROVECODE_API_KEY pair beats both.

hosted apis

local runtimes

  • kaesra
  • openai
  • anthropic
  • deepseek
  • groq
  • openrouter
  • together
  • mistral
  • cerebras
  • fireworks
  • perplexity
  • xai
  • moondream
  • ollama
  • lmstudio
  • vllm

● local runtimes need no key · rovecode auth set <name> stores a key in ~/.rovecode/credentials.json, prompted on the terminal and never echoed.

any endpoint · live

Add a provider in another terminal; the running cockpit picks it up on the next call. No restart.

$ rovecode provider add homelab http://10.0.0.7:8000/v1 --no-key
~/.rovecode/providers.json
{
"default": "kaesra/zai-org/glm-5.3-flash",
"providers": {
"kaesra": {
"baseUrl": "https://api.kaesra.tech/v1",
"protocol": "openai",
"keyEnv": "KAESRA_API_KEY"
},
"homelab": {
"baseUrl": "http://10.0.0.7:8000/v1",
"protocol": "openai",
"noKey": true,
"models": ["qwen3-coder-30b"]
}
}
}

09in their words

Teams that moved review into the terminal.

  • Review moved into the terminal and the approval card became the conversation. We ship the same amount with a third of the back-and-forth.

    Aylin Demirci

    Head of Platform · Northwind Robotics

  • The deny-default policy is the reason security signed off. Every tool call is a line in a log we already read.

    Marcus Oyelaran

    Staff Engineer · Harbourline Payments

  • Twelve people, local models, no vendor in the loop. It runs where our clients' code is allowed to run.

    Inés Ferrer

    Founder · Meridian Studio

Illustrative quotes from fictional teams, written for the page — real ones replace them before launch.

10pricing

Free to start. Priced for the team that ships.

Every plan runs the same agent behind the same deny-default policy. The plans differ in how much of it you run, and with whom.

  • Free

    For trying the agent on your own repositories.

    $0/ month

  • Pro

    For one engineer who ships with it every day.

    $20/ month

  • Max

    For the engineer whose week is spent inside it.

    $200/ month

  • Teams

    For a team that shares credits, knowledge and policy.

    $80/ month

    $80 minimum · $40 per full seat / month

See all plans

11faq

Objections, answered with specifics.

Seven questions people ask before they trust an agent with a shell. Each answer names the mechanism and where it stops.

Everything here is lifted from README.md sections Safety model, Known limitations, Observability and License & notices. Where the README says a limit exists, so does this page.

No. Four stacked layers run before and around every tool call: deny-default policy rules, execpolicy verdicts (a forbidden command never reaches execution or a human), the approval gate on revised args, and a runtime bash denylist with a cwd lock. Where bash runs is selectable, direct, WSL2 or Docker, but every rung is delegation, not isolation. Use a container or microVM for untrusted work.

12get rovecode

Six panels. Sixteen providers. Free to start, priced for teams.

$ git clone https://github.com/9Code-Labs/rovecode && cd rovecode && bun install && bun link
Rovecode, the cloud mascot, giving a thumbs up