7a93f83a month ago3 CommitsA 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).
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.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.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./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.Providers). Retries with exponential backoff are built in.~/.wynba/themes/*.json, switchable live with /theme.Requires a recent stable Rust (the crate uses the 2024 edition).
git clone <this-repo>
cd wynba
cargo build --release
# binary at target/release/wynba
Run the tests with:
cargo test
wynba
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.export OPENAI_API_KEY=..., and the
provider is ready to use immediately.Example one-shot use:
wynba "explain how the revert command works"
wynba chat -s 1 "continue"
wynba --session <uuid> "what did we change last?"
wynba [OPTIONS] [COMMAND] [MESSAGE...]
Global options:
| Option | Description |
|---|---|
--db <PATH> | Path to the SQLite database (default ~/.wynba/agent.db, or $WYNBA_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 ~/.wynba/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.
Inside the interactive TUI:
\+Enter — newline.| 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 |
/compact [focus] | Compact the session context (summarize older turns) |
/help | Show commands and key bindings |
/exit, /quit | Leave |
When the provider rejects a request because the history no longer fits its
context window, the agent auto-compacts — the older turns are folded into
a summary, exactly like /compact — and retries the turn once (mirroring
pi's overflow recovery). If the provider instead reports an output token
limit (finish_reason=length with no content, usually thinking eating the
whole budget), raise MAX_TOKENS or lower thinking effort with /effort.
Credential env vars (run wynba 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 16384).WYNBA_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
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.
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
~/.wynba/themes/*.json. Every field
is optional and falls back to the built-in default palette. Values are
6-digit hex strings (#rrggbb). Example:
{
"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.
~/.wynba/agent.db (override with
--db/WYNBA_DB). Holds sessions, messages, provider configs, file
backups, settings, per-session todos, and per-session goals.~/.wynba/themes/ plus the built-in palettes in
src/theme.rs.~/.wynba/backups/<session_id>/, used to undo a
turn's file changes when you revert.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
No license file is currently specified in this repository.