An AI coding agent for the terminal, built in Rust.
ragent is a Rust coding agent inspired by RooCode, Claude Code, Copilot CLI and OpenCode. It provides multi-provider LLM orchestration, a comprehensive built-in tool system, a terminal UI, and a client/server architecture β all compiled into a single statically-linked binary with zero runtime dependencies.
It is implemented in Rust as a learning exercise for the author.
Read TUI-QUICKSTART for instructions on how to use the tool.
- Multi-provider LLM support β Anthropic, OpenAI, Google Gemini, Hugging Face, GitHub Copilot, Ollama (local and cloud), Generic OpenAI-compatible endpoints, Azure AI Foundry, Azure Resource (File) provider, Amazon Bedrock, Microsoft Foundry Local, OpenRouter, and a Model Router cluster out of the box, with an extensible provider trait for adding more
- Local-first defaults β when no model is explicitly configured, ragent resolves to the first available local/self-hosted provider (e.g. Ollama) rather than hard-wiring a cloud provider
- Comprehensive tool system β 169 registered tools across 25 categories:
- File operations β read, write, create, edit, multiedit, apply_patch, patch, rm, move, copy, mkdir, append, file_info, diff, glob, list
- Shell β bash, bash_reset, open (7-layer security with safe-command whitelist,
banned commands, denied patterns, directory escape prevention, syntax validation,
obfuscation detection, and user allowlist/denylist)
- Bang commands β prefix any prompt with
!(e.g.! ls -la) to run a shell command directly; the output is sent to the model for review and error resolution - Search β grep
- Web β webfetch, websearch, http_request
- Browser automation β browser (Chrome DevTools Protocol: open, snapshot, click, type, fill_form, select, wait, eval, scroll, upload, press, screenshot, status, setup)
- Code intelligence β codeindex_search, codeindex_symbols, codeindex_references, codeindex_dependencies, codeindex_status, codeindex_reindex, codeindex_explain, codeindex_path, codeindex_communities, codeindex_godnodes (read-only, hardwired always-allowed)
- Memory β memory_read, memory_write, memory_replace, memory_store, memory_recall, memory_forget, memory_search, memory_migrate, conversation_search, session_search
- Teams β 20 tools for team lifecycle, tasks, messaging, and coordination
- GitHub & GitLab β 29 native VCS tools for issues, PRs/MRs, pipelines, CI/CD, and repository management
- Office & PDF β office_read/write/info, libre_read/write/info, pdf_read, pdf_write
- Sub-agents β new_agent, cancel_agent, list_agents, wait_agents, agent_complete
- Planning β plan_enter, plan_exit
- MCP β mcp_tool (McpToolWrapper) for external Model Context Protocol servers
- Task Management β task_create, task_update, task_get, task_list
- Interactive β question, think
- Utility β calculator, get_env, ragent_info (reports the running version, build time, git commit, and compiler)
- Stocks & currency β stock_quote, stock_history, stock_fundamentals,
stock_search, stock_options, currency_rate, currency_history. Free Yahoo
Finance is the default; Alpha Vantage can be configured in
ragent.json. - Plotting β plot_line, plot_scatter, plot_bar, plot_histogram,
plot_pie, plot_heatmap render ASCII-art graphs (with ANSI colours)
inline in the message window via
ratatui-plt - Code search & navigation β codeindex_search, codeindex_symbols, codeindex_references, codeindex_dependencies, codeindex_status, codeindex_reindex
- MasterFetch β mf_fetch, mf_search, mf_crawl, mf_cache_clear for web content
extraction, search, and crawling;
mf_searchruns DuckDuckGo, Brave, OpenAlex (scholarly works), and Wikipedia (encyclopedia summaries) keyless backends in parallel, plus optional LangSearch / Tavily / Perplexity / Exa API-backed engines when configured - Gmail & messaging β gmail, send_channel_message for external notifications
- Bang commands β prefix any prompt with
- Terminal UI β full-screen ratatui interface with provider setup dialog,
slash-command autocomplete, agent cycling, streaming chat with markdown and syntax
highlighting, step-numbered tool calls with pretty-printed JSON in the log panel,
a live permission countdown timer (120-second timeout with EXPIRED state), and a
message input queue (
Alt+Qmenu //queue) that keeps the input field editable while the agent executes - HTTP server β axum-based REST + SSE API so any frontend can drive the agent
- Session management β persistent conversation history stored in SQLite; list, resume, export, and import sessions
- Permission system β multi-layered defense-in-depth with hardwired rules (codeindex tools always allowed), configurable allow/deny/ask rules, 7-layer bash security, file-path guards, and YOLO mode for trusted environments
- Agent presets β general, coder, task, architect, ask, debug, code-review, and orchestrator agents with tailored system prompts
- Custom agents β user-defined agents via JSON (OASF format) or Markdown profiles
- Project guidelines β auto-loads
AGENTS.mdfrom the project root (and~/.local/share/ragent/) into the system prompt so agents follow project-specific conventions - MCP client β Model Context Protocol support with auto-discovery of 9 known
server types, stdio client, and tool bridging; TUI commands (
/mcp//mcp status,/mcp discover,/mcp connect <id>,/mcp disconnect <id>) with durable global enable/disable state (mcp_state.json) and live connect/disconnect - Snapshot & undo β file snapshots before edits so changes can be rolled back
- Event bus β internal tokio pub/sub for real-time UI updates across all components
- Background agents β spawn and run multiple sub-agents concurrently for parallel
task execution, with REST API and TUI monitoring;
/spawn <agent> <prompt>launches a detached fire-and-forget sub-agent that nothing ever waits on (nolist_agentsentry, not awaitable viawait_agents, result never injected into the chat); every completed sub-agent run (detached or not) also writes its FULL output tolog/subagents/<task-id>.md, and the completion event carries the real loopfinish_reason(stop/truncation/length/cancelled/error) so a provider-side cut is flagged in the Agents panel instead of looking like a healthy finish - Prompt inspector β
/promptrenders the assembled system prompt an agent would receive (primary or subagent mode, per-agent override, roster) with the effective tool surface β read-only, no LLM call - Tool-repeat guard β after five consecutive identical tool calls the sixth is held for confirmation in interactive runs and auto-denied in unattended runs, so agent loops cannot hang replaying the same call (FR-044)
- Code index β automatic codebase indexing with tree-sitter parsing (15+ languages),
full-text search via Tantivy, incremental updates via file watcher, and LLM-accessible
tools; supports Rust, Python, TypeScript/JavaScript, Go, C/C++, Java, OpenSCAD,
Terraform, CMake, Gradle, and Maven; enable/disable via
/codeindex on|off, language filtering via/codeindex lang <language>; semantic code graph withcodeindex_godnodes(top-N most-connected symbols),codeindex_path(shortest path between symbols),codeindex_explain(node metadata and edges), andcodeindex_communities(community detection); graph built in the background via/codeindex graph build(phased lock discipline keeps search available during derivation; status-baridx/graphbusy indicators show progress) - Memory system β three-tier system with file blocks, structured SQLite store, and optional embedding-based semantic search; automatic extraction, decay, compression, and knowledge graph support
- Spec management β
/specslash commands for creating, listing, searching, validating, and tracking specification lifecycles;/spec jtbdperforms Jobs-To-Be-Done analysis on existing specs;/spec updateregeneratesPLAN.mdandTESTPLAN.mdfrom an editedSPEC.md;/spec createnow also emits a manualTESTPLAN.mdtest-plan artifact - GitHub repo reverse-engineering β
/spec reverse <owner/repo | URL>fetches a public repo's metadata, root file tree, and README via the GitHub API, then asks the currently selected LLM model to generate a synthetic creation prompt; the/newscaffold flags (--language <lang> --type <type> [--stack <name>]) steer the prompt towards a target language, app type, and framework stack, and with those flags--folder <path>scaffolds a real project (default: the current directory) while--github/--gitlabcreate a private remote and push it;--create <name>chains into/spec createto auto-generate a spec from the reverse-engineered prompt, written under the scaffolded project (<folder>/specs/<name>/) when--folderwas used - Project scaffolding β
/new --language <lang> --type <type>scaffolds a new project in an empty directory: the ragent workspace (.ragent/,specs/,log/,.gitignore,AGENTS.md), a runnable hello-world artifact set for 26 application languages (rust, python, go, typescript, shell, ...) with library/cmdline/tui/gui layouts (plus a webapp HTTP server for the five web languages) plus sample-document stubs for 20 data, markup, and build formats (json, yaml, sql, cmake, maven, ...) covering every codeindex scanner language, optional stack layers (--stack axum), starter docs (README.md,QUICKSTART.md,STATS.md,docs/), git init + initial commit, and optional GitHub/GitLab remote creation + push (--github/--gitlab); progress streams live in the message window; also available as theragent newCLI subcommand - Research system β
/researchslash command family andragent researchCLI for structured information gathering (web search + local file cross-referencing) with self-containedRESEARCH.mdoutputs andGET/POST/DELETE /researchHTTP endpoints; concept/finding output limits (--max-concepts/--max-findings,research.max_concepts/research.max_findings), scholarly-engine exclusion (--no-papers, alias--no-scholarly,research.exclude_academic_engines), open-access toggles (--oa-enable/--no-oa), URL cloaking (--url-cloak) that defangs web source URLs in theSourcesbullets andReferences Indexso scanners do not flag them, a per-engine progress table that breaks exclusions and fetch failures out by reason/cause, andmf_searchexclude_engines - Skills system β loadable skill packs (bundled or custom YAML) that inject tools, prompts, and file context into agent sessions
- Plugin system β load Codex-dialect (
codex-plugin.jsonor the nested.codex-plugin/plugin.jsontheopenai/pluginsstore ships) and Claude Code/Desktop-dialect (.claude-plugin/plugin.json) plugins β including multi-target trees that ship both nested manifests side by side (e.g.mongodb/agent-skills), which resolve to the Claude dialect β run their JavaScript entries on an embedded, budget-sandboxed engine (rquickjs, no Node/Deno required) behind a versionedragenthost API, and register their tools (plugin_<id>_<tool>) and slash commands; skill-only/MCP-only plugins (no JavaScript entry) install and load inertly, and theirskillsdirectories andmcpServersentries are bridged into the session (plugin skills join the skill-discovery roots; plugin MCP servers connect as<plugin-id>.<server>); a plugin's slash commands are bridged too, including the Claudecommands/*.mdprompt commands (each injected as a user turn with$ARGUMENTSsubstituted), registered under their bare name or the namespacedplugin:<id>:<name>trigger and listed in the/menu and/help; pluginagents/*.mdprofiles join agent discovery (YAML frontmatter accepted, project agents win name clashes), and plugin-declaredhooksfire on the matching session lifecycle events (bothpre_tool_useand Claude'sPreToolUsespellings accepted; thehooks.jsonfile and the group{matcher, hooks: [...]}shape are read, a plugin hook getsCLAUDE_PLUGIN_ROOTand the Claude event JSON on stdin, and a blocking Stop hook can feed findings back before the turn ends);/plugins codexand/plugins claudebrowse each store's official marketplace (StoreProvidernormalises the Codex and Claude document shapes), and/plugins addalso accepts agit+<https-url>#<ref>[:<subpath>]git source; a freshly installed plugin is recorded enabled and loads at the next session start (no JavaScript runs during the install); managed through/plugins list|add|remove|enable|disable|test|stores|helpin the TUI and theragent plugins <sub>CLI;plugins.enabled: falsemakes the subsystem inert - Input queue β the TUI input field stays editable while the primary agent
executes: each
Enterappends the message to a bounded FIFO queue (default 32 entries, configurable viainput_queue_capacity), a two-digit counter appears before the prompt, and the oldest entry runs at each turn boundary; control it with theAlt+Qmenu (Next/Stop/Clear/Show, navigated withUp/Down/Enter) or/queue [list|clear|next|help]; theShowrow opens a scrollable panel of the queued entries whereEntermoves the highlighted entry one step toward the front andDelremoves it - Teams & Swarms β multi-agent coordination with named teammates, shared task lists,
mailbox messaging, and swarm decomposition for parallel work (
/swarm <prompt>) - Autopilot mode β autonomous operation with configurable iteration limits and
permission auto-approval (
/autopilot on [--max-tokens N] [--max-time N]) - Config error reporting β actionable JSON parse diagnostics showing file path, line, column, problematic source line, and caret marker
git clone https://github.com/thawkins/ragent.git
cd ragent
cargo build --release
# Binary is at target/release/ragentRequires Rust 1.85+ (edition 2024).
# Configure an API key
export ANTHROPIC_API_KEY="sk-..."
# or
export OPENAI_API_KEY="sk-..."
# or (for Azure AI Foundry)
export AZURE_AI_FOUNDRY_API_KEY="sk-..."
# or (for Generic OpenAI API provider)
export GENERIC_OPENAI_API_KEY="sk-..."
# or (for OpenRouter)
export OPENROUTER_API_KEY="sk-or-..."
# Launch the interactive TUI
ragent
# Run a one-shot prompt
ragent run "Explain this codebase"
# Start the HTTP server only
ragent serve --port 9100Use OpenRouter models directly from the CLI:
ragent run --model openrouter/anthropic/claude-sonnet-4 "Refactor this function"Generic OpenAI-compatible endpoint (including custom port) can be configured in
ragent.json:
{
"provider": {
"generic_openai": {
"env": ["GENERIC_OPENAI_API_KEY"],
"api": { "base_url": "http://127.0.0.1:8080" }
}
}
}ragent [OPTIONS] [COMMAND]
Commands:
run Execute agent with a prompt
serve Start HTTP server only
session Manage sessions (list, resume, import, export)
auth Configure provider authentication
models List available models
config Show resolved configuration
new Scaffold a new project in the current directory
plugins Manage plugins (the `/plugins` slash-command parity surface)
Options:
--model <MODEL> Override model (provider/model format)
--agent <AGENT> Override agent [default: coder]
--log-level <LOG_LEVEL> Log level [default: warn]
--no-tui Disable TUI, use plain stdout
--yes Auto-approve all permissions
--config <CONFIG> Path to config file
ragent reads configuration from ragent.json (or ragent.jsonc) in the .ragent/
directory, with fallback to ~/.config/ragent/config.json. The format is compatible
with OpenCode's opencode.json.
See the full configuration schema in SPEC.md.
You can define your own agents as JSON files using the Open Agentic Schema Framework (OASF) standard. Place them in:
~/.ragent/agents/β user-global (all projects)~/.config/ragent/agents/β user-global (all projects; XDG config location, takes priority over~/.ragent/agents/).ragent/agents/β project-local (this project, highest priority)
ragent loads them automatically at startup. Use /agents to list loaded agents
and view diagnostics, or /agent to open the interactive picker (custom agents
are marked with a yellow [custom] badge).
See docs/custom-agents.md for the full schema
reference, template variables ({{WORKING_DIR}}, {{FILE_TREE}}, {{AGENTS_MD}},
{{DATE}}), permission rules, and worked examples. Ready-to-use example files
are in examples/agents/.
Scaffold a brand-new, agent-friendly project in an empty directory with one command:
# TUI
/new --language rust --type cmdline
# CLI
ragent new --language rust --type cmdlineThe command validates the directory is empty, generates the ragent workspace
(.ragent/, specs/, log/, .gitignore, AGENTS.md), a runnable
hello-world artifact set for rust/python/go/typescript in
library/cmdline/tui/gui/webapp layouts, starter documentation (README.md,
QUICKSTART.md, STATS.md, docs/), initialises git with an initial
commit, and β with --github or --gitlab β creates a private hosting
repository, sets it as origin, and pushes.
# Add a framework stack (Rust: axum, warp, raylib, gtk4, ratatui)
ragent new --language rust --type cmdline --stack axum
# Create the project on GitHub or GitLab (mutually exclusive)
ragent new --language python --type library --gitlabSee docs/howtos/newproj.md for the full manual.
Teams let one lead session coordinate multiple teammates with shared tasks and mailbox messaging.
Quick flow:
- Create a team:
/team create <name>(orteam_create) - Re-open an existing team:
/team open <name> - Spawn teammates:
team_spawn - Add/list/claim/complete tasks:
team_task_create,team_task_list,team_task_claim,team_task_complete - Communicate:
/team message ...orteam_message, plusteam_read_messages - Reset/close/delete team state:
/team clear,/team close,/team delete <name> - Cleanup when finished:
/team cleanuporteam_cleanup
Docs and examples:
- Guide:
docs/userdocs/TEAMS.md - How-to manual:
docs/howtos/teams.md - Example bundles:
examples/teams/
The project is a Cargo workspace built from 17 focused crates:
| Crate | Purpose |
|---|---|
ragent-agent |
Agent/runtime layer: sessions, orchestration, MCP, memory, tool registry |
ragent-bench |
Benchmark runner shared between TUI and CLI |
ragent-codeindex |
Codebase indexing: tree-sitter parsing, SQLite store, Tantivy FTS, file watcher |
ragent-config |
Configuration types, defaults, and parsing |
ragent-llm |
Provider clients and model/provider registry (Anthropic, OpenAI, Gemini, Ollama, HuggingFace, Copilot, Generic OpenAI, Azure AI Foundry, Azure Resource, Amazon Bedrock, Microsoft Foundry Local) |
ragent-plugins |
Plugin system: Codex/Claude dialect manifests, sandboxed JS runtime, lifecycle, /plugins surface |
ragent-research |
Research system: web/local gathering, synthesis, RESEARCH.md output |
ragent-server |
Axum HTTP routes and SSE streaming |
ragent-specs |
Spec lifecycle management: discovery, validation, status transitions, review, archival, JTBD analysis |
ragent-storage |
SQLite-backed storage, snapshots, encrypted credentials |
ragent-team |
Team coordination runtime and team tools |
ragent-telemetry |
OpenTelemetry instrumentation and OTLP export |
ragent-tools-core |
Core shell/file/search tools |
ragent-tools-extended |
Extended document/web/memory/codeindex/plot tools |
ragent-tools-vcs |
GitHub and GitLab tool surface |
ragent-tui |
Ratatui terminal interface |
ragent-types |
Shared IDs, events, messages, and sanitization primitives |
The binary entry point (src/main.rs) wires these crates together behind a clap CLI.
User Input
β
βΌ
ββββββββββββ ββββββββββββββββ ββββββββββββββββ
β TUI βββββΊβ Event Bus βββββΊβ HTTP Server β
ββββββ¬ββββββ ββββββββ¬ββββββββ ββββββββ¬ββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββ
β Session Processor β
β (agent loop β LLM call β tool execution) β
ββββββββββββββββββββ¬βββββββββββββββββββββββββββ
β
βββββββββββΌββββββββββ
βΌ βΌ βΌ
βββββββββββ ββββββββ ββββββββββ
βProvider β βTools β βStorage β
β(LLM API)β β β β(SQLite)β
βββββββββββ ββββββββ ββββββββββ
Criterion benchmarks currently ship with ragent-tui, ragent-server, and
ragent-codeindex. See docs/performance/benchmark-guide.md
for full instructions.
# Run crate benchmarks
cargo bench -p ragent-tui
cargo bench -p ragent-server
cargo bench -p ragent-codeindexKey optimisations in the current release:
- DashMap replaces
RwLock<HashMap>in the orchestrator, reducing lock contention - LRU file-read cache (256-entry, mtime-keyed) avoids redundant disk I/O
- Rayon parallel glob walk for large directory trees
- Incremental snapshots store only changed files (via
similardiffs) - Async storage writes via
tokio::task::spawn_blockingkeep the executor free
v1.0.119 β The core architecture, tool system (169 tools across 25 categories), TUI, HTTP server, memory system, teams/swarm coordination, spec management, skills system, research system, plugin system, and multi-layered security are functional and under active development.
Recent highlights:
-
MCP transport/session fixes + simplify sweep (v1.0.119) β a sessionful Streamable-HTTP MCP server now reports its tools:
HttpMcpClientperforms aninitializehandshake, replays the returnedmcp-session-id, advertisestext/event-stream, and unwraps SSE frames, andMcpClient::adopt_connectedadopts an already-running server through that client. The HTTP client is built lazily so it no longer panics outside a Tokio runtime. The TUI prints a per-server MCP startup report (with the declared transport on every line and a 3-second connect grace),/plugins listresolves live MCP tool counts, and/plugins list --mcpsorts server ids for a deterministic contributions block. A/simplify allpass over the recent MCP/swarm/plugins work fixed a progress-bar overflow in/swarm status, a pending-marker race in/spawn, and--mcpflag handling on non-list/pluginssubcommands. -
Durable MCP server enable/disable + plugin-bridged servers (v1.0.118) β whether an MCP server is started is now a persisted choice (
<global state dir>/mcp_state.json) rather than an implicit effect of being listed inragent.json; a server absent from the ledger is enabled, andmcp.<id>.disabled: truealways wins./mcp connect <id>//mcp disconnect <id>enable/disable a server live and the choice survives a restart;/mcplists plugin-contributed servers with their liveenabledstate and tool count, and/plugins listgainsMCP/MCP Toolscolumns. PluginmcpServersentries are bridged as<plugin-id>.<server>by default./toolsnow also lists the tools a visibility switch has hidden. -
/spec reverse --folderscaffolds and hosts the target project (v1.0.117) β/spec reversenow accepts--folder <path>plus--github/--gitlab(with the/newscaffold flags present) and creates the project in the target folder before synthesising the prompt; a chained--create <name>writes the spec into<folder>/specs/<name>/. Usage errors now state the specific cause instead of the bare usage line. -
webappapp type (v1.0.117) β--type webappis a first-class registered value for/new,/spec reverse, and/spec govcreate; it generates a tiny dependency-free HTTP-server starter forrust,python,go,typescript, andjavascript, and degrades to a manifest-only layout elsewhere. -
lopdfjoins the lint suite (v1.0.117) β the vendoredlopdfcrate carries crate-level allowances (matchingvendor/pdf-extract) so the dead-code lint andcargo-macheteare green. Full CI hygiene (cargo check, the dead-code lint and reason checks,clippy -D warnings,cargo fmt --check,cargo audit,cargo deny check) and the entirecargo test --workspacesuite are green. -
Detached sub-agents +
/spawn(v1.0.115) β/spawn <agent> <prompt...>launches a sub-agent directly from the chat input as a detached fire-and-forget task: it runs concurrently and shows in the Agents panel, butlist_agents/wait_agentsnever see it and its result is never injected back into the chat. Every completed sub-agent run (detached or not) now persists its FULL output tolog/subagents/<task-id>.md, and the completion event carries the real loopfinish_reason(stop/truncation/length/cancelled/error), so a provider-side cut is flagged in the Agents panel instead of looking like a healthy finish. Thenew_agenttool gained the matching optionaldetached: trueparameter. Spec:specs/spawnagent/. -
Plugin bridges (v1.0.114) β plugin bridges for skills, MCP servers, slash commands, agents, and hooks (including the full Claude
hooks.jsondeclaration surface, a.codex-plugin/plugin.jsonrecogniser, and the both-nested multi-target descriptor fix); the GitHub credential chain now has a sharedragent_config::githubresolver with aghCLI fallback and an app-token downgrade, so/new --githubcreates a hosting repository even when/github loginstored aghu_token; the input field queues slash commands while the agent runs; and a new read-onlyragent_infotool reports the running version, build time, git commit, and compiler (169 tools). -
Store providers + plugin-store installs β
/plugins codexand/plugins claudenow browse the stores' own official marketplaces (openai/pluginsandanthropics/claude-plugins-official). AStoreProvidertrait with per-store Codex and Claude implementations normalises each vendor document shape (name-as-id, optionalversion,local/url/git-subdir/repo-relative sources) into the internal model, and the store kind is threaded through the fetch seam so every fetch parses with the right provider. A repo-relative source resolves against the origin's GitHub repository as an installablegit+<repo>#<ref>:<path>source, and the install pipeline accepts agit+<https-url>#<ref>[:<subpath>]source via a shallow, sparsegit clone, so a plugin hosted in a subdirectory of a large repository installs without downloading the whole tree. -
Message input queue (v1.0.113) β the TUI input field stays editable while the primary agent executes: each
Enterqueues the message in a bounded FIFO (default 32,input_queue_capacityconfig, clamped1..=99) with a two-digit counter before the prompt, and the oldest entry runs at each turn boundary. AnAlt+Qqueue-control menu (Next/Stop/Resume/Clear/Show, navigated withUp/Down/Enter) and a/queue [list|clear|next|help]slash command expose the same queue; aYes/Nodialog (defaultNo) guards clearing, and theShowrow opens a scrollable queue-entry panel whereEntermoves an entry one step toward the front andDelremoves it. A slash command (/β¦) is queued the same way while a turn runs (FR-017 amendment) and runs at the next turn boundary; only bang commands (!β¦) and teammate-targeted sends keep the busy refusal. Specinputqueuecomplete (T-001..T-027), 19 new test files (234 new test attributes). This release also lands the full-workspace clippy hygiene pass: the non-existentclippy::assert_is_emptyallow is removed from 244 files and the--all-targetsclippy gate is now clean. -
Plugin system (v1.0.112) β the plugin system goes from spec draft to full implementation: the new
ragent-pluginscrate (234 tests) discovers and normalises Codex- and Claude Code/Desktop-dialect manifests, runs plugin JavaScript on a budgeted embeddedrquickjsengine behind the versionedragenthost API, registersplugin_<id>_<tool>tools and slash commands, and drives the/pluginssix-subcommand family plus theragent pluginsCLI parity surface. Apluginsconfig block (enabled, budget limits,store_dir, per-plugin permissions) with overlay-wins merge, eight acceptance/fixture plugins underassets/plugins/fixtures/, and a code-quality cleanup pass (sharedScratchSurface/store_and_config, singlehelp::attributionheader source, surfaced config-load warnings, hoisted prefix allocation) complete the change set. -
Release mechanism fix (v1.0.111) β the release workflow's changelog extractor now matches the Keep a Changelog
## [<version>] - <date>header form (plus the two legacy forms), so GitHub releases carry their notes; the v1.0.107..v1.0.110 releases were backfilled. -
TUI paint-safety fix (v1.0.110) β
should_rendernow paints a pending message-cache group at the safety interval, closing the PERF-042 throttle-tail stall where a tool-call row stayed invisible while the status bar showed it running (regression testtest_pending_message_cache_group_forces_safety_paint), plus dependency and advisory hygiene (dropped unuseddirs/tokio/tempfiledependencies; removed four staledeny.tomladvisory ignores). -
/simplifyfinal phase over v1.0.106..v1.0.108 (v1.0.109) β the last code-quality findings from the three-commit review window land: deadutf8_prefix_lenhelper removed from the LLM HTTP client (FUNC-033 made it redundant),config_agents_dircollapsed intoglobal_agents_dir,extract_http_statusparses status digits byte-wise without an intermediate allocation, andragent-research's eight poisoned-lock sites now share onelock_conn()helper with a dedicatedSourceVaultError::LockPoisonedvariant. -
Config rules and fixes (v1.0.108) β code-quality pass over the v1.0.105..v1.0.107 window from five parallel explore reviews: GitLab legacy credential migration scans the real legacy
~/.ragent/root again (silent no-op migration fixed, regression test pinned), the team-blueprint "global" fallback restores the true legacy~/.ragent/blueprints(/teams)scan so old installs keep working, the four/spec govcreatemutex-lock sites uniformly recover poisoned locks,/config showrenders unavailable global dirs as "(unavailable)",acquire_localno longer misreports an exact-cap natural completion as budget exhaustion, and shared research helpers (num_prefix_re,join_text) are deduplicated into single copies. -
/spec govcreateβ spec authoring from an architecture document (v1.0.107) β/spec govcreate <spec-id> <content-ref> <target-folder>(and theragent spec govcreateCLI subcommand) acquires an architecture document from a local folder or URL, extracts its content, authorsSPEC.md/PLAN.md/TESTPLAN.mdvia the configured LLM, and writes a new spec β with staged[ .. ]/[ ok ]/[fail]progress in the TUI, Escape cancellation, and an FR-011 guard that refuses non-empty targets without--force. The same window carries HEAD~3 review fixes: SSE chunk coalescing no longer splits multi-byte UTF-8 sequences driven byUtf8Error::error_len()(with six regression tests), secret redaction captures key+separator and widens the value charset to base64/base64url, spec dependency-range expansion is capped at 1000 IDs,delete_memories_by_filterreports real row counts, and masterfetch's cache deletes corrupt rows instead of poisoning hits. Documentation: the 612-linetools.mdis replaced by 26 per-category how-tos indocs/howtos/tools/with argument tables and examples, each with a generated PDF. -
--url-cloakresearch source defanging (v1.0.106) β/research creategained--url-cloak, which emits web source URLs as defanged plain text rather than clickable links: the scheme is rewritten (https://->hxxps://,http://->hxxp://), every dot is bracketed (example.com->example[.]com), and the result is wrapped in a Markdown code span. It applies to the**Sources:**bullets under each finding and theReferences Indextable inRESEARCH.md(plus theSources Referencetable inCORPA.md), leaving non-URL rows untouched, so automated URL scanners do not flag the document. Available on the root CLI, the TUI slash command, andPOST /research(url_cloak), recorded in frontmatter (url_cloak: true) for/research updatereplay, and off by default. A follow-up/simplifypass over the change set tightenedSourceVault/GatherLogblocking offloads (sharedrun_blockinghelper, newSourceVaultError::TaskPanic), defanged thecloak_urlnon-URL fallback, hardenedextract_http_statusagainst "500ms"/"404 bytes" false positives, and foldedassemble_and_write's 18 parameters into oneAssembleInputstruct; the how-to manuals were rebuilt to PDF. -
Research output limits, scholarly-engine exclusion, and progress-table detail (v1.0.105) β
/research createcaps its## Concepts/## Findingslists at 5 / 20 by default, reordering most-relevant-first (highest cited source rank, then cited count) before truncation; the limits are set with--max-concepts N/--max-findings Non the root CLI, TUI, andPOST /research(max_concepts/max_findingsfields), or persistently viaresearch.max_concepts/research.max_findings(0= unbounded).mf_searchgained anexclude_enginesarray that drops named backends before any request is dispatched, and research--no-papers(alias--no-scholarly, configresearch.exclude_academic_engines) routes through it so OpenAlex consumes no search budget and cannot shadow general-web URLs in dedup.POST /researchgainedno_scholarly;--oa-enable/--no-oatoggle open-access recovery per run. The per-engine progress table now shows why candidates were dropped (five exclusion-reason columns) and how fetches failed (seven failure-kind columns)./spec implnow expands task-range Dependencies cells (T-001βT-014) into every spanned ID, the TASKS panel shows the task ID after the status, and every toggled right-hand side panel takes 50% of the window width. -
Functional anti-pattern remediation β FUNCPLAN.md (FUNC-038..069, 080..082) complete (v1.0.104) β the second pass closes the plan's M1 tail and all of M2-M5:
mf_searchkeyless engines now surface a dead engine as an error instead of a zero-result success;github_merge_prrejects an unknown merge method instead of silently merging; the last three production poison-lock panics recover viaPoisonError::into_inner; GitLab GETs retry429honouringRetry-Afterwith bounded request/entry budgets and full pagination;move_filerenames first (no orphan dirs),copy_filerefuses a self-copy,append_fileflushes; GitHubpost/put/patchhonourbase_url; percent-encoding is byte-wise (UTF-8 correct) across GitHub/GitLab; codeindexparent_idresolves multi-level nesting to a fixpoint; the keyword verifier no longer passes an empty/uncited analysis; the server auth comparison hashes fixed-length digests and the rate limiter enforces exactly 60/min; and a newscripts/check-poison-locks.shguard is wired intopre-flight.shand CI. -
M1 agent per-turn hot path β PERF-032..040 + PERF-048 complete (v1.0.103) β the per-turn allocation and clone load in the agent loop is removed: the provider-facing transcript is held and handed out behind an
Arc<Vec<ChatMessage>>(no per-turn deep clone), a pure history append converts only the new tail (SessionState::take_cached_for_append), the subagent tool surface is cached behind the tool-registry version,LoopTrackerisCopy, a newRequestTokenTrackermakes the per-step token estimate O(changed message) instead of O(history), tool/result pairing is a single pass, the compaction prompt is assembled into one buffer, memory-entry token costs are memoised, the activity log is written by one background task per process, and the TUI viewers retain a single copy of their rendered rows. New benchesturn_loop/m3_hot_paths; new guardstest_activity_writerandtest_no_percall_regex.rustlsbumped 0.23.43 -> 0.23.45 (RUSTSEC-2026-0285). -
Simplify/quality pass across the search, research, agent, and TUI crates (v1.0.102) β the second
/simplifysweep deduplicated the API-key search engines behind shared preflight/finish/mask helpers, made engine-merge output deterministic with renumbered positions, resolved the web-gatherer volume policy through onevolume_policy()helper, and removed the vestigial deadline flag. A third pass (v1.0.101) followed the same pattern acrossmasterfetch::searchandragent-research. -
Serper search engine, mf_search resilience, and research webgather cleanups (v1.0.100) β
mf_searchgained a fifth optional API-backed engine (Serper, Google search) alongside LangSearch / Tavily / Perplexity / Exa, configurable viaserper_api_keyinragent.json; transient engine failures (Wikipedia 429, HTTP 5xx, transport timeouts) are now retried inside the engine call path with exponential backoff (2 retries, 1 s/2 s), account-level quota blocks are reported asblocked_engineswith reasons instead of retried, and the orchestrator staggers engine starts by 120 ms so keyless backends no longer burst at t=0 (this fixes the "only LangSearch results"/websearch searchsymptom). The research web-gatherer no longer cancels in-flight fetches at the--web-timephase deadline (every candidate is fetched to completion; the deadline bounds only the search stage) and the consecutive-failure search circuit breaker was removed in favour of the H-002 retry policy./researchgained an interactive clarification gate in the TUI. -
/promptinspector, tool-repeat guard, redundant command removal (v1.0.96) β the new read-only/promptslash command renders the assembled system prompt an agent would receive (primary or subagent mode, roster, per-agent override) with its effective tool surface; a tool-repeat guard (FR-044) blocks agent loops stuck replaying the same tool call (sixth identical call prompts in interactive runs, auto-denies in unattended runs); and the redundant/opt(plus itsragent-prompt_optcrate andPOST /optendpoint),/tasks, and/themeslash commands were removed, returning the workspace to 16 crates. -
AgentNotice chat-bubble separation + /toolchain fixed-width table (v1.0.94) β consecutive
AgentNoticenotices now render as their own yellow bubbles (the TUI event handler forces a new assistant message before and after each notice), and the/toolchain listtable switched to fixed 10/10/10/50 character columns (Language/Runtime clip, Status and Version word-wrap onto continuation grid lines) at a constant 93-column width. Released in v1.0.95 with the docupdate pass. -
Spec-impl tracker semantics + sub-agent completion hard requirement + compaction performance pass (v1.0.93) β
/spec implno longer pre-creates session tracker tasks (spec_task_updatenow creates-or-updates them, seeded from the spec'sPLAN.md), the sub-agent completion protocol is a mandatory hard requirement enforced in the system prompt, theagent_completetool description, and the mid-run summary nudge, and compaction gained acompaction.modelfast/cheap summariser override for/compact, configurablesummary_tokens(1500) /tool_output_max_chars(2000), an adaptive prompt cap, 180 s / 60 s stream caps with chunk-level cancellation, and an allocation-free token estimator. -
Subagent interactive-tool blocking (v1.0.92) β sub-agent runs now deny
ask_userwith a corrective observation instead of stalling the run on an unbounded user-answer wait; a shareddenied_tool_callhelper covers all tool-call denial paths. -
Scaffold + status-bar simplify pass (v1.0.90) β the
/newTUI command and theragent newCLI subcommand now share oneplan_and_emit()pipeline in theproject_scaffoldengine module (each surface attaches only its own git/hosting outcome lines), the GitHub/GitLab remote flows share aregister_origin_and_pushhelper, and the status-bar last-prompt renderer is single-pass. No behaviour change; ~135 duplicated lines removed across the scaffolder and status bar. -
Research-crate simplify pass (v1.0.88) β a
/simplifyaudit over allragent-researchsources fixed aparse_subject_summaryslice panic (}-before-{responses no longer panic the analysis merge path), madeAnalysisEngine::with_briefa required trait method, cached hot regexes behindOnceLockstatics, deduplicated the twoRESEARCH.mdlayout assemblers into a shared section-emitter module, unified search-engine ordering across gather paths, and consolidated per-page media-type classification and pdf/youtube tallies into single passes. -
UI polish and tool-calling fixes (v1.0.87) β the status bar's top line now renders the last submitted prompt as a centred bracketed tag (first 32 characters,
....when truncated) between the git branch and the session status, with the working directory shortened to fit and a graceful fallback to the previous layout when the terminal is too narrow; the message window no longer pushes the transcript down with a leading blank line before the first "You:" prompt; and thetext_toolcallsrecovery helpers were tightened topub(crate)visibility. -
Spec-system documentation and semantics polish (v1.0.86) β the
/spechow-to manual now documents the spec file write semantics (atomic temp-file + rename writes, clear-on-emptyREVIEW.md/FEEDBACK.md), the/spec coveragereport format (sharedSpec::coverage_report()renderer with[ok]/[wait]/[sync]/[stop]task-status symbols), and the automatic task-completion heuristic guarded bywrites_in_spec_dir(writes outside the active spec directory never complete spec tasks). The master spec gained sections 10.10aβ10.10c covering the same semantics. -
Tool-calling audit remediation (shipped in v1.0.85) β fixes every HIGH/MED finding from the tool-calling + UTF-8 audit across provider stream parsers, tool dispatch, and the edit-tool family: OpenAI Responses API tool calls no longer silently dropped (missing
ToolCallStart), Gemini final-chunkfunctionCallparsed before the finishReason flush, malformed tool arguments fail fast with a corrective LLM-visible error instead of silently executing with{}, loop restrictions fail closed, schema validation of required args before execution, panicked tool tasks synthesise error results (no orphanedtool_use), object-formargumentsaccepted from llama.cpp/vLLM-style servers, Anthropic/Azure paralleltool_useblocks keyed by SSE block index, HuggingFace tool-incapable models no longer receive a tools array, CRLF files keep their line endings through edits, BOM round-trip fixed, and a conservative text-format tool-call recovery extractor for models that narrate tool calls as prose. -
Goal-driven loop programming (
/loop) β a goal-driven agentic loop that runs aLoopSpecto a stop condition (goal achieved, verification passed, budget exhausted, or interrupted), with a verification gate for verify commands, restriction layers (tool set, read-only globs, scope globs), pre-loop snapshot capture, and a post-loop rollback flow (Enter restores the pre-loop snapshot, Esc keeps changes). The one-shot form/loop <agent> [flags] <goal>accepts--max-steps N,--cost_limit N, and--timeout Noverrides in any position. Configured via theloopsection ofragent.json(loop.max_steps512 default,loop.cost_limit,loop.error_retry_allowance,loop.checkpoints,loop.checkpoint_timeout_secs); seedocs/howtos/loopprogramming.md(shipped in v1.0.82) -
Agents panel reconciliation β with many concurrent sub-agents the TUI Agents button previously could stay disabled with a zero count: the reconcile poll now also fires periodically (every 1.5 s) and merges the authoritative
AgentManager::tasks_snapshot, so the panel self-heals regardless of broadcast-lag event loss (shipped in v1.0.82) -
How-to documentation set β three new how-to manuals in
docs/howtos/:reactagent.md(the core per-turn ReACT loop),loopprogramming.md(goal-driven loops with/loop), andoffice.md(office + PDF tool families with format matrix, JSON examples, and configuration) -
Code index status improvements β the
codeindex_statustool never blocks on the store lock: when a background reindex or graph build holds the mutex it returns an immediate busy report built from lock-free progress atomics;IndexStatsnow carriesgraph_total_edges/graph_nodes/graph_communities; andcodeindex_path/codeindex_explainresolve symbols with exact-match + definition-kind ranking so impl/trait names no longer shadow the real definitions -
Config save/load cache coherence (M-025) β every
Config::save()invalidates the on-disk load cache (Config::invalidate_load_cache()), and the cache key is snapshotted after the auto-creating first load, so TUI config writes (/codeindex off,/tools, ...) are immediately visible to subsequent loads in the same process β this fixes the v1.0.80 CI failure (run 34023696563) -
plot_*tool family β six scientific/terminal plotting tools (plot_line,plot_scatter,plot_bar,plot_histogram,plot_pie,plot_heatmap) render ASCII-art graphs β with real ANSI colours β inline in the TUI message window viaratatui-plt; GPL-3.0 dependency explicitly accepted and allow-listed indeny.toml(v1.0.80) -
Research web-search quota controls β
--max-search-calls Nplaces a hard, run-scoped cap on total web-search calls per research run, shared viaArcacross every supervisor/competitive researcher and gather pass; a run-scoped query cache memoises identical sub-queries so parallel researchers reuse cached hits instead of re-issuing paid calls (v1.0.79) -
--depthbounds web volume by default β the effective web-source budget is derived from the selected depth (shallow 6 / standard 9 / deep 15) unless--max-web-resultsis passed explicitly, so--depth shallownow actually limits search/fetch volume (v1.0.79) -
/research update <name>invocation replay β re-runs a research item by replaying its recorded invocation line, overwritingRESEARCH.mdand associated files with freshly gathered results; available via CLI, TUI, and HTTPPUT /research/{name}(v1.0.79) -
--mode competitivedefaults--formattocomparison-tableβ competitive runs no longer require an explicit--format comparison-table(v1.0.79) -
GitHub
blob/URLs no longer fail research gathering β file-view URLs are rewritten toraw.githubusercontent.comand non-HTML content bypasses the readability gate, eliminating guaranteedreadability extraction failedrejections (v1.0.79) -
/clipslash command β copies the rendered message-window transcript to the system clipboard in one step (v1.0.79) -
/research listrenders a human-readable table again β the fixed-widthNAME/TITLE/STATUS/CREATED/MODIFIEDtable is restored as the default output, with JSON behind the--jsonflag (v1.0.79) -
Research evaluation scorecard configuration β new
research.evaluatesection inragent.jsoncontrols the self-evaluation scorecard appended to research reports (FR-015 of specs/opendeepresearch) -
Clippy
for_kv_mapfix β Ollama provider iteration now usesvalues()instead of destructuring a key-value pair; the LangSearch merge test expectation was also corrected (v1.0.74) -
Sub-agent / teammate step visibility β TUI step log now shows tool calls from tracked sub-agents and teammates with an
[agent-tag]prefix; rebuilt step tags for lagged event-bus bursts prevent undercounting (v1.0.73) -
Tool-permit handling fix β
SessionProcessornow surfaces an explicit error when the per-tool resource permit cannot be acquired (v1.0.73) -
Token counting fixes β TUI context panel percentages now use a consistent bytes-to-tokens conversion so they align with the status-bar usage figure (v1.0.72)
-
Context side panel β toggleable
Alt+Cpanel showing live, quantified context-window occupancy (v1.0.71) -
Research clustering β
/research clusterconcept extraction and a newcluster.rspayload builder (v1.0.71) -
One-shot agent runner β lightweight, provider-agnostic single-prompt execution path without spinning up a full agent loop (v1.0.71)
-
CPU-spin fixes β Gemini SSE parser infinite loop fixed (
continuetobreak), timed-out bash children now killed viakill_on_drop, and the TUI idle redraw interval raised from 250 ms to 2 s with dirty-flag gating (v1.0.60) -
Performance and resource bounding β removed
gh auth tokensubprocess auto-discovery, replaced background-task polling withtokio::sync::Notify, code-index worker busy-spin withrecv_timeout, capped TUI messages (500), log entries (1000), LLM request stats (1000), read-timestamp map (2000), and added WAL auto-checkpointing (v1.0.59) -
Activity log system β new append-only JSONL event store with
RunId/EventIdidentifiers, projection types, rollback/resume support, and consistency validation (v1.0.59) -
Storage schema-version fast path β warm starts skip the full migration batch, reducing
Storage::openfrom ~41 SQL round-trips to a singleCREATE TABLE+SELECT(v1.0.59) -
Research tooling overhaul β New
polarity.rs,run_request.rs,contradiction.rs,corpus_critic.rs, andreconcile.rsmodules; unifiedResearchRunRequestbuilder shared across CLI/TUI/HTTP; tier routing with--tierflag; IMRAD output format; new HTTP research routes with SSE events and 202+Location async behaviour; 37 new tests (v1.0.58) -
Code index semantic graph β Four new graph analysis tools (
codeindex_godnodes,codeindex_path,codeindex_explain,codeindex_communities) with community detection, shortest-path traversal, and god-node identification;/codeindex graph buildsub-command -
Threaded codeindex graph build + status indicators β graph builds run on a dedicated OS thread via
spawn_graph_buildwith a phased lock discipline (brief snapshot, lock-free derivation, brief persist), so FTS search stays available during derivation; the TUI status bar showsidx/graphbusy tags while a reindex or graph build runs (uncommitted, v1.0.80 cycle) -
Bang commands β Prefix any prompt with
!to run a shell command and have the model review its output (v1.0.42) -
Compaction fix β Fixed compaction getting stuck when all messages fit the keep budget; now forces at least one message into the head
-
Code quality β Extracted shared helpers for markdown rendering and agent dispatch, eliminated unnecessary clones, cleaned up noise comments
-
CI fixes β Resolved clippy
needless_raw_string_hashes,vec_init_then_push, anduseless_borrows_in_formattingwarnings
See CHANGELOG.md for the full history.
MIT
{ "provider": { "anthropic": { "thinking": { "enabled": true, "level": "low" }, "models": { "claude-sonnet-4-20250514": { "thinking": { "enabled": true, "level": "high", "budget_tokens": 16000 } } } } }, "defaultAgent": "coder", "permissions": [ { "permission": "file:write", "pattern": "src/**", "action": "allow" } ], "memory": { "enabled": true, "structured": { "enabled": true }, "semantic": { "enabled": false, "dimensions": 384 } }, "compaction": { "auto": true, "threshold": 0.7, "buffer": 0.10, "keep": { "tokens": 0.20 }, // Optional: route compaction to a fast/cheap model instead of the // session's primary model. Default: session model. // "model": { "provider_id": "ollama", "model_id": "qwen2.5:1.5b" }, // Optional: cap summary output tokens (default 1500) and per-tool-output // truncation in the compaction prompt (default 2000). // "summary_tokens": 1500, // "tool_output_max_chars": 2000 }, "tool_visibility": { "office": true, "github": true, "gitlab": true, "teams": true, "agents": true, "plan": true, "codeindex": true }, // Plugin subsystem (defaults shown). `enabled: false` makes the whole // subsystem inert (no discovery or loading). "plugins": { "enabled": true, "max_execution_ms": 5000, "max_entry_ms": 10000, "max_memory_mb": 64 } }