docs: product-facing README; archive CST theory notes (0.9.34)

Rewrite the homepage for day-to-day use, move paper/eval drafts under
docs/archive, and add a docs index so theory no longer leads the project.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WHC
2026-10-29 20:00:22 +08:00
co-authored by Cursor
parent 814a31c9c8
commit 2602806aea
10 changed files with 163 additions and 489 deletions
+128 -481
View File
@@ -1,548 +1,195 @@
# CST-Agent
C11 OpenCode-like carrier that extends paper **CST** (confirmation frontier / irreversible emission) from Markdown→HTML to the **agent tool loop**.
本地 coding agent:终端 TUI、可选 WebUI / 桌面 GUI,在工作区里读改文件、跑命令、管会话。
C11 实现,OpenAI 兼容网关(DeepSeek / Kimi / MiniMax / OpenAI 等)。
See [docs/theory_tool_cst.md](docs/theory_tool_cst.md).
评测/反哺论文素材:[docs/eval_tool_cst.md](docs/eval_tool_cst.md)。
**适合**:有监督的本地改动与仓库探索(权限确认、diff、`/undo`、沙箱)。
**慎用**:完全无人值守的长任务;headless 默认自动批准。
## 能不能用来工作?
文档索引:[docs/README.md](docs/README.md)。
**可以**:有监督的本地改动 / 探索仓库(TUI + 13 个内置工具 + 带 diff 的权限确认 + `/undo`)。
**不宜**:无人值守长任务或当 CI 主力(网关偶发空答;headless 模式默认自动批准)。
---
### 5 分钟试用
## 安装
### Linux / WSL / macOS(推荐)
```bash
# Linux / WSL / macOS 一键:克隆到 ~/CST-agent、编译、装到 ~/.local/bin
# 预编译包(快;失败则自动回退源码编译)
curl -fsSL https://git.whcself.xyz/WHC/CST-agent/raw/branch/main/scripts/bootstrap_linux.sh | bash -s -- --release
# 或始终从源码增量编译安装到 ~/.local/bin
curl -fsSL https://git.whcself.xyz/WHC/CST-agent/raw/branch/main/scripts/bootstrap_linux.sh | bash
# 已有仓库目录内(装到别处:CST_AGENT_PREFIX=/usr/local)
./scripts/bootstrap_linux.sh .
# 以后升级:拉取最新代码、重新编译并安装(本地有未提交改动时跳过 pull)
cst-agent-update
cst-agent --version
# 在项目目录里直接启动:首次会让你选 provider 并输入 API key(遮罩输入,按 provider 保存)
cd ~/my-project && cst-agent
```
不想编译:[Release](https://git.whcself.xyz/WHC/CST-agent/releases) 里有静态链接的 Linux 单文件
(`cst-agent-VERSION-linux-{x86_64,x86,aarch64}.tar.gz`,musl,任何发行版都能直接跑),解压后把 `cst-agent`
放进 `PATH` 即可;每个文件旁边有 `.sha256`。
已有仓库目录:
Windows 10 1903+(PowerShell,不需要管理员):
```bash
./scripts/bootstrap_linux.sh . # 源码
./scripts/bootstrap_linux.sh . --release # 只装 Release 二进制
cst-agent-update # 之后升级
cst-agent --version
```
[Release](https://git.whcself.xyz/WHC/CST-agent/releases) 也提供静态 musl 包
`cst-agent-VERSION-linux-{x86_64,x86,aarch64}.tar.gz`(旁有 `.sha256`),解压后把 `cst-agent` 放进 `PATH` 即可。
### Windows 10 1903+
```powershell
irm https://git.whcself.xyz/WHC/CST-agent/raw/branch/main/scripts/install_windows.ps1 | iex
# 新开终端后:cd 到项目目录运行 cst-agent;升级用 cst-agent-update
```
也可以下载 Release 里的安装包 `cst-agent-VERSION-windows-x86_64-setup.exe`(按用户安装、自动加 PATH、
开始菜单有 WebUI 入口),或便携版 zip。详见 [docs/README-windows.md](docs/README-windows.md)。
一键脚本可以重复运行:已有仓库会 `git pull --ff-only`,**增量编译**后重新安装(`CST_AGENT_CLEAN=1` 才强制 clean);
同时装 `cst-agent-update` 与 `cst-agent-service`(议会席位服务辅助)。NixOS 上会自动进 `nix-shell` 编译。
之后再启动会沿用上次的 provider、模型和推理强度(low / medium / high / max),不需要任何参数或环境变量。
界面里用 `/provider` 切换(没保存过 key 的会当场询问),`/model`、`/effort` 切换模型和推理强度,`/key` 更换 key。
完整环境变量说明:[docs/env_openai.md](docs/env_openai.md)。
多设备议会(密码 Realm / 主席 / 常驻同步):[docs/parliament.md](docs/parliament.md)。
| 平台 | 一键脚本 |
|---|---|
| Linux | [`scripts/bootstrap_linux.sh`](scripts/bootstrap_linux.sh) |
| Termux | [`scripts/bootstrap_termux.sh`](scripts/bootstrap_termux.sh) |
| Windows 安装 / 升级 | [`scripts/install_windows.ps1`](scripts/install_windows.ps1)(从 Release 安装),之后 `cst-agent-update` |
| Linux 静态发行包(musl 交叉) | [`scripts/package_linux.sh`](scripts/package_linux.sh) `x86_64\|x86\|aarch64` → `dist/*.tar.gz` |
| Windows 交叉构建(在 Linux 上) | [`scripts/bootstrap_windows.sh`](scripts/bootstrap_windows.sh) → `dist/windows-x86_64/`、zip 和安装包 |
| Windows 原生构建(MSYS2 UCRT64) | [`scripts/bootstrap_msys2.sh`](scripts/bootstrap_msys2.sh) → `dist/windows-x86_64/` |
### 迷你验收工程(论文案例)
故意带 bug 的小计算器:[`fixtures/mini_calc/`](fixtures/mini_calc/)(任务书 `TASK.md`)。
```bash
./scripts/e2e_mini_calc.sh --baseline-only # 无 API:证明初始测试 RED
./scripts/e2e_mini_calc.sh --provider deepseek --protocol ctl # 有 key
```
更多夹具(每个都有 `TASK.md` + `check.sh`):`makefile_tab`(写含 TAB 的 Makefile)、
`big_file`(写 5000 字节文件)、`test_fix_test`(先跑测试→修→再跑测试)、
`multi_file_refactor`(跨文件改名 + 修 bug,适合 `edit_file` / `grep`)、
`ask_or_todo`(必须用 `todo_write` 规划并全部完成;无人回答 `ask_user`)。
后两个需要 `--tools default`(脚本默认 `minimal`,即论文用的 4 个工具)。
```bash
scripts/e2e_fixture.sh makefile_tab --provider deepseek --protocol native-inc
scripts/e2e_fixture.sh multi_file_refactor --provider deepseek --tools default
# 批量实验:协议 x 模型 x 夹具 x N 次 → results.csv + summary.md
scripts/run_matrix.sh -p "native-eos native-inc ctl ctl-heredoc xml" \
-m "deepseek:deepseek-flash deepseek:deepseek-v4-pro" -n 3 -r
```
口径:`pass` / `fail` / `agent_error` / `timeout` — 见 [docs/eval_tool_cst.md](docs/eval_tool_cst.md)。
## Build
### Make(Linux 默认)
```bash
cd CST-agent
make -j$(nproc) # 增量编译;头文件依赖走 -MMD,测试复用 libcstcore.a
make -j$(nproc) check # 并行编测试二进制,再串行跑
make asan # AddressSanitizer + UBSan 构建并跑全部测试
make CC=tcc AR=ar check # TinyCC:整套构建 + 测试十几秒(CI 的校验就是这条)
make install PREFIX=$HOME/.local # 或 sudo make install(默认 /usr/local)
make install-service PREFIX=$HOME/.local # 可选:systemd --user 议会服务单元
```
NixOS:`nix-shell --run 'make -j$(nproc) && make install PREFIX=$HOME/.local'`(CLI);Qt 桌面用 `nix-build` / `cst-agent-app`。
macOS:`brew install curl ncurses pkg-config` 后直接 `make`(Makefile 会找 Homebrew 的 keg-only 库)。
各平台细节与验收清单见 [docs/compat.md](docs/compat.md)。
### CMake(推荐跨编译器 / 交叉)
```bash
# GCC
cmake -B build-gcc -DCMAKE_C_COMPILER=gcc -DCST_BUILD_TUI=ON
cmake --build build-gcc && ctest --test-dir build-gcc
# Clang
cmake -B build-clang -DCMAKE_C_COMPILER=clang -DCST_BUILD_TUI=ON
cmake --build build-clang
# Headless only(无 ncurses)
cmake -B build-hd -DCST_BUILD_TUI=OFF && cmake --build build-hd
# Windows:用一键脚本(见下方“Windows 发行包”),会先编译静态依赖
./scripts/bootstrap_windows.sh
```
依赖:`gcc`、`clang` 或 `tcc`(0.9.27 mob 以上)、`libcurl`、TUI 需 `ncursesw`(Windows 版用打过补丁的 ncurses 6.6,脚本自动编译)。
### 桌面 GUI(Qt/QML,可选)
把引擎放进同一个进程的窗口前端(无端口、无第二个进程):`app/`,细节见 [app/README.md](app/README.md)。
```bash
# NixOS / nix:装进用户 profile(PATH + 菜单项 + 图标),卸载 nix profile remove cst-agent
nix profile add --file .
# 其他发行版(需要 Qt 6 的 Quick/Qml/QuickControls2 与 libcurl)
cmake -B build-app -DCST_BUILD_APP=ON -DCMAKE_BUILD_TYPE=Release
cmake --build build-app -j && cmake --install build-app --component app --prefix ~/.local
```
菜单里启动时工作区=启动目录(即 `$HOME`);在项目目录里 `cst-agent-app` 启动则工作区就是那个目录。
Sashidown(`vendor/sashidown`)与 cJSON(`vendor/cjson`,MIT)已随仓库提供。
API Key:TUI 里输入并按 provider 保存到配置目录的 `credentials`(权限 0600);`/key` 更换,`--ask-key` 在命令行输入。
`--api-key` 只用于本次进程、不落盘;`DEEPSEEK_API_KEY` 等环境变量和 `CST_API_KEY` 仅作为没有保存 key 时的兜底(方便 CI)。
## 平台支持矩阵
| OS | Arch | 编译器 | Headless | TUI | Shell |
|---|---|---|---|---|---|
| Linux(glibc / musl) | x86_64 / x86 / aarch64 | GCC, Clang, TinyCC | yes | ncursesw | `/bin/sh` 或旁路 `busybox` |
| WSL2 | x86_64 | 同 Linux | yes | ncursesw | `/bin/sh`(工作区建议放在 Linux 文件系统内) |
| macOS | arm64 / x86_64 | Apple Clang | yes | ncurses(Homebrew) | `/bin/sh` |
| Android Termux | aarch64 / … | Clang (Termux) | yes | ncurses(Termux 包) | `$PREFIX/bin/sh`;可旁路 busybox |
| Windows 10 1903+ | x86_64 | MinGW-w64 GCC(UCRT) | yes | ncurses 6.6(Windows 控制台) | **捆绑 busybox-w32** |
### WebUI(`--web`)
同一个二进制内置一个 HTTP + SSE 前端:`cst-agent --web`(默认 `http://127.0.0.1:8787/`)。
它和 TUI 是同一引擎的两个前端,浏览器里能流式看回答、点审批、切会话、贴图。
协议是一份稳定的 JSON + SSE 接口,供以后的专用客户端复用。详见 [docs/webui.md](docs/webui.md)。
```bash
cst-agent --web # 本机浏览器打开 http://127.0.0.1:8787/
cst-agent --web --web-port 0 # 端口交给系统,启动日志里给 URL
cst-agent --web --web-dev ./web # 开发前端:直接读目录,改完刷新
cst-agent --web --web-host 0.0.0.0 --web-token 口令 # 手机/局域网访问
sh scripts/e2e_webui.sh # 用录制流跑完整轮次,不需要 API key
```
不带 TUI 的构建也可以开 WebUI(`cmake -DCST_BUILD_WEBUI=ON -DCST_BUILD_TUI=OFF`);
`-DCST_BUILD_WEBUI=OFF` 时 `--web` 只打印一条提示。
或下载 `cst-agent-VERSION-windows-x86_64-setup.exe` / 便携 zip。详见 [docs/README-windows.md](docs/README-windows.md)。
### Termux
```bash
# 一键:装依赖、克隆到 ~/CST-agent、编译、安装到 $PREFIX/bin
curl -fsSL https://git.whcself.xyz/WHC/CST-agent/raw/branch/main/scripts/bootstrap_termux.sh | bash
# 以后升级(重跑上面那条也一样)
cst-agent-update
# 或手动
pkg install git clang make pkg-config binutils libcurl ncurses
git clone https://git.whcself.xyz/WHC/CST-agent.git && cd CST-agent
make && make install # 装到 Termux 的 $PREFIX/bin,之后任意目录运行 cst-agent
# 可选:旁路 Unix busybox
# ./scripts/build_third_party_mingw.sh busybox-unix
```
环境:`PREFIX` 自动用于找 `sh`;`CST_EXE_DIR` / `argv[0]` 用于定位旁路 busybox(`/proc/self/exe` 受限时)。
临时目录:依次试 `$TMPDIR`、`$PREFIX/tmp`、`/tmp`、`/var/tmp`、`~/.cache/cst-agent/tmp`,用第一个真能建文件的,
并写回 `TMPDIR` 给 shell 子进程和沙箱用(Termux 的 `/tmp` 常常不存在或被 SELinux 拒绝)。
### Linux 静态发行包
### 第一次用
```bash
scripts/package_linux.sh x86_64 # 或 x86 / aarch64;CST_LINUX_CHECK=1 顺便跑 make check
cd ~/my-project && cst-agent
```
用 Bootlin 的 musl 交叉 gcc(固定版本、校验 sha256)静态编译 mbedTLS、curl 8.22(只开 HTTP/HTTPS)和宽字符 ncurses,
再以 `STATIC=1` 和 `-Werror` 编出 `cst-agent`,产物是 `dist/cst-agent-VERSION-linux-ARCH.tar.gz`(+ `.sha256`)。
宿主需要 `cmake ninja make perl` 以及 `tic`/`infocmp` 和终端条目(Debian:`ncurses-bin ncurses-term`)。
ncurses 会去常见目录找 terminfo,找不到时用编进去的 `xterm-256color`、`xterm`、`screen-256color`、`tmux-256color`、`linux`、`vt100`。
CA 证书:`CST_CA_BUNDLE` → `SSL_CERT_FILE` → 各发行版的常见位置(Debian/Ubuntu、Fedora/RHEL、openSUSE、Alpine)。
首次选择 provider 并输入 API key(遮罩输入,按 provider 存到配置目录 `credentials`,权限 0600)。
之后用 `/provider`、`/model`、`/effort`、`/key` 切换;选择会记在 `settings.json`。
### Windows 发行包
完整环境变量:[docs/env_openai.md](docs/env_openai.md)。
多设备议会:[docs/parliament.md](docs/parliament.md)。
见 [docs/README-windows.md](docs/README-windows.md)(安装、编码、沙箱、构建、已知限制)。
```bash
./scripts/bootstrap_windows.sh # Linux 交叉编译;Windows 上在 MSYS2 UCRT64 里用 scripts/bootstrap_msys2.sh
```
产物:`dist/windows-x86_64/`(静态链接的 `cst-agent.exe` + `busybox.exe`,无其他 DLL)、
`dist/cst-agent-VERSION-windows-x86_64.zip`,以及装了 `makensis` 时的安装包 `dist/cst-agent-VERSION-windows-x86_64-setup.exe`。
### CI 与 Release
`.gitea/workflows/ci.yml`:TinyCC 校验(构建、`make check`、WebUI 端到端)通过后,用 gcc(`-Werror`)打发行包——
Linux x86_64 / x86 / aarch64 静态包(前两者跑 `make check`,aarch64 用 qemu 冒烟),
Windows x86_64 的 zip 和安装包(Debian mingw-w64 UCRT + NSIS)。
推送到 `main` 或 `v*` tag 时各任务经 `scripts/ci_publish.sh` 上传到 Gitea Release `vVERSION`(同名资源会被替换);
仓库可设 `RELEASE_TOKEN`(`write:repository`),否则用任务自带 token。
共用逻辑在 `scripts/lib_release.sh`(版本号、sha256、打包、下载镜像)。
本地:`GITEA_TOKEN=... scripts/release.sh dist/cst-agent-*.tar.gz dist/cst-agent-*.zip dist/cst-agent-*-setup.exe`。
快速安装预编译包:`scripts/bootstrap_linux.sh --release`(失败则回退源码编译)。
环境变量:`CST_SHELL`、`CST_EXE_DIR`、`CST_AUTO_APPROVE` 等。
## Defaults (API)
`--provider`(或 `CST_PROVIDER`)选择预设;显式的 `--api-base` / `--model` / 环境变量优先。
| provider | API Base | 默认模型 | Key 变量 |
|---|---|---|---|
| `minimax`(默认) | `https://api.minimax.cn/v1` | `MiniMax-M2.7` | `MINIMAX_API_KEY` |
| `deepseek` | `https://api.deepseek.com/v1` | `deepseek-flash`(另有 `deepseek-v4-pro`) | `DEEPSEEK_API_KEY` |
| `kimi` | `https://api.moonshot.ai/v1` | `kimi-k3`(另有 `kimi-k2.6`、`kimi-k2.7-code`) | `MOONSHOT_API_KEY` |
| `kimi-code` | `https://api.kimi.ai/coding/v1` | `k3`(另有 `k3-256k`、`kimi-for-coding`、`kimi-for-coding-highspeed`) | `KIMI_API_KEY` |
| `openai` | `https://api.openai.com/v1` | `gpt-4.1-mini` | `OPENAI_API_KEY` |
| `teamorouter` | `https://api.teamorouter.com/v1` | 登录后自动取 `/models` 第一个(`/model` 可换) | `TEAMOROUTER_API_KEY` |
| 用途 | 来源(优先级从高到低) |
| 平台 | 脚本 |
|---|---|
| Provider | `--provider` → `CST_PROVIDER` → 上次使用 → `minimax` |
| Key | `--api-key` → 已保存的 key(`credentials`)→ provider 的 Key 变量 → `CST_API_KEY` → TUI 询问 |
| Base(含 `/v1`) | `--api-base` → `CST_API_BASE` → `OPENAI_BASE_URL` → `OPENAI_API_BASE` → 预设 |
| Model | `--model` → `CST_MODEL` → `OPENAI_MODEL` → 该 provider 上次使用的模型 → 预设 |
| 推理强度 | `--effort` → `CST_EFFORT` → 上次使用 → `medium` |
| Linux / macOS | [`scripts/bootstrap_linux.sh`](scripts/bootstrap_linux.sh) |
| Termux | [`scripts/bootstrap_termux.sh`](scripts/bootstrap_termux.sh) |
| Windows 安装 | [`scripts/install_windows.ps1`](scripts/install_windows.ps1) |
| Linux 静态包 | [`scripts/package_linux.sh`](scripts/package_linux.sh) `x86_64\|x86\|aarch64` |
| Windows 交叉构建 | [`scripts/bootstrap_windows.sh`](scripts/bootstrap_windows.sh) |
| Windows 原生(MSYS2) | [`scripts/bootstrap_msys2.sh`](scripts/bootstrap_msys2.sh) |
“上次使用”记在配置目录的 `settings.json`(TUI 里切换时更新;headless 运行不改它)。
推理强度会按 provider 适配:DeepSeek/OpenAI 使用 `reasoning_effort`,Kimi K3 使用同名字段,Kimi K2 使用 `thinking` 并保留 `reasoning_content`。Kimi 默认开启 1 小时隐式 prompt cache,可用 `CST_KIMI_CACHE_TTL=5m|1h` 调整,或用 `CST_NO_CACHE_HINTS=1` 关闭提示。
---
Kimi 与 DeepSeek 还提供官方联网工具:`web_search` 调用 provider 的 Search API,`web_fetch` 调用 provider 的 Fetch API;其它 provider 继续使用通用 HTTP 抓取。
`kimi` 是按量计费的 Kimi 开放平台,`kimi-code` 是会员订阅的 Kimi Code API;两者的 Base URL 和 API Key 不通用。
详见 [docs/env_openai.md](docs/env_openai.md)。
| 变量 | 作用(默认) |
|---|---|
| `CST_PROTOCOL` / `--protocol` | 工具调用协议(`native-eos`) |
| `CST_TOOLS` / `--tools` | 工具集:`default`(全部)/ `minimal`(论文 4 件套) |
| `CST_MODE` / `--mode` | 工作模式:`coding`(默认,代码口径)/ `general`(通用助手口径) |
| `CST_EFFORT` / `--effort` | 推理强度 `low` / `medium` / `high` / `max` |
| `CST_CONFIRM` / `--confirm` | 哪些类别要确认:`shell,write,net`(默认)或 `none` |
| `CST_MAX_STEPS` / `--max-steps` | 每个用户回合最多调用模型几次(30) |
| `CST_TOOL_OUT_CAP` | 单个工具输出发给模型的字节上限(16384,保留头 60% + 尾 40%) |
| `CST_CTX_WINDOW` | 发给模型的最近非 system 消息条数(80) |
| `CST_CTX_TOKENS` / `CST_AUTO_COMPACT=0` | 覆盖模型上下文窗口大小 / 关闭自动压缩(用到 75% 时自动 `/compact`) |
| `CST_NO_PROJECT_NOTES=1` | 不把工作区的 `AGENTS.md` 注入 system prompt |
| `NO_COLOR` / `CST_ASCII=1` | 关闭颜色 / 强制 ASCII 图形(非 UTF-8 终端自动退化) |
| `CST_SHELL_TIMEOUT` | `run_shell` 超时秒数(默认不限),设了才在超时后整组杀进程,exit=124 |
| `CST_METRICS=0` / `CST_METRICS_PATH` | 关闭 / 指定计时埋点 JSONL(默认 `.agent/metrics/<session>.jsonl`) |
| `CST_RECORD_SSE=DIR` / `CST_REPLAY_SSE=DIR` | 录制 / 回放原始 SSE 流(`NNNN.sse` + `NNNN.req.json`) |
| `CST_APPROVAL=ask\|auto\|yolo` / `CST_SANDBOX=off\|landlock\|seccomp` | 审批模式 / 关闭沙箱(回落到只读白名单规则)或只用指定沙箱 |
| `CST_CA_BUNDLE` | HTTPS 用的 CA 证书文件(默认:`SSL_CERT_FILE`、libcurl 自带路径、常见发行版位置;Windows 用系统证书库) |
| `CST_MODELS`、`CST_AUTO_APPROVE=1`、`CST_SHELL`、`CST_EXE_DIR` | 模型列表、自动批准(= yolo)、shell、旁路 busybox |
## Run
## 构建
```bash
# TUI(工作目录 = 当前目录;Assistant Markdown 经 Sashidown CST 渲染)
cst-agent
make -j$(nproc) # 增量;有 ccache 会自动用;make help 看目标
make -j$(nproc) check # 单元测试
make asan # ASan + UBSan
make CC=tcc AR=ar check # TinyCC 快校验(CI 同款)
make install PREFIX=$HOME/.local
make install-service PREFIX=$HOME/.local # 可选:systemd --user 议会单元
```
# Local CTL demo (no API)
cst-agent --demo-ctl
NixOS:`nix-shell --run 'make -j$(nproc)'`。macOS:`brew install curl ncurses pkg-config` 后直接 `make`。
平台细节:[docs/compat.md](docs/compat.md)。
# 在命令行输入并保存当前 provider 的 key(不回显)
```bash
# CMake(多编译器 / 无 TUI)
cmake -B build -DCMAKE_C_COMPILER=gcc -DCST_BUILD_TUI=ON
cmake --build build -j && ctest --test-dir build --output-on-failure
```
可选 Qt 桌面前端:[app/README.md](app/README.md)。
Android APK:[docs/android.md](docs/android.md)。
### CI 与发布
推送 `main` / `v*` 时 [`.gitea/workflows/ci.yml`](.gitea/workflows/ci.yml) 会:TinyCC `check` → 打 Linux/Windows 发行包 → `scripts/ci_publish.sh` 上传 Gitea Release。
共用逻辑:[`scripts/lib_release.sh`](scripts/lib_release.sh)。本地上传:`GITEA_TOKEN=... scripts/release.sh dist/cst-agent-*`。
---
## 用法速览
```bash
cst-agent # TUI,工作区=当前目录
cst-agent --web # 浏览器 http://127.0.0.1:8787/
cst-agent --headless --prompt '…' # 无人值守(默认自动批准)
cst-agent --ask-key --provider deepseek
# Headless(默认 auto-approve shell/写文件)
cst-agent --headless --prompt 'List files'
```
会话相关命令行参数:
| 参数 | 作用 |
|---|---|
| `-c` / `--continue` | 打开上次的会话(默认行为) |
| `-N` / `--new` | 开新会话 |
| `-R ID` / `--resume ID` | 打开指定会话(完整 id 或唯一前缀) |
| `-L` / `--list-sessions` | 列出会话(时间、条数、标题)后退出 |
| `--migrate-store` | 把旧版本的会话(扁平 `<id>.jsonl`)搬进新布局后退出 |
| `-A MODE` / `--approval MODE` | 审批模式 `ask` / `auto`(默认)/ `yolo`,见下文 |
| `-y` / `--yolo` | 等同 `--approval yolo`,只对本次运行有效 |
| `-C LIST` / `--confirm LIST` | 需要确认的类别:`shell,write,net` 的任意组合或 `none` |
| `-T PROFILE` / `--tools PROFILE` | `default` 或 `minimal` |
| `-M MODE` / `--mode MODE` | 工作模式 `coding`(默认)/ `general`,也读 `CST_MODE`,并记进 `settings.json` |
| `-P NAME` / `-m NAME` / `-e LEVEL` | 本次使用的 provider / 模型 / 推理强度(不传则用上次的) |
| `-a` / `--ask-key` | 在命令行输入并保存当前 provider 的 key |
| `-c` / `-N` / `-R ID` / `-L` | 继续上次 / 新会话 / 恢复 / 列表 |
| `-A ask\|auto\|yolo` / `-y` | 审批模式 |
| `-T default\|minimal` | 工具集(`minimal` = 读写 shell 四件套) |
| `-M coding\|general` | 工作模式 |
| `-P` / `-m` / `-e` | provider / 模型 / 推理强度 |
| `-w DIR` | 工作区 |
工作目录默认就是当前目录(`-w DIR` 可指定别的目录)。
会话目录:`<workspace>/.agent/sessions/<uuid>/`(自带 `.gitignore`)。WebUI 协议:[docs/webui.md](docs/webui.md)。
会话落盘:一个会话一个目录 `<workspace>/.agent/sessions/<id>/`(`session.jsonl` 转录、`title`、`attachments/`、子 agent 的 `sub-N.jsonl`)+ `CURRENT` 指向下次打开的会话;id 是 uuid,两台机器共用一份工作目录也不会撞。旧版本写的扁平会话仍然可读,`--migrate-store` 一次搬进新布局(幂等)。`.agent/` 自带 `.gitignore`,不会被误提交。
### Provider 默认
### 内置工具
| provider | API Base | 默认模型 | Key |
|---|---|---|---|
| `minimax`(默认) | `https://api.minimax.cn/v1` | `MiniMax-M2.7` | `MINIMAX_API_KEY` |
| `deepseek` | `https://api.deepseek.com/v1` | `deepseek-flash` | `DEEPSEEK_API_KEY` |
| `kimi` | `https://api.moonshot.ai/v1` | `kimi-k3` | `MOONSHOT_API_KEY` |
| `kimi-code` | `https://api.kimi.ai/coding/v1` | `k3` | `KIMI_API_KEY` |
| `openai` | `https://api.openai.com/v1` | `gpt-4.1-mini` | `OPENAI_API_KEY` |
| `teamorouter` | `https://api.teamorouter.com/v1` | `/models` 首个 | `TEAMOROUTER_API_KEY` |
| 工具 | 类别 | 说明 |
|---|---|---|
| `read_file` | 读 | 支持 `offset` / `limit` 分段读和行号 |
| `list_dir` | 读 | 目录树(`depth`),遵守 `.gitignore`,跳过 `.git` / `node_modules` 等 |
| `glob` | 读 | 按通配符找文件(支持 `**`) |
| `grep` | 读 | 正则搜索内容,可限定路径 / glob、忽略大小写、带上下文 |
| `write_file` | 写 | 整文件写入(自动建父目录) |
| `edit_file` | 写 | 精确片段替换(必须唯一,或 `replace_all`) |
| `apply_patch` | 写 | 应用 unified diff,多文件原子生效 |
| `delete_file` / `move_file` | 写 | 删除 / 移动(重命名)文件 |
| `run_shell` | shell | 非交互命令,超时整组进程被杀,Esc 可中断 |
| `web_fetch` | 网络 | 抓取 URL,HTML 转纯文本 |
| `web_search` | 网络 | 使用 Kimi 或 DeepSeek 的官方 Search API 搜索实时网页 |
| `download` | 网络 | 把 URL 抓成工作区里的文件(≤128 MB,超限删掉残file);字节落在磁盘上,不进模型上下文 |
| `read_pdf` | 读 | 读 PDF 的文本层(`read_file` 因二进制拒收的缺口),带页数,文本默认截到 256 KiB |
| `clipboard_read` | 读 | 读系统剪贴板里的文本(`max_bytes` 默认 64 KiB,超出截断并说明) |
| `clipboard_write` | 写 | 把文本放进系统剪贴板(按写类权限确认;本机走 pbcopy / wl-copy / xclip / Win32 API) |
| `todo_write` | 元 | 维护任务清单(TUI 右侧面板,Ctrl+T 开关) |
| `ask_user` | 询问 | 向用户提问(可给选项);headless 下返回错误让模型自行决定 |
| `skill` | 元 | 加载一个 skill 的说明(`SKILL.md`)或其中的文件;有 skill 时才出现 |
| `task` | 子 agent | 把独立任务交给子 agent(`general` / `explore` / `plan` / 自定义角色),只返回最终报告 |
| `deliver_file` | 交付 | 把工作区里的成品文件复制进会话库并交给用户(任意字节,≤64 MB):前端画成文件卡,可打开 / 分享;带 `for_user` 标记,永不进模型上下文 |
| `md_to_html` | 文档 | 把 markdown(文本或工作区 `.md`)渲染成一份自包含 HTML 文档写进工作区并交付成文件卡:utf-8、标题、内联样式,无脚本无外链 |
| `md_to_pdf` | 文档 | 图形前端(桌面 / APK)自带:把 markdown 或工作区 `.md` / `.html` 排成 A4 PDF(15 mm 边距,自动分页)写进工作区并交付成文件卡;不需要 Qt PrintSupport,手机上也能出 |
| `session_search` | 读 | 在过去和当前的所有会话转录里搜子串,给会话 id、条数、标题和匹配行(行号 + 角色 + 上下文);有预算:`max_bytes`(默认 32 MB)、`max_seconds`(默认 5 s),超 64 KiB 的单行跳过,被预算截断时结果里写清楚 |
| `device_info` | 读 | 报告运行环境:系统 / 架构 / CPU 数、工作区、沙箱、模型与审批模式、config / temp / 程序目录、pid(审批策略名 `device`) |
优先级:CLI → 已保存 credentials → 环境变量 → TUI 询问。详见 [docs/env_openai.md](docs/env_openai.md)。
插件工具和 MCP 工具(`mcp__<server>__<tool>`)在运行时注册,和内置工具走同一套审批与 `/tools` 开关。
同一步里的多个只读调用(读文件、搜索、只读子 agent)会并行执行(最多 4 个)。
### 内置能力(摘要)
`--tools minimal` 只保留 `read_file` / `run_shell` / `write_file` / `apply_patch`(论文实验口径)。
TUI 中 `/tools off NAME`、`/tools on NAME` 可临时开关单个工具。
- **文件**:`read_file` / `list_dir` / `glob` / `grep` / `edit_file` / `apply_patch` / `write_file` / `delete_file` / `move_file`
- **命令**:`run_shell`(沙箱 + 可中断;超时 `CST_SHELL_TIMEOUT`)
- **网络**:`web_fetch`;Kimi/DeepSeek 另有官方 `web_search`
- **任务**:`todo_write`、`ask_user`、`task` 子 agent、后台 `job_*`(完成会推 TUI / 下一回合笔记)
- **扩展**:Skills、插件、MCP([docs/plugins.md](docs/plugins.md));worker 编排([docs/workers.md](docs/workers.md))
### 工作模式(coding / general)
同一步里连续只读调用会自动并行(默认最多 8,`CST_PAR_MAX` 可调)。截断结果带 `[truncated … evidence=ID]`,用 `evidence_read` 续读。
`--mode general`(或 TUI 里 `/mode general`、WebUI 运行设置里的「工作模式」、`CST_MODE=general`)把默认口径
从"代码助手"换成"通用助手":工作流从改代码/跑测试换成"先弄清要什么、再动手、给出处和不确定的地方",
工具说明从"仓库"改成"文件与数据",并说明 `web_fetch` 可以拿外部资料;`/status` 第一行显示当前模式,
切换后 history 里会留一条系统提示。默认仍是 `coding`,选择记在 `settings.json`;
`--tools minimal`(论文口径)的提示词按字节冻结,不受模式影响。
### 审批与沙箱
### 剪贴板与文档附件
Shift+Tab / `/approval` 在 `ask` → `auto` → `yolo` 间切换。`auto` 下 Linux 优先 Landlock(否则 seccomp),macOS `sandbox_init`,Windows Low IL;详见源码与 [docs/compat.md](docs/compat.md)。
写文件前自动快照,`/undo` 可回滚;工作区 `AGENTS.md` 会注入系统提示。
- **剪贴板**:`clipboard_read` / `clipboard_write` 两个工具(写剪贴板是不可逆发射,要确认);
TUI 里 `/attach paste` 在剪贴板里没有图片时,把剪贴板的**文本**放进输入框(丢掉 CR 与控制字节,尊重输入长度上限)。
- **附件**(`/attach <path>`、拖入终端、剪贴板图片都算):图片按原样存进会话目录,发给模型时是 image part;
**PDF 在摄取时就抽出文本层**(零依赖解析器:Flate / ASCIIHex / ASCII85、对象流、CID 字体 ToUnicode、
内联图像跳过),存的是文本、`mime` 仍是 `application/pdf`;其余文件必须是 UTF-8 文本。
文档以 **text part 内联**发出,所以不受 `CST_NO_IMAGES` 或非视觉模型影响;图片照旧会被换成一行"未发送"说明。
上限:单个附件 ≤16 MB(文档文本 ≤4 MiB),每条消息最多 8 个。
加密 PDF、扫描件(无文本层)会被明确拒绝并说明原因;
`view_image` 仍只收图片,文本/PDF 走 `/attach`。
### TUI 常用
### 权限、撤销与项目说明
- **审批模式**(Shift+Tab 循环切换,`/approval`,`--approval`,`CST_APPROVAL`):
| 模式 | 写文件 | run_shell | web_fetch |
|---|---|---|---|
| `ask` | 询问 | 询问 | 询问 |
| `auto`(默认) | 直接执行 | 有沙箱 → 在沙箱里直接执行;没有沙箱 → 只读白名单命令直接执行,其余询问 | 询问 |
| `yolo` | 直接执行 | 直接执行(不进沙箱) | 直接执行 |
已保存的规则(`a` / `p`)优先:匹配的命令不进沙箱直接运行。
`ask` / `auto` 的选择会记在 `settings.json`;`yolo` 只在本次运行有效。headless 行为不变(全部自动)。
- **沙箱**(C 实现,`src/sandbox_exec.c`):
- Linux:Landlock(内核 5.13+,直接 syscall,无需 libseccomp)。子进程只能写工作区、临时目录、`/dev/null`、`/dev/tty`;
读、执行和联网不受限。
- Linux 没有 Landlock 时(Android / Termux、WSL、老发行版;内核 5.5+,x86_64 / aarch64):seccomp user-notify
(界面显示 `auto · seccomp`)。子进程的写类系统调用(带写标志的 open、创建 / 删除 / 改名 / 链接 / chmod 等)先交给
agent 里的监督线程,按真实路径判断是否在工作区、临时目录或 `/dev/null` 等之内,不在就返回 `EACCES`。联网不受限。
读、执行和已打开文件的写入不检查。它防的是误操作而不是恶意程序:检查之后内核会再读一次路径,多线程程序可以趁机换掉。
探测还会确认能读直接子进程的内存;`ptrace_scope=2` 且无 `CAP_SYS_PTRACE` 时 seccomp 不会启用。
比 shell 活得久的后台进程:桌面发行版开着 Yama(`ptrace_scope` ≥ 1)时它们的受检写入会被拒;命令结束后一律失败。
- macOS:`sandbox_init` profile,同样只放行工作区和临时目录写入,不限制联网。
- Windows 10 1903+:Low 完整性级别的受限令牌 + Job Object(界面显示 `auto · lowil`)。第一次在工作区运行时
给它打上 Low 标签,之后子进程只能写工作区和沙箱临时目录,读不到凭据文件;不限制联网。
`/sandbox` 查看、`/sandbox reset-labels` 撤销标签,详见 [docs/README-windows.md](docs/README-windows.md)。
- 更老的内核:没有沙箱,自动回落到规则判断(界面显示 `auto · rules`)。
- `CST_SANDBOX=off` 强制关闭沙箱;`CST_SANDBOX=landlock` / `seccomp` / `lowil` 只用指定的那种。
- 沙箱里的命令如果像是被拦了(`Permission denied` / `权限不够` / `Read-only file system` 等),会弹窗问
“Rerun outside the sandbox?”:`y` 在沙箱外重跑一次 · `p` 保存命令前缀规则并重跑 · `n` 保留沙箱结果(模型会收到说明)。
- **只读白名单**(无沙箱时 `auto` 用):`ls cat head tail wc grep rg find pwd echo which file stat du tree`
和 `git status/diff/log/show/branch`;可以用 `|` `&&` `||` `;` 串联,但每段都必须在白名单里。
`find -exec/-delete`、`rg --pre`、`git branch NAME`、`>` 重定向(`2>&1`、`>/dev/null` 除外)、`$(…)`、反引号、
`<(…)`、`sudo`、`rm` 一律不算安全。
- **确认弹窗**会显示命令或写入的 diff:
`y` 允许一次 · `a` 本工具总是允许 · `p` 总是允许这个命令前缀(如 `make`、`git status`)· `n` / Esc 拒绝。
`a` / `p` 写入 `<workspace>/.agent/permissions.json`,`/permissions` 查看,`/permissions reset` 清空。
`sudo`、`rm`、解释器(`python3 -c …`)等危险前缀不会被建议成规则。
- **撤销**:每轮写文件前自动快照到 `.agent/undo/`,`/undo` 恢复上一轮改动的全部文件(新建的文件会被删除)。
- **AGENTS.md**:工作区根目录的 `AGENTS.md` 会注入 system prompt;`/init` 让 agent 自己生成一份。
- **自动压缩**:上一轮 prompt 用到模型上下文 75% 时,下一轮开始前自动总结历史(`CST_AUTO_COMPACT=0` 关闭)。
### 扩展:Skills、插件、MCP、子 agent
多模型角色绑定、可续接 worker、共享执行预算与编排模式见 [worker 配置指南](docs/workers.md)。
`--tools minimal` 下这些都不加载(论文口径保持不变)。配置写法与示例见 [docs/plugins.md](docs/plugins.md)。
- **Skills**:`<dir>/SKILL.md`(frontmatter `name` + `description`),放在工作区 `.agent/skills/`、`.claude/skills/`
或配置目录 `skills/`。system prompt 只放名字和一句描述,模型需要时调用 `skill(name)` 读全文;
`/skills` 浏览,`/skill NAME 任务` 直接带着某个 skill 开始一轮。
- **插件**:`plugins/<name>/plugin.json` 声明外部命令工具(参数以 JSON 写到 stdin,stdout 即结果,`perm` 决定审批,
默认 60 s 超时),也可以附带 skills 目录和 MCP 服务器。
- **MCP**:`mcp.json`(`{"mcpServers": {...}}`,与 Claude/Cursor 格式相同)里的 stdio 服务器在后台启动,
工具注册为 `mcp__<server>__<tool>`,默认按网络工具审批(`autoApprove` 可放行)。`/mcp` 看状态,侧栏显示连接数。
- **工作区信任**:工作区里的 `.agent/plugins/` 和 `.agent/mcp.json` 会执行命令,默认不加载;
`/plugins trust` 后才生效(记在 `settings.json`)。配置目录(`~/.config/cst-agent/`)下的始终加载。
- **子 agent**:`task(description, prompt, agent?)` 新开一个独立上下文跑完一轮,把最终报告交回主 agent。
内置 `general`(除 task 外全部工具)、`explore`(只读,可并行)、`plan`(只读,输出计划);
`.agent/agents/*.md` 或配置目录 `agents/*.md` 可自定义角色(frontmatter `name / description / model / tools /
max_steps / readonly`,正文是角色说明)。子 agent 不能再开子 agent;Esc 会一并取消;它的审批弹窗标 `[角色名]`;
文件改动并入当前轮,`/undo` 一起撤销。转录在 `.agent/sessions/<会话>/sub-N.jsonl`,`/agents` 查看。
### TUI 快捷键
默认 leader 是 **Ctrl+X**:先按 Ctrl+X,再按后面的字母。`/keys`(或 F1、Ctrl+X h)列出当前全部绑定。
| 按键 | 说明 |
| 按键 / 命令 | 说明 |
|---|---|
| Enter | 发送;busy 时入队 |
| Ctrl+N / Alt+Enter | 换行(粘贴的多行文本保持原样,不会被当成发送) |
| Shift+Enter / Ctrl+Enter | 换行;需要支持 kitty 键盘协议的终端(kitty、WezTerm、foot、Ghostty、WHC Shell 等),启动时自动探测 |
| ← → Home End Ctrl+A/E Ctrl+B/F Alt+B/F Ctrl/Alt+← → | 移动光标(按字 / 按词,支持中文宽字符) |
| Ctrl+W / Alt+Backspace / Ctrl+Backspace / Ctrl+Delete | 向前删词 / 向后删词(Ctrl+Backspace 需要 kitty 键盘协议) |
| Ctrl+U / Ctrl+K / Delete | 删到行首 / 删到行尾 / 删后一个字符 |
| ↑ / ↓ | 提示历史(多行输入时先在行间移动) |
| Tab | 补全 `/命令` 和 `@文件`;没有可补全时切换 Build / Plan(Plan 只开放只读工具) |
| Shift+Tab | 循环切换审批模式 ask → auto → yolo |
| Ctrl+P | 命令面板(输入过滤,↑↓ / 鼠标选择) |
| Ctrl+O / Ctrl+R | 展开/折叠最近的 tool 输出 / 最近的 Thought |
| Ctrl+T / Ctrl+L | 开关任务面板 / 重绘 |
| PgUp / PgDn、Alt+↑ / Alt+↓、Ctrl+Home / Ctrl+End | 半页滚动、单行滚动、跳到开头 / 最新 |
| Ctrl+X n / l | 新会话 / 会话列表 |
| Ctrl+X m / p / e | 模型 / provider / 推理强度 |
| Ctrl+X u / r / c | 撤销上一轮改动 / 重问 / 压缩上下文 |
| Ctrl+X y / x | 复制上一条回复 / 导出记录 |
| Ctrl+X t / d / s | 全部 Thought 默认展开或折叠 / 全部 tool 输出 / 侧栏 |
| Ctrl+X a / k / g | 子 agent 面板 / skills / 插件 |
| Ctrl+X h、F1 / Ctrl+X q | 快捷键列表 / 退出 |
| 鼠标点击 | 展开/折叠 tool 卡片和 Thought、在输入框里定位光标、点模式行切换 Build/Plan、在选择框里选中 |
| 鼠标拖动 / 双击 / 三击 | 在对话区选中文字(按字符 / 词 / 行),松开即通过 OSC 52 复制到剪贴板;拖到上下边缘会自动滚动。Shift+拖动或 `/mouse` 关闭后用终端原生选择 |
| Esc | 取消当前 turn(不会退出) |
| Ctrl+C 两次 / 空输入 Ctrl+D | 退出 |
| Enter / Esc | 发送(busy 时入队)/ 取消当前回合 |
| Tab / Shift+Tab | 补全或 Build↔Plan / 审批模式 |
| Ctrl+P / Ctrl+T | 命令面板 / 任务面板 |
| Ctrl+X 再按字母 | Leader 快捷键(`/keys` 或 F1 查看) |
| `/provider` `/model` `/effort` `/key` | 切换后端 |
| `/realm` `/motion` | 议会登录提示、Seat Deck 动效 |
| `/web` `/quit` | 起 WebUI / 退出 |
Thought(推理过程)默认折叠成一行“Thought · 3.2s”,生成中显示实时计时;`/thinking on` 改为默认展开。
完整快捷键与斜杠命令仍以 TUI 内 `/help`、`/keys` 为准。
**自定义按键**:`~/.config/cst-agent/keybinds.json`,键是动作名(`/keys` 里能看到),值是一个或多个按键,
`"none"` 解除绑定:
### 工具协议(可选)
```json
{
"leader": "ctrl+x",
"new_session": ["<leader> n", "f2"],
"toggle_thought": "ctrl+g",
"todo": "none"
}
```
默认 `native-eos`(OpenAI `tools[]`,流结束后执行)。也可 `native-inc`、文本帧 `ctl` / `ctl-heredoc`、`xml`(`CST_PROTOCOL` / `/protocol`)。日常使用保持默认即可。
按键写法:`ctrl+x`、`alt+b`、`shift+tab`、`f1`…`f12`、`pgup`、`home`、`<leader> n`。
写错的条目会被跳过并在 `/keys` 里提示,其余照常生效。
---
### 斜杠命令
## 平台
输入 `/` 弹出补全;唯一前缀即可(如 `/st` → `/status`)。标 * 的命令在模型运行中也能用。
| OS | Arch | TUI | 备注 |
|---|---|---|---|
| Linux glibc/musl | x86_64 / x86 / aarch64 | ncursesw | 静态 Release 为 musl |
| WSL2 | x86_64 | ncursesw | 工作区放在 Linux 文件系统 |
| macOS | arm64 / x86_64 | Homebrew ncurses | |
| Termux | aarch64 等 | Termux ncurses | |
| Windows 10 1903+ | x86_64 | 捆绑 ncurses | shell 为 busybox-w32 |
| 命令 | 说明 |
|---|---|
| `/help` * | 命令与按键 |
| `/new`、`/session [id]`、`/rename <标题>` *、`/delete [id]` | 新建 / 选择切换 / 命名 / 删除会话 |
| `/provider [name]`、`/model [name]`、`/effort [level]` | 切换 provider(缺 key 时当场输入并用 `/models` 校验)、模型(列表优先显示 API 实际返回的模型,标 `(api)`)、推理强度;都会记住 |
| `/key` | 输入或更换当前 provider 的 API key(遮罩输入并保存) |
| `/protocol [name]` | 切换工具调用协议 |
| `/mode [coding\|general]` | 工作模式(通用助手 / 代码助手口径) |
| `/tools [on\|off NAME\|minimal\|default]` | 查看或开关工具 |
| `/approval [ask\|auto\|yolo]` *、`/yolo` * | 审批模式;本次开关 yolo |
| `/permissions [reset]` *、`/max-steps [N]` * | 权限规则、每轮步数 |
| `/sidebar` *、`/mouse` * | 开关右侧边栏(≥120 列时显示)、开关鼠标 |
| `/status` *、`/todo` * | 会话 / 模型 / 上下文占比 / 设置;任务清单 |
| `/undo`、`/retry` | 撤销上一轮文件改动;丢弃上一条回复重问 |
| `/diff [path]` * | `git status` + `git diff` |
| `/compact` | 手动压缩上下文 |
| `/export [file]` *、`/copy` * | 导出 Markdown 记录;复制上一条回复(OSC 52,需终端支持) |
| `/attach [path\|paste\|list\|clear]` | 给下一条消息带附件:图片、PDF(自动取文本层)、文本文件;`paste` 优先取剪贴板图片,没有就把剪贴板文本放进输入框 |
| `/web` * | 后台起一个 WebUI 进程(同 workspace、新会话,日志写到 `.agent/webui.log`) |
| `/init` | 让 agent 写 `AGENTS.md` |
| `/details` *、`/thinking [on\|off]`、`/keys` * | 展开全部 tool 输出;Thought 默认展开/折叠;快捷键列表 |
| `/skills [reload\|list]`、`/skill <name> [任务]` | 浏览 skills;带着某个 skill 开始一轮 |
| `/plugins [trust\|untrust\|reload]`、`/mcp [reload]` | 插件与工作区信任;MCP 服务器状态 |
| `/agents` | 子 agent 角色与本会话的子 agent 记录(可查看转录) |
| `/quit` * | 退出 |
---
### 协议
请求统一走 OpenAI 兼容 `POST …/chat/completions`(SSE)。工具调用的承载方式由 `--protocol` 决定:
| 协议 | 承载 | 何时执行 |
|---|---|---|
| `native-eos`(默认) | 原生 `tools[]` / SSE `tool_calls` | 整个流结束后(基线) |
| `native-inc` | 同上 | 某个 index 的参数完整(下一个 index 开始或 finish)即执行 |
| `ctl` | 正文中的 CTL 帧,长度前缀参数 | `end` 行一被确认即执行,流仍在继续 |
| `ctl-heredoc` | 正文中的 CTL 帧,`<<TAG` 定界参数 | 同上 |
| `xml` | MiniMax `<minimax:tool_call>` 文本 | 流结束后 |
文本协议(ctl / ctl-heredoc / xml)不发送 `tools[]`,工具结果以
`result <id> exit=<n> <nbytes>` … `end` 帧放在下一条 user 消息里。
同一会话可以随时切换协议:历史中的调用会按当前协议重新渲染。
## CTL tool language
```text
call <id> <name>
arg <key> <nbytes>
<raw bytes exactly nbytes>
arg <key> <<TAG
<lines, verbatim>
TAG
arg <key> short inline value
end
```
Execution happens only on confirmed `end` (`CTL_EV_CALL_READY`); no prefix of
a call is ever executable. See [docs/theory_tool_cst.md](docs/theory_tool_cst.md).
## Starvation experiment
## 开发者备忘
```bash
make check
./scripts/replay_starvation.sh
./tests/test_replay_real # 真实 DeepSeek 录制流上的逐字节截断(实验 C)
scripts/prompt_smoke.sh # 系统提示契约(无 API)
scripts/e2e_webui.sh # WebUI 录制流(无 API)
scripts/e2e_fixture.sh mini_calc --provider deepseek # 可选:带 key 的夹具
```
CTL vs JSON-buffer 截断数字写入 [docs/eval_tool_cst.md](docs/eval_tool_cst.md) 实验 A / C;与 mini_calc e2e 一起作为 Tool-loop CST 附录素材(**不**替代 SD 主论文 Markdown→HTML 实验)。
`fixtures/` 下是可重复的本地任务夹具(`TASK.md` + `check.sh`),用于手工或脚本验收,不是产品依赖。
许可证与第三方:`vendor/sashidown`、`vendor/cjson`(MIT)、`vendor/monocypher` 随仓库提供。