Agent 智能体

Zaru CLI|终端内运行、需先授权再执行的 AI 编程助手(pre-alpha,源码构建)

Zaru CLI

Zaru 是一个运行在终端里的 AI 助手命令行程序:它把任务交给语言模型,并按模型请求读取文件、修改文件、执行命令、抓取网页,每次操作前先征求你的许可,全过程写入纯文本会话记录。

获取与使用

需要部署

按官方资料自行安装或部署

使用难度待核验
国内可用性待核验

2026-11-09 更新 · 本站尚未实测

项目介绍

Agent 智能体 · 2026-11-09 更新 · 本站尚未实测

Zaru 是一个在终端中工作的 AI 助手,对应仓库 100monkeys-ai/zaru-cli,实现语言为 Rust。你把任务作为参数交给它,它向语言模型提问,并执行模型要求的工具调用:读取文件、列出目录、搜索文件、写入文件、编辑文件、运行命令、抓取网页。每一步都会写入可用 cat 直接阅读的纯文本会话记录。

README 明确说明该项目处于 pre-alpha 阶段:没有发布版本、没有软件包,只能从源码构建,命令、文件和配置都可能在不通知的情况下变化。

核心能力

点击能力名称查看输入、输出和原文依据。

  • 七个内置工具:fs.read、fs.list、fs.search、fs.write、fs.edit、cmd.run、web.fetch。
  • fs.read 每次最多返回 500 行带编号内容,可拒绝二进制或非 UTF-8 文件;fs.edit 修改精确匹配的唯一文本或全部出现处,保留换行符与结尾换行。
  • fs.search 在指定目录下按明文检索文件内容与文件名,跳过 .gitignore、.ignore 中列出的内容及常见构建目录,最多显示 40 行结果并说明遗漏情况。
  • cmd.run 不经过 shell 直接启动程序,仅继承 PATH、HOME、LANG、LC_ALL、TMPDIR,两分钟后停止该程序。
  • web.fetch 只抓取 http/https 地址,会拒绝本机地址与链路本地地址(含云元数据地址),跨主机重定向会再次征求许可。
  • 三档权限模式:ask(默认)、allow、yolo;可用配置文件、环境变量或 --mode 指定,项目自带文件不能修改模式或白名单。
  • 会话机制:--continue 重开当前目录最近会话,--resume <id> 重开指定会话,对话从记录重建。
  • 校验器循环:项目在 ./zaru.toml 声明校验命令(如构建、测试),失败时把输出回传给模型重试,直到全部通过或达到 runtime.max_iterations。
  • 上下文窗口管理:会话达到窗口四分之三时摘要较早轮次,并始终保留最后八分之一给模型回答。

实际应用场景

适用场景

  • 在 Linux 终端里对代码库做“读代码并解释”“定位并修改某处逻辑”“运行测试并据报错迭代”等任务。
  • 希望每次文件写入、命令执行、网页抓取前都获得人工确认的开发者。
  • 需要留存可事后审计的纯文本操作记录的场合。
  • 使用本地 Ollama 模型、希望不依赖外部云服务的个人试验环境。

不适合作为沙箱使用:工具调用以当前用户权限直接在机器上执行。

安装与接入

前置条件(据 README):Linux;Rust 1.98.1(由 rust-toolchain.toml 固定,首次构建时 rustup 自动安装);C 编译器 cc;首次构建需访问 crates.io。

构建安装原文命令:

git clone https://github.com/100monkeys-ai/zaru-cli.git
cd zaru-cli
cargo install --path crates/zaru-cli --locked

也可用 cargo build --locked 只构建,产物位于 target/debug/zaru。

模型接入三种方式(需自行创建 ~/.zaru/config.toml,无默认模型):

  • Gemini:用 zaru providers keys add gemini 从标准输入存入 API Key,再在配置中指定模型。
  • Ollama:无需密钥,默认连接 http://localhost:11434,可改 provider.ollama.endpoint。
  • OpenAI 兼容服务:填写基础 URL(Zaru 自动补 /chat/completions),必要时提供上下文 token 数;需要密钥时用 zaru providers keys add openai-compatible 存入。

使用方式:在当前目录执行 zaru "<任务>" 运行单个任务,或直接运行 zaru 进入交互会话。

使用条件与限制

是否需要部署
需自行准备运行环境,具体要求见正文
是否需要注册
账号和认证要求见正文;未明确说明的项目仍待核验
是否需要 API Key
待核验
费用与额度
费用边界见正文,项目许可不代表模型或托管服务免费
所需权限
待核验
许可证与服务条款
待核验

权限费用与限制

  • 安全边界:Zaru 明确声明自己不是沙箱。允许的调用不受限制;yolo 模式下不再询问,模型甚至可能改变已批准的校验器,仅应在完全信任的目录与任务中使用。
  • 校验器需人工批准后才运行,批准记录保存在 ~/.zaru/ 而非项目内,校验命令变化时会重新询问。
  • 发送给模型服务商的内容包括:简短系统提示、你的任务、已有对话、工具描述,以及每次工具调用的结果(含读取的文件内容、命令输出、抓取的页面)。Zaru 会移除自己存储的密钥与令牌值,但不搜索其他任何秘密。
  • 密钥与令牌以 AES-256-GCM 加密存放于 ~/.zaru/credentials.json,加密钥匙放在操作系统钥匙串或 ZARU_CREDENTIAL_KEY;无钥匙串的机器(服务器、WSL、容器)需自行设置该变量,否则无法读取已存密钥。
  • 运行层级:默认 bare 不使用 100monkeys 平台;contained 与 linked 可选但尚未实现,任何层级下工具调用都直接在本机运行。
  • 已知限制:只有 gemini、ollama、openai-compatible 三类可用,anthropic 与 aegis 仅有识别无客户端;zaru learned 与 zaru inbox 为占位命令。
  • 平台:README 称仅在 Linux 构建与测试,使用 Unix 专有 API,无法在 Windows 构建,macOS 未测试。
  • 费用:仓库代码不收费,但 Gemini 或其它 OpenAI 兼容服务是否收费、定价如何,资料未说明,需向对应服务商核验。

国内使用情况

网友核验 用户经验分享

与站长实测独立,不代表官方认证或本站已实测。

我要核验
0 位参与者0 份有效分项记录

最近核验:暂无有效核验。参与人数按当前项目有效身份去重;不同核验项分别统计,不合并成用户总结果。仅统计审核通过且未过期的记录。

分项统计、有效期与样本量
核验项目有效人数成功 / 部分 / 失败 / 无法判断成功率最近核验 / 有效期
官方网站访问00 / 0 / 0 / 0样本不足暂无 / 7 天
GitHub 仓库访问00 / 0 / 0 / 0样本不足暂无 / 7 天
安装与运行00 / 0 / 0 / 0样本不足暂无 / 30 天
官方服务国内连接 / MCP 连接00 / 0 / 0 / 0样本不足暂无 / 30 天
国内网络情况00 / 0 / 0 / 0样本不足暂无 / 7 天
国内模型兼容性00 / 0 / 0 / 0样本不足暂无 / 30 天
自定义 API00 / 0 / 0 / 0样本不足暂无 / 30 天
海外服务依赖
00 / 0 / 0 / 0样本不足暂无 / 30 天
海外账号要求
00 / 0 / 0 / 0样本不足暂无 / 30 天
中文界面
00 / 0 / 0 / 0样本不足暂无 / 30 天
客户端兼容性00 / 0 / 0 / 0样本不足暂无 / 30 天
账号及费用信息
00 / 0 / 0 / 0样本不足暂无 / 30 天

成功率 = 成功 ÷(成功 + 部分成功 + 失败);无法判断不计入分母。至少 5 份可判断结果才显示成功率。账号、费用、海外依赖与语言等事实项,成功表示核查结论与资料吻合,具体观察另行统计;不表示免费或没有海外依赖。不同网络、客户端和版本的结果不能直接等同。

最近有效核验

暂无审核通过且未过期的网友核验。欢迎提交真实使用记录。

查看全部有效核验 →

国内实测状态:国内可用性待核验。协议兼容和官方资料说明不等于国内网络可用。

官方网站访问
尚未实测 待核验
GitHub 仓库访问
尚未实测 待核验
官方服务国内连接
尚未实测 待核验
国内网络情况
尚未实测 待核验
国内模型兼容性
尚未实测 待核验
自定义 API
尚未实测 待核验
海外服务依赖
尚未实测 待核验
海外账号要求
尚未实测 待核验
中文界面
尚未实测 待核验
国内最后核验时间
尚未实测

许可与国内使用

仓库附有 Apache-2.0 许可证文件,README 也写明许可证为 Apache-2.0,并提及 NOTICE 与 THIRD_PARTY.md(后者内容未获取,第三方组件许可待核验)。代码开源不代表所接入的模型服务或 100monkeys 的 Carbon Forge 笔记服务免费或可自由使用:Carbon Forge 属其笔记服务,访问需另存令牌,其许可与费用资料未说明,需向官方核验。

国内使用方面,README 未提及在中国大陆的可用性、网络连通或国内模型厂商适配;Ollama 与 OpenAI 兼容接口在配置层面可指向任意自建服务,但是否存在具体国内模型支持、延迟与合规情况,均待核查。

项目资料与来源

官方网站 ↗

GitHub 仓库 ↗

官方文档 ↗

字段依据与待核验事项

access:来源确认 · git clone https://github.com/100monkeys-ai/zaru-cli.git cd zaru-cli cargo install --path crates/zaru-cli --locked

project_type:来源确认 · Zaru is an AI assistant that works in your terminal. You give it a task, it asks a language model, and it runs the tools the model asks for

原始 README(折叠技术参考)
# Zaru

Zaru is an AI assistant that works in your terminal. You give it a task, it asks a language model, and it runs the tools the model asks for: it reads and edits files, runs commands and fetches web pages, asking your permission first. Every step is written to a plain-text transcript you can read with `cat`.

This repository is the `zaru` command-line program. It is pre-alpha: there are no releases and no packages, you build it from source, and commands, files and settings can change without notice.

## Requirements

- Linux. The program is built and tested on Linux only. It uses Unix-only APIs, so it does not build on Windows. macOS is not tested.
- Rust 1.98.1. The version is pinned in [`rust-toolchain.toml`](rust-toolchain.toml), and `rustup` installs it for you on the first build.
- A C compiler (`cc`). Some dependencies compile C code.
- Network access to crates.io for the first build.
- A model to talk to: a Google Gemini API key, an [Ollama](https://ollama.com) server, or any server with an OpenAI-compatible chat completions API.

## Build and install

```sh
git clone https://github.com/100monkeys-ai/zaru-cli.git
cd zaru-cli
cargo install --path crates/zaru-cli --locked
```

This builds the `zaru` binary and copies it to `~/.cargo/bin`; `zaru --version` checks that it runs. To build without installing, run `cargo build --locked`; the binary is then `target/debug/zaru`.

## Quick start

### 1. Choose a model

Zaru has no default model. You name one in `~/.zaru/config.toml`, which you create yourself.

**Gemini.** Store your API key. It is read from standard input: paste it, press Enter, then press Ctrl-D.

```console
$ zaru providers keys add gemini
stored a `gemini` key under the alias `provider.gemini`.
  the value is sealed and is not printed by any command.
```

Then name the model in `~/.zaru/config.toml`:

```toml
[model]
default = "gemini-3.6-flash"
```

Stored keys are encrypted with a key kept in your operating system's keyring. If the machine has no keyring (a server, WSL, a container) and a task needs a stored key, `zaru` tells you so and stops. Set `ZARU_CREDENTIAL_KEY` to 64 lower-case hexadecimal characters in your shell profile, for example the output of `openssl rand -hex 32`, and keep that value: without it, the keys you stored cannot be read again. A task that needs no stored key, such as one for Ollama, goes on without it and says that the stored keys could not be read.

**Ollama.** No key is needed. Start the server, then write `~/.zaru/config.toml`:

```toml
[model]
default = "llama3.2"

[provider.default]
kind = "ollama"
```

Zaru connects to `http://localhost:11434`. Set `provider.ollama.endpoint` if your server is elsewhere.

**An OpenAI-compatible server.** Give the base URL (Zaru adds `/chat/completions` to it). If the server's `/models` list does not give the model's context window, give it in tokens too:

```toml
[model]
default = "your-model-name"

[provider.default]
kind = "openai-compatible"

[provider.openai_compatible]
endpoint = "http://localhost:8080/v1"
context_tokens = 32768
```

If the server needs a key, store it with `zaru providers keys add openai-compatible`.

### 2. Run a task

Run `zaru` with the task in quotes, from the directory you want it to work in:

```console
$ zaru "read src/main.rs and tell me what it does"
Zaru is not a sandbox. Tool calls run on your machine with your permissions. A permission prompt asks before a call runs; it does not limit what an allowed call can do.

fs.read /home/you/project/src/main.rs — permitted
  read src/main.rs · lines 1 to 42 of 42

<the model's answer>

tokens: 120 prompt + 7 completion = 127, counted by the provider

no validators are declared, so the iteration loop cannot run · declare one in `./zaru.toml`
```

It prints a warning that it is not a sandbox (see [Safety](#safety)), each tool call the model made with what it did (see [What a tool call shows](#what-a-tool-call-shows)), the model's answer, the tokens the task used as the provider counted them, and a note about validators (see [Validators](#validators-and-the-iteration-loop)). These lines use plain ASCII marks, so they read the same through a pipe.

When the model wants to write a file or run a command, Zaru asks you first. If there is no terminal to ask (for example, when `zaru` runs in a script), the call is refused and the model is told so.

### 3. Read the transcript

Each task creates a session: a directory under `~/.zaru/sessions/` named by a session ID.

```sh
zaru sessions list
cat ~/.zaru/sessions/<id>/transcript.jsonl
```

The transcript has one JSON object per line: your task, each model reply with the tool calls it asked for and their arguments, each tool call and whether it was allowed, what each call returned exactly as the model was given it, what the screen showed of each call's result, and the answer. Stored keys and tokens are replaced with a marker before a model reply or a tool result is written.

## Using Zaru

### Interactive sessions

Run `zaru` with no arguments in a terminal to open a session. Type a task and press Enter; each task you type continues the same conversation, and the model is sent every earlier task, reply, tool call and tool result in it. Type `/help` to list commands. Type `/exit`, or press Ctrl-C when nothing is running and the prompt is empty, to leave. Ctrl-C while a task runs, or at a permission prompt, stops the task and keeps the session open.

`zaru --continue` reopens the most recent session started in the current directory, and `zaru --resume <id>` reopens the session with that ID. The conversation is rebuilt from the transcript, so the model is sent the same conversation it had before. A session recorded before tool results were kept reopens with your tasks and the answers, and says once that the earlier tool results were not recorded. When the output is not a terminal, both print the session's transcript and exit instead. The line at the top of the screen shows the runtime tier, the model, the permission mode, how much of the model's context window is used, the tokens the provider counted for the last request, and the session ID. The context figure is an estimate and is marked `~`, for example `~2.1k/4.0k`: Zaru has no tokenizer, so it divides a request's bytes by a bytes-per-token ratio. It starts at 3 bytes a token and, after each answer, uses what the provider counted. The provider's own count is marked `counted`.

**When the conversation gets long.** At three quarters of the window Zaru summarises the oldest turns and says so (`◈ compacted …`); the whole history stays in the transcript. The last eighth of the window is kept for the model's answer, so a request is sent only when its estimate fits in the other seven eighths. If one request cannot fit, for example after a tool returned a very large result, Zaru does not send it: it says how large the request is, which tool result is largest, and what to do. For Ollama, every request also tells the server not to cut the prompt (`"truncate": false`).

**Selecting text.** A session takes over the mouse so that the scroll wheel scrolls the transcript. To select text, hold Shift while you drag (this works in most terminals, including Windows Terminal and VS Code). To give the mouse back to your terminal instead, set `terminal.mouse = false` in `~/.zaru/config.toml`; the scroll wheel then no longer scrolls the transcript.

### What a tool call shows

Under each tool call the screen shows what the call did, as the model was given it:

- **A command**: its exit code and how many lines it printed on standard output and on standard error, then its last 7 lines. Lines from standard output start with `out` and lines from standard error with `err`. A command that printed nothing says so. The output is shown when the command ends, not while it runs.
- **An edit or a write**: the lines it changed, with each line's number. A removed line is marked `-` and an added line `+`, with 2 unchanged lines on each side of a change, and at most 7 rows. A new file shows its first 5 lines and how long it is.
- **A read, a listing, a search or a fetch**: one line saying what came back: which lines of which file, how many entries, how many lines matched in how many files, or the page's status, size and title.

The marks are characters, so they do not depend on colour. A long line is cut at the edge of the screen. When a block leaves lines out, or cuts a long line, all of it is kept in a file in the session's folder, such as `~/.zaru/sessions/<id>/shown-0001.txt`, and the block's last or first line gives the file's path. A stored key is shown as its marker, never its value. Output that would move the cursor, clear the screen or change the terminal's title is shown written out, for example `\u{1b}[2J`, and the terminal does not act on it. Nothing shown here is sent to the model.

### Permission prompts and modes

Before a tool call that needs permission, Zaru shows what the call will do (for a file write, the file and its new contents) and asks `[y/N/a · a allows this exact line for this session · esc says no to this call · ctrl-c stops the turn]`. `y` allows the call once. `a` allows the same call for the rest of the session. `N`, Enter or Esc says no to this call: the model is told you said no, and the task goes on. Ctrl-C stops the whole task: the call does not run, no other call runs, and the session stays open for your next task. The file, command or web address the prompt asks about is always on its first lines. On a small terminal a long path is shortened in the middle so its start and the file's name both show, a long command shows the program and says how many arguments it leaves out, and a long preview shows its first lines and says how many it leaves out. Before fetching a web page, Zaru shows the whole URL and also offers `h`, which allows every URL on that host for the rest of the session.

The permission mode decides what needs asking. Set it with `tools.mode` in `~/.zaru/config.toml`, the `ZARU_TOOLS_MODE` environment variable, or `--mode` on the command line:

| Mode | What it asks about |
| --- | --- |
| `ask` (default) | Every file write, file edit, command, web page fetch and Carbon Forge call, and anything outside the working directory. Reading, listing and searching files inside it do not ask. |
| `allow` | Nothing on your allowlist; everything else. |
| `yolo` | Nothing. Every call the model makes runs. |

The allowlist is `tools.allowlist` in `~/.zaru/config.toml`: a list of the exact lines the prompt shows, for example `"cmd.run cargo test"`. For `web.fetch` an entry may also name a host with no `http://` or `https://`, for example `"web.fetch docs.rs"`, which allows every URL on exactly that host. A project's own files cannot set the mode or the allowlist.

### Configuration

Zaru reads settings from these places. A later one overrides an earlier one:

1. built-in defaults
2. `~/.zaru/config.toml`, your settings
3. `./zaru.toml`, the project's settings (only `[project]`, `[runtime]` and `[[validator]]`)
4. environment variables: the key in upper case with `ZARU_` in front, for example `ZARU_MODEL_DEFAULT`
5. command-line flags

`zaru config explain <key>` shows the value from every place and marks the one in effect. The keys most people need:

| Key | Meaning |
| --- | --- |
| `model.default` | The model to use. `--model` sets it for one run. |
| `provider.default.kind` | `gemini`, `ollama` or `openai-compatible`. |
| `provider.ollama.endpoint`, `provider.openai_compatible.endpoint` | Where the model server listens. |
| `provider.<kind>.context_tokens` | The model's context window, in tokens. See [Context window](#context-window). |
| `tools.mode`, `tools.allowlist` | See [Permission prompts and modes](#permission-prompts-and-modes). |
| `runtime.max_iterations` | How many attempts the validator loop makes. |
| `runtime.max_tool_exchanges` | The most model replies one task may have: 50 unless you set it. At the limit the task stops, the session stays open, and typing `continue` goes on. A project may lower it and not raise it. |
| `terminal.mouse` | `false` gives mouse selection back to the terminal. |

### Context window

When a session opens, Zaru asks the provider how large the model's context window is: Gemini's model description, Ollama's `show`, or the `/models` list of an OpenAI-compatible server. If the provider does not say, Zaru uses `provider.<kind>.context_tokens` from your configuration, and if that is not set, its own default: 1,048,576 for Gemini and 4,096 for Ollama. An OpenAI-compatible server has no default, so if it does not say, you must set the key. Your setting can lower what the provider says and never raises it. For Ollama the model's own figure only lowers the window, because Ollama serves the window Zaru asks for (`num_ctx`), and asking for the model's full length can take gigabytes of memory; set `provider.ollama.context_tokens` to use more. `zaru models` shows the window and which of the three it came from.

### Validators and the iteration loop

A validator is a command in `./zaru.toml` that checks the model's work, such as a build or a test run. When a project declares validators, a task runs in a loop: the model makes a change, the validators run, and if any fails, its output goes back to the model for another attempt. The loop stops when every validator passes or when it reaches `runtime.max_iterations` attempts, which is one at the `bare` tier unless you set it. The screen shows each attempt's tool calls and what they did, as it does for any task. The next task you type is sent each attempt's tool calls and their results, as it is sent a task's; the harness's requests for another attempt are not sent again.

`zaru init` writes an example `./zaru.toml` to edit. A small one:

```toml
[[validator]]
name = "test"
run = "cargo test"
expect = "exit-zero"
```

`expect` can be `"exit-zero"`, `{ exit-code = 2 }`, `{ matches = "<regex>" }` or `{ json_schema = "<file>" }`. If the validators never all pass, `zaru` exits with code 1.

Validators are commands, so none runs until you approve them. Before the first one runs in a project, Zaru shows every validator's name and command and asks. Your answer is kept in `~/.zaru/approved-validators.jsonl`, for that directory and that exact set of commands. If `zaru.toml` changes them, Zaru asks again and shows what changed. When there is no terminal to ask on, the task is refused: run `zaru validators approve` in the project's directory to see the commands and approve them, and `zaru validators list` to see what you have approved. The permission mode does not change this, `yolo` included.

### Carbon Forge

Carbon Forge is 100monkeys' notes service. `zaru notes tokens add <alias> <host>` stores an access token for it, read from standard input. When a session opens with a stored token, Zaru suggests matching page and atom names from your notes as you type. The model can call a Carbon Forge instance's tools only if you list them under `notes.<alias>.agent_tools` in `~/.zaru/config.toml`.

## Command reference

`zaru "<task>"` runs one task. `zaru` with no arguments opens a session in a terminal and prints help otherwise.

| Command | What it does |
| --- | --- |
| `zaru runtime` | Show the runtime tier and what the other tiers would change. |
| `zaru models` | Show each model alias (`default`, `fast`, `smart`, `cheap`, `local`) and the model it resolves to, and the context window a session would use and where it comes from. |
| `zaru config explain <key>` | Show one setting's value at every level, marking the one in effect. |
| `zaru init` | Write an example `./zaru.toml`, if there is none. |
| `zaru providers keys` | List the provider keys stored on this machine. |
| `zaru providers keys add <kind>` | Store a provider key, read from standard input. |
| `zaru providers keys rm <kind>` | Delete a stored provider key. |
| `zaru validators approve` | Show the validators in `./zaru.toml` and ask to approve them. |
| `zaru validators list` | List every project whose validators you approved, and their commands. |
| `zaru sessions list` | List the sessions on this machine. |
| `zaru sessions rm <id>` | Delete a session's directory. |
| `zaru notes tokens` | List the stored Carbon Forge tokens. |
| `zaru notes tokens add <alias> <host>` | Store a Carbon Forge token, read from standard input. |
| `zaru notes tokens describe <alias> <text>` | Add a description to a stored token. |
| `zaru notes tokens rm <alias>` | Delete a stored token. |
| `zaru notes use <alias>` | Choose which token the session's suggestions use. |
| `zaru learned` | Not built yet; says there is nothing to show. |
| `zaru inbox` | Not built yet; says there is nothing to show. |
| `zaru help` | Print the help text. |

| Flag | What it does |
| --- | --- |
| `--model <identifier>` | Use this model for one run. A model alias such as `cheap` means the model it resolves to; anything else is taken as the model's identifier. |
| `--mode <mode>` | Use this permission mode for one run: `ask`, `allow` or `yolo`. |
| `--runtime <tier>` | Use this runtime tier for one run. |
| `--resume <id>` | Reopen a session. |
| `--continue` | Reopen the most recent session started in this directory. |
| `--help` | Print the help text. |
| `--version` | Print the version and the libraries it is built from. |

## Safety

Zaru acts on your machine with your user account's permissions. It is not a sandbox.

- **What the model can do.** It has seven built-in tools: `fs.read`, `fs.list`, `fs.search`, `fs.write`, `fs.edit`, `cmd.run` and `web.fetch`. `fs.read` returns at most 500 numbered lines at a time, fewer when the lines are long, and says how many lines the file has and where to start to read on; it refuses a binary file or one that is not UTF-8, naming its size. `fs.edit` changes text that occurs exactly once, or every occurrence when asked; it keeps the file's line endings and final newline, and when the text is not found it shows the nearest lines. `fs.write` says whether it created a file or replaced one, and how large the old one was. `fs.search` looks for plain text in the files under a folder, and in their names. A needle with no capital letters matches any case; a call can ask for exact case, whole words or one file type. It skips what `.gitignore` and `.ignore` files name, the folders `.git`, `target`, `node_modules`, `vendor`, `dist`, `build`, `__pycache__`, `.venv` and `venv`, and lock files, unless the call asks to include them. It shows at most 40 matching lines, grouped by file and ranked: definitions first, then source, then tests, then generated files. It says how many more lines there are, how to narrow the search, how many files it read and what it did not search. A needle of two or more words also finds declarations whose names or nearby comments hold those words, from each Rust, Python, JavaScript, TypeScript, Go or Java file's parsed structure; nothing is sent anywhere, no model is used and nothing is stored. `fs.list` lists one folder. `cmd.run` starts a program directly, without a shell, in the working directory, with only `PATH`, `HOME`, `LANG`, `LC_ALL` and `TMPDIR` from your environment, and stops it after two minutes. Nothing limits what that program does while it runs. `web.fetch` fetches `http` and `https` URLs only. In `ask` mode it asks first and shows the whole URL, because a URL can carry data off your machine. A redirect to another host is asked about again, and refused when there is no terminal to ask on. It refuses this machine's own addresses and the link-local range, which includes the cloud metadata address.
- **Permission.** The permission mode decides what Zaru asks about. In `yolo` mode it asks nothing, so a model can also change which validators are approved; use `yolo` only for a directory and a task you trust entirely.
- **Validators run only after you approve them.** The commands in a project's `./zaru.toml` are shown to you and run only once you say yes, and you are asked again when they change. The approval is kept under `~/.zaru/`, never in the project, and the permission mode does not skip it.
- **Runtime tiers.** A runtime tier is how much of the 100monkeys platform Zaru uses. The default is `bare`, which uses none. `contained` and `linked` can be selected but are not built yet: at every tier, tool calls run directly on your machine. Zaru prints the not-a-sandbox warning at every tier, and at `contained` and `linked` it adds that the tier is not built yet and changes nothing about how tool calls run. `zaru runtime` says the same.
- **What the model provider receives.** A short system prompt, your task, the conversation so far, the tool descriptions, and the result of every tool call, including the contents of files read, command output and fetched pages. The system prompt states the working directory, the operating system, the date, the tool names and the permission mode; if a system prompt is read from a Carbon Forge page (`persona.path`), that page is sent instead. Zaru removes the values of the keys and tokens it has stored from this. When it cannot read them (no keyring and no `ZARU_CREDENTIAL_KEY`) and the task needs none of them, it says so and goes on without removing them. It does not look for any other secret.
- **What stays on your machine.** Settings, stored keys and sessions are under `~/.zaru/`. Keys and tokens are in `~/.zaru/credentials.json`, encrypted with AES-256-GCM; the encryption key is in the OS keyring or in `ZARU_CREDENTIAL_KEY`. Session files are readable only by you and are kept until you delete them with `zaru sessions rm`.

### Known limitations

- Only three provider kinds work: `gemini`, `ollama` and `openai-compatible`. `anthropic` and `aegis` are recognised but have no client.
- `zaru learned` and `zaru inbox` are placeholders.
- The `contained` and `linked` tiers contain nothing (see above).

## Exit codes

| Code | Meaning |
| --- | --- |
| 0 | The command succeeded. |
| 1 | The work failed: the validators never all passed. |
| 2 | Something you can fix: a missing key or model, a bad setting, an unknown command. The message says what to change. |
| 3 | A problem outside Zaru, such as the network or the provider. The message says whether to wait. |
| 4 | The current runtime tier cannot do what was asked. |
| 70 | A bug in Zaru. The message says how to report it. |
| 128 + n | The session or task was ended by signal n: 143 for `SIGTERM`, 130 for `SIGINT`, and 129 for `SIGHUP` or a terminal that was closed. What was running is stopped first, and the session can be resumed. |

## Development

```sh
cargo fmt --all --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --locked
scripts/check-license-headers.sh
python3 scripts/check-crate-boundaries.py
```

These are the checks CI runs, together with `cargo doc` and a sign-off check. Unset `NO_COLOR` before you run the tests, because one test checks colour output. Every commit needs a `Signed-off-by` line (`git commit -s`); see [CONTRIBUTING.md](CONTRIBUTING.md). Contributors and coding agents start at [CLAUDE.md](CLAUDE.md).

## Licence

Apache-2.0. See [LICENSE](LICENSE), [NOTICE](NOTICE) and [THIRD_PARTY.md](THIRD_PARTY.md).
历史前置条件说明(补充参考)

Linux 系统;Rust 1.98.1(由 rust-toolchain.toml 固定);C 编译器 cc;首次构建需访问 crates.io。需自备模型:Google Gemini API Key、Ollama 服务或任意 OpenAI 兼容 chat completions 服务(服务是否收费待核验)。无钥匙串的环境需自行设置 ZARU_CREDENTIAL_KEY。是否支持国内网络环境与国内模型,待核验。

项目来源与清单版权许可

https://github.com/100monkeys-ai/zaru-cli

整理来源:https://github.com/slavakurilyak/awesome-ai-agents

清单版权与许可:

MIT License

Copyright (c) 2024 Slava Kurilyak

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.