# Capo

A Rust-native coding agent CLI. Single binary, library-first, focused on shipping correct code through a small set of well-understood tools.

```
$ capo
```

## Install

```bash
cargo install capo-cli
```

The crate is published as `capo-cli` (the name `capo` was already taken on
crates.io); the installed binary is still `capo`.

Or grab a pre-built binary from the latest [GitHub Release](https://github.com/motosan-dev/capo/releases).

## Quickstart

```bash
export ANTHROPIC_API_KEY=sk-ant-...
capo                  # interactive TUI
capo -p "fix the failing test in src/auth/mod.rs"   # print mode
capo -c               # continue the most recent session in this directory
capo --resume         # pick a recent session
```

Capo reads `AGENTS.md` / `CLAUDE.md` from the current directory upward, so per-project context is automatic.

## Supported providers

Capo dispatches to one of six providers, selected by `--provider <name>` or `model.provider` in `~/.capo/agent/settings.toml` (legacy `settings.json` is still read when no TOML file exists).

| `provider` | Backend | Auth |
|---|---|---|
| `anthropic` | Direct Anthropic API | `ANTHROPIC_API_KEY` env, or `auth.json::anthropic.key` |
| `claude-code` | Shells out to the `claude` CLI (Claude Code subscription) | The `claude` CLI handles its own auth |
| `codex-cli` | Shells out to OpenAI's `codex exec --json` | The `codex` CLI handles its own auth |
| `openai` | Direct OpenAI API | `OPENAI_API_KEY` env, or `auth.json::openai.key` |
| `gemini` | Direct Google Generative AI REST API | `GEMINI_API_KEY` env, or `auth.json::gemini.key` |
| `gemini-cli` | Shells out to Google's `gemini` CLI | The `gemini` CLI handles its own auth |

Set the model name with `--model <name>` or `model.name` in settings; capo passes the name through to the provider's API verbatim.

## Tools

| Tool | What it does |
|---|---|
| `read` | Read a file. Always allowed. |
| `grep` | Regex search over file contents. Always allowed. |
| `find` | List files/directories by glob. Always allowed. |
| `ls` | List a directory's entries. Always allowed. |
| `write` | Create or overwrite a file. Prompts unless allowlisted. |
| `edit` | Patch an existing file via unique-string replacement. Prompts unless allowlisted. |
| `bash` | Run a shell command via PTY. Prompts every time unless allowlisted. |

Configure allowlists in `~/.capo/agent/permissions.toml`. See `docs/superpowers/specs/2026-04-23-capo-design.md` §4 for the full permission model.

## Commands & editor

Inside the TUI:

- Type `/` for the command palette — `/help`, `/quit`, `/new`, `/model`,
  `/compact`, `/resume`.
- Type `@` to fuzzy-search and insert a project file path.
- A line starting with `!` runs a shell command and sends its output to
  the agent; `!!` runs it and shows the output without sending.
- `--resume` (or `/resume`) opens an interactive picker of recent
  sessions for the current directory.
- Attach an image: type `/image <path>` (one or more paths, optional
  trailing text). Most modern terminals also let you **drag** an image
  file into the prompt — they paste the file's path as text, which
  Capo auto-detects when it appears at the start or end of your
  message. Supported: PNG, JPEG, GIF, WEBP. Max 5 MiB per image. Works
  against any vision-capable provider (Anthropic, OpenAI, Gemini).
- Cumulative session tokens render in the footer (`Σ N↑ M↓`) when
  `ui.footer_show_cost = true` in `~/.capo/agent/settings.toml`.
  Token-only — no price estimation. Providers that don't surface
  token counts (CLI-shell providers) show `tokens: unavailable`.
- Type `/settings` to open an inline editor for `settings.toml`.
  Edit any of 13 fields across 5 sections; navigate with `↑`/`↓`,
  edit with `Enter`, toggle bools with `Space`, save with `F2`,
  cancel with `Esc`. Save tries the rebuild first — if the new
  settings fail to apply (e.g. invalid provider), `settings.toml`
  stays unchanged on disk.
- Reduce transcript noise with `[ui]` collapse settings (edit via
  `/settings`): `hide_thinking_blocks`, `collapse_tool_output_by_default`,
  `collapse_tool_args_max_lines`, `collapse_history_after`. All apply
  to rendering only — the agent still sees full content.
- Press `Ctrl+E` to globally expand all collapsed blocks in this
  session (toggle).
- Press `F3` to enter history-nav mode: `↑↓` or `j/k` move selection,
  `Space` toggles the selected block's collapsed state (also works on
  default-collapsed blocks), `gg` jumps to top, `G` to bottom, `Esc`
  exits. Selection marker is `▸` in the left gutter; nav-hint row
  appears above the footer while active.
- Thinking / reasoning blocks (Claude extended thinking) render as
  dim italic in the transcript. `hide_thinking_blocks = true` (the
  default) keeps them invisible; flip to `false` in `/settings` to
  reveal.

## JSON / RPC mode

Capo can speak structured JSON instead of running its TUI, for use from scripts and IDE plugins:

- **One-shot:** `capo -p "<prompt>" --json` runs a single turn and streams the result as line-delimited JSON. See [`docs/json.md`](docs/json.md).
- **Persistent:** `capo --rpc` runs a long-lived server speaking bidirectional JSONL over stdin/stdout. See [`docs/rpc.md`](docs/rpc.md).
- **Attachments:** in print and JSON mode, repeat `--image <PATH>` on
  the command line (e.g. `capo -p "describe these" --image a.png
  --image b.jpg --json`). In `--rpc` mode, send attachments inside
  `Command::SendUserMessage`'s `attachments` array — see
  [`docs/rpc.md`](docs/rpc.md) for the wire form.

## Skills

Markdown files in `~/.capo/agent/skills/<name>/SKILL.md` (or flat `<name>.md`) become discoverable skills. They follow the [Agent Skills standard](https://agentskills.io/integrate-skills):

```markdown
---
name: rust-error-triage
description: Use when debugging Rust compile errors or runtime panics
---

Body content (loaded by the model via the `read` tool when the description matches).
```

Per-project skills live at `<repo>/.capo/skills/`.

## Extensions

Capo loads third-party extensions from `~/.capo/agent/extensions.toml`. An
extension is any executable that reads a JSON event on stdin and writes a
JSON action on stdout — capo spawns it fresh per event.

Three hook events:
- `session_before_switch` — before `/new`, `/resume`, `/model`, `/clone`,
  `/fork`. Extension can `cancel` to block the action.
- `before_user_message` — before every Enter press, gets the user's text
  and attachments. Extension can `cancel` to block the turn or
  `transform_text` to rewrite it.
- `command` — when the user types a slash command an extension has
  registered. Extension can `reply` with a Notice or `send` a synthesized
  user message.

Manifest example:

```toml
[[extensions]]
name = "dirty-repo-guard"
command = "~/.capo/agent/extensions/dirty-repo-guard.sh"
hooks = ["session_before_switch"]
```

Run `capo` and type `/extensions` to see what's loaded.

See [`examples/extensions/`](examples/extensions/) for working scripts and
[`docs/superpowers/specs/2026-05-21-capo-v0.7-design.md`](docs/superpowers/specs/2026-05-21-capo-v0.7-design.md)
for the full design.

## MCP

Capo speaks the [Model Context Protocol](https://modelcontextprotocol.io). Servers configured in `~/.capo/agent/mcp.toml` are connected at startup; their tools become available as `<server>__<tool>` (rendered as `<server>:<tool>` in the UI):

```toml
[servers.github]
transport = "stdio"
command = "github-mcp-server"
args = ["--scope", "read-only"]
env = { GITHUB_TOKEN = "${GITHUB_TOKEN}" }
```

## Using `capo-agent` as a library

```rust
use capo_agent::{AppBuilder, Auth, Settings};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let agent_dir = capo_agent::agent_dir();
    let app = AppBuilder::new()
        .with_settings(Settings::load(&Default::default())?)
        .with_auth(Auth::load(&agent_dir)?)
        .with_builtin_tools()
        .build()
        .await?;

    let stream = app.send_user_message("list every .rs file in src/".into());
    use futures::StreamExt;
    futures::pin_mut!(stream);
    while let Some(_event) = stream.next().await { /* render UI events */ }
    Ok(())
}
```

See `crates/capo-agent/examples/list_rust_files.rs` for a runnable version.

## Architecture

Three crates, all under `crates/`:

- `capo-tui` — Elm-style MVU TUI runtime/rendering; consumes `capo-agent` UI event types.
- `capo-agent` — coding-agent SDK; built on `motosan-agent-loop`.
- `capo` — the binary you install.

Detailed design lives in `docs/superpowers/specs/2026-04-23-capo-design.md`.

## License

MIT — see [LICENSE](LICENSE).
