# coding-agent

A Rust coding agent with tool use and SQLite-backed sessions. It runs on your
machine, edits real files, searches your codebase, runs commands, spawns
sub-agents, and searches the web — all from a fast TUI (or plain REPL).

## Features

- **Terminal UI** — streaming markdown, tool-call blocks with diffs, a
  Grok-Build-style prompt editor with paste chips, image paste, a status bar
  and scrollable history. Falls back to a plain REPL when stdin isn't a
  terminal, and to a one-shot mode when you pass a message on the command line.
- **15 built-in tools** — `read_file`, `write_file`, `edit_file`,
  `delete_file`, `list_files`, `search`, `run_command`, `task` (sub-agents),
  `web_search`, `web_fetch`, `todowrite`, `todoread`, plus the goal tools
  `create_goal`, `update_goal`, `get_goal`.
- **Sub-agents** — the `task` tool can launch `general` (full tool access) or
  `explore` (read-only research) sub-agents with their own prompts, capped at a
  max nesting depth.
- **Todos** — opencode-style task tracking: `todowrite` creates/updates a
  structured per-session task list (`content`/`status`/`priority`, statuses
  `pending`/`in_progress`/`completed`/`cancelled`), `todoread` reads it back.
  Persisted in SQLite so the list survives compaction and relaunches.
- **Goals** — opencode-style long-running goals: `/goal <objective>` sets a
  goal and the agent keeps working across turns (tracking time used and
  iteration count) until it's `complete`, `blocked`, `paused`, or `cleared`.
  Manage it with `/goal status`, `/goal pause`, `/goal resume`, `/goal clear`;
  the agent itself uses `create_goal`/`update_goal`/`get_goal`. Goals are
  stored per session in SQLite.
- **Sessions** — every conversation and tool result is persisted to SQLite.
  Create, list, show, resume, revert, and fork sessions at any point in the
  history.
- **Many providers** — OpenAI-compatible APIs, Anthropic, Gemini, and Bedrock
  wire formats, plus a large registry of providers (see
  [`Providers`](#providers)). Retries with exponential backoff are built in.
- **Context management** — the message history sent to the model is bounded by
  round and byte budget so long, tool-heavy runs don't overflow the context
  window.
- **Steering** — queue follow-up messages (Alt+Enter) while the agent is
  running, or type to steer the running agent mid-turn; interruptions (Esc)
  restore the prompt editor.
- **File safety** — edits and writes are backed up per session so you can
  revert a turn (and its file changes) with one command.
- **Themes** — popular palettes built in (Dracula, One Dark, Gruvbox, Nord,
  Solarized, Tokyo Night, Catppuccin, Monokai, GitHub Dark, Rose Pine — each
  repaints the full UI including the background) plus custom themes in
  `~/.coding-agent/themes/*.json`, switchable live with `/theme`.
- **Images** — paste images from the clipboard (Ctrl+V) into your prompt on
  vision-capable models; stored per message and sent in each provider's native
  format.

## Installation

Requires a recent stable Rust (the crate uses the 2024 edition).

```sh
git clone <this-repo>
cd coding-agent
cargo build --release
# binary at target/release/coding-agent
```

Run the tests with:

```sh
cargo test
```

## Quick start

```sh
coding-agent
```

On first launch you'll get a new session. Connect a provider (interactively)
or set an API key as an environment variable, then chat:

- `/connect` — searchable provider picker, then enter credentials. Credentials
  are stored in the local database.
- or set the matching env var, e.g. `export OPENAI_API_KEY=...`, and the
  provider is ready to use immediately.

Example one-shot use:

```sh
coding-agent "explain how the revert command works"
coding-agent chat -s 1 "continue"
coding-agent --session <uuid> "what did we change last?"
```

## CLI

```
coding-agent [OPTIONS] [COMMAND] [MESSAGE...]
```

Global options:

| Option            | Description                                                |
| ----------------- | ---------------------------------------------------------- |
| `--db <PATH>`     | Path to the SQLite database (default `~/.coding-agent/agent.db`, or `$CODING_AGENT_DB`) |
| `--provider <N>`  | Provider to use (default from `$DEFAULT_PROVIDER`, else `openai`) |
| `--model <N>`     | Model name, overrides the provider default                 |
| `--session <UUID>`| Resume an existing session by UUID (REPL or one-shot)      |
| `--theme <NAME>`  | Theme name: a built-in palette (`default`, `dracula`, `one-dark`, …) or a `~/.coding-agent/themes/*.json` name |
| `-h`, `-V`        | Help / version                                             |

Subcommands:

| Command                  | Description                                        |
| ------------------------ | -------------------------------------------------- |
| `new [--name N] [MSG]`   | Create a new session (interactive or with a message) |
| `list`                   | List all sessions                                  |
| `show <SESSION>`         | Show the full message history of a session         |
| `chat [-s ID] [MSG]`     | Chat in an existing session (by numeric id) or create one |
| `delete <SESSION>`       | Delete a session and all its messages              |
| `connect`                | Interactively connect a provider                   |
| `providers`              | List providers and their credential env vars       |
| `resume`                 | List sessions and pick one to continue             |

`<SESSION>` accepts either a UUID or a numeric id.

## TUI usage

Inside the interactive TUI:

- **Enter** — send. **Shift+Enter** or **`\`+Enter** — newline.
- **Alt+Enter** — queue a follow-up message (delivered when the agent finishes).
- **Enter while the agent is busy** — steer it: the text is folded into the
  conversation before the next LLM call.
- **Esc Esc** — stop the current reply; Escape never quits the session.
- **↑/↓, mouse wheel** — scroll the history.
- **Ctrl+V** — paste text or an image from the clipboard (images on
  vision-capable models).
- Select a past user message to **revert** (restores its file changes too) or
  **fork** a new session from that point.

### Slash commands

| Command            | Description                                          |
| ------------------ | ---------------------------------------------------- |
| `/connect`         | Interactively connect a provider                     |
| `/model <name>`    | Switch model directly (or `/model` to pick from the provider's model list) |
| `/theme <name>`    | Switch theme directly (or `/theme` for a live preview picker) |
| `/new`             | Start a new session                                  |
| `/resume`          | Pick a saved session and continue it                 |
| `/import`          | Import a session from another agent harness (Claude Code, Codex, OpenCode, Pi, GrokBuild) |
| `/import <name>`   | Import from a specific harness (`claude-code`, `codex`, `opencode`, `pi`, `grokbuild`), `--last` for the most recent |
| `/redo`            | Restore the last reverted messages                   |
| `/goal <objective>`| Set a long-running goal the agent works toward across turns |
| `/goal status`     | Show the current goal                                |
| `/goal pause`      | Pause the goal (keeps it, stops auto-continue)       |
| `/goal resume`     | Resume a paused goal                                 |
| `/goal clear`      | Clear the goal                                       |
| `/help`            | Show commands and key bindings                       |
| `/exit`, `/quit`   | Leave                                                |

## Providers

Credential env vars (run `coding-agent providers` for the full list with
default models). The most common are:

| Provider        | Env var                  | Notes                                     |
| --------------- | ------------------------ | ----------------------------------------- |
| OpenAI          | `OPENAI_API_KEY`         | also `OPENAI_BASE_URL`, `OPENAI_MODEL`    |
| Anthropic       | `ANTHROPIC_API_KEY`      | also `ANTHROPIC_BASE_URL`, `ANTHROPIC_MODEL` |
| Google Gemini   | `GOOGLE_API_KEY` / `GEMINI_API_KEY` | also `GOOGLE_MODEL`              |
| Groq            | `GROQ_API_KEY`           |                                           |
| Mistral         | `MISTRAL_API_KEY`        |                                           |
| xAI (Grok)      | `XAI_API_KEY`            |                                           |
| DeepSeek        | `DEEPSEEK_API_KEY`       |                                           |
| Ollama          | *(none)*                 | defaults to `http://localhost:11434/v1`   |
| LM Studio       | *(none)*                 | defaults to `http://localhost:1234/v1`    |
| Amazon Bedrock  | `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY` | native Bedrock format |
| Google Vertex   | `GOOGLE_VERTEX_TOKEN`    | native Gemini format                      |
| Azure OpenAI    | `AZURE_OPENAI_API_KEY`   | full chat-completions URL                 |
| Compatible      | `COMPATIBLE_API_KEY` (optional) | any OpenAI-compatible endpoint     |

General settings:

- `DEFAULT_PROVIDER` — default provider name (default `openai`).
- `MAX_TOKENS` — max output tokens for the chat call (default `4096`).
- `CODING_AGENT_DB` — override the SQLite database path.

Each provider also honors `<PROVIDER>_BASE_URL` and `<PROVIDER>_MODEL` env vars
(see `resolve_provider` in `src/llm.rs`). The broad registry of additional
providers comes from [Mastra's provider registry](https://github.com/mastra-ai/mastra)
and is generated by `scripts/gen_providers.py` into
`src/llm/providers_data.rs` — don't edit that file by hand.

Model selection uses the provider's live `/models` endpoint when available and
falls back to the embedded registry.

## Theming

The agent ships with a set of **built-in popular palettes** — every one
overrides the full color map, so switching themes repaints the whole UI
including the full-screen background. Available out of the box:

`default`, `dracula`, `one-dark`, `gruvbox-dark`, `solarized-dark`, `nord`,
`tokyo-night`, `catppuccin-mocha`, `monokai`, `github-dark`, `rose-pine`,
`cursor` (a port of the Cursor editor's dark theme — near-black surfaces,
electric-blue `#4d9eff` accent for AI/highlights, and Cursor's exact diff
greens/reds).

On top of those, custom themes are JSON files in
`~/.coding-agent/themes/*.json`. Every field
is optional and falls back to the built-in `default` palette. Values are
6-digit hex strings (`#rrggbb`). Example:

```json
{
  "name": "rose",
  "accent": "#ff6b9d",
  "border": "#4a4a55",
  "user_bg": "#3a2b38",
  "md_green": "#b5bd68"
}
```

Available fields include `bg` (the full-screen interface background — like
Grok Build, the TUI paints its own background instead of inheriting the
terminal's), plus `border`, `accent`, `muted`, `dim`, `text`,
`user_bg`, `user_fg`, `tool_pending_bg`, `tool_ok_bg`, `tool_err_bg`,
`tool_title_fg`, `tool_call_fg`, `tool_args_fg`, `tool_out_fg`, `tool_err_fg`,
`diff_add_fg`, `diff_del_fg`, `diff_hunk_fg`, `diff_add_bg`, `diff_del_bg`,
`subagent_pending_*`, `subagent_ok_*`, `sel_bg`, `sel_fg`, `revert_bg`,
`revert_fg`, and `md_*` colors. Pick one with `/theme` (live preview) or set it
at launch with `--theme <name>`. The active theme is persisted in the settings
table.

## Storage

- **Database** — SQLite at `~/.coding-agent/agent.db` (override with
  `--db`/`CODING_AGENT_DB`). Holds sessions, messages, provider configs, file
  backups, settings, per-session todos, and per-session goals.
- **Themes** — `~/.coding-agent/themes/` plus the built-in palettes in
  `src/theme.rs`.
- **File backups** — `~/.coding-agent/backups/<session_id>/`, used to undo a
  turn's file changes when you revert.

## Project layout

```
src/
  main.rs        CLI, REPL/TUI loop, slash commands, session management
  agent.rs       agent loop: system prompt, tool rounds, steering, sub-agents
  tools.rs       tool definitions, execution, diff engine
  llm.rs         provider adapters, retries, model listing
  llm/providers_data.rs  generated provider registry (see scripts/)
  db.rs          SQLite schema and queries
  goal.rs        long-running goals: template, continuation prompt, statuses
  tui.rs         terminal UI: editor, streaming render, tool blocks
  md.rs          streaming markdown renderer
  theme.rs       color themes
scripts/
  gen_providers.py  regenerates src/llm/providers_data.rs from Mastra's registry
```

## License

No license file is currently specified in this repository.
