opi-coding-agent
The
opibinary — a minimal terminal coding agent. Produced by this crate, built onopi-ai,opi-agent, andopi-tui.
Status (v0.2.0)
Phase 1 MVP. The interactive TUI and non-interactive (positional prompt or
--non-interactive) modes both work end-to-end against Anthropic. Six built-in
tools, TOML configuration, exit codes, and a high-risk-tool safety policy are in
place.
Not yet implemented: other providers, persistent sessions, sub-agents,
skills, slash commands, /login / OAuth.
Install
Or download the pre-built binary for your platform from a GitHub Release.
Quick start
# Interactive (ratatui TUI)
# Non-interactive — positional prompt to stdout, exit
# Pick a different model
# Allow write/edit/bash in non-interactive mode
CLI flags
| Flag / arg | Description |
|---|---|
[PROMPT]... |
Positional prompt text; non-empty args select non-interactive mode |
-m, --model <SPEC> |
Model spec (e.g. anthropic:claude-sonnet-4) |
-c, --config <FILE> |
Path to a TOML config file (must exist) |
-s, --system <FILE> |
System prompt file (prepended to the built-in prompt) |
--non-interactive |
Force non-interactive mode (prompt text still required) |
--allow-mutating |
Allow write / edit / bash in non-interactive mode |
-v, --verbose |
Enable debug tracing |
Configuration
TOML files merge user → project → --config (later layers override earlier keys).
Model resolution (highest → lowest):
--model(CLI)OPI_MODEL— only when--configwas not passedmodelin--config <file>- Project —
<CWD>/.opi/config.toml - User —
%APPDATA%\opi\config.toml(Windows) or~/.config/opi/config.toml(Unix) - Built-in defaults
.opi/config.toml shape (every field is optional; values shown are defaults):
[]
= "anthropic:claude-sonnet-4"
= 50
= 30000
= "default"
= false
[]
= true
= 10000
[]
= "ANTHROPIC_API_KEY"
# base_url = "https://api.anthropic.com" # override only if needed
Set defaults.allow_mutating_tools = true to skip --allow-mutating on every
non-interactive invocation.
Built-in tools
Tools live in src/tool/:
| Tool | Args | Notes |
|---|---|---|
read |
path, optional offset + limit |
1-based line range |
glob |
pattern, optional path |
gitignore-aware |
grep |
pattern, optional glob / path |
gitignore-aware, regex |
write |
path, content |
mutating; needs --allow-mutating non-interactively |
edit |
path, old_string, new_string |
exact-match replacement; mutating |
bash |
command, optional timeout_secs |
uses cmd.exe on Windows, sh on Unix |
All paths are resolved relative to (and constrained within) the workspace root
passed to CodingHarness::new (the CLI uses the current working directory).
Modes
Non-interactive
NonInteractiveRunner::run() captures assistant text to stdout, diagnostics
to stderr, and returns one of these exit codes:
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Runtime failure |
2 |
Config error |
3 |
Auth failure (missing or invalid API key) |
4 |
Provider failure |
5 |
Tool failure |
130 |
Interrupted (Ctrl+C) |
Interactive
CodingHarness + InteractiveCodingHooks drives a ratatui TUI built from
opi-tui widgets. Streaming text deltas update the live transcript, tool
calls render with status, and mutating tools surface confirmation.
Library use
opi-coding-agent is also a regular library crate. The harness and
runner modules let you embed the same loop in your own Rust app:
use OpiConfig;
use CodingHarness;
# async
License
MIT — see workspace LICENSE.