Files
CST-agent/README.md
T
WHCandCursor 2f96b050d6 perf: faster builds, leaner daemon, smoother install/run (0.9.20)
Reuse libcstcore.a for tests with -MMD incremental deps; idle-backoff the
parliament seat loop; defer curl init and cache settings; add systemd helper.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-29 11:41:16 +08:00

35 KiB
Raw Blame History

CST-Agent

C11 OpenCode-like carrier that extends paper CST (confirmation frontier / irreversible emission) from Markdown→HTML to the agent tool loop.

See docs/theory_tool_cst.md. 评测/反哺论文素材:docs/eval_tool_cst.md。

能不能用来工作?

可以:有监督的本地改动 / 探索仓库(TUI + 13 个内置工具 + 带 diff 的权限确认 + /undo)。
不宜:无人值守长任务或当 CI 主力(网关偶发空答;headless 模式默认自动批准)。

5 分钟试用

# Linux / WSL / macOS 一键:克隆到 ~/CST-agent、编译、装到 ~/.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 里有静态链接的 Linux 单文件 (cst-agent-VERSION-linux-{x86_64,x86,aarch64}.tar.gz,musl,任何发行版都能直接跑),解压后把 cst-agent 放进 PATH 即可;每个文件旁边有 .sha256。

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。

一键脚本可以重复运行:已有仓库会 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。
多设备议会(密码 Realm / 主席 / 常驻同步):docs/parliament.md。

平台 一键脚本
Linux scripts/bootstrap_linux.sh
Termux scripts/bootstrap_termux.sh
Windows 安装 / 升级 scripts/install_windows.ps1(从 Release 安装),之后 cst-agent-update
Linux 静态发行包(musl 交叉) scripts/package_linux.sh x86_64|x86|aarch64 → dist/*.tar.gz
Windows 交叉构建(在 Linux 上) scripts/bootstrap_windows.sh → dist/windows-x86_64/、zip 和安装包
Windows 原生构建(MSYS2 UCRT64) scripts/bootstrap_msys2.sh → dist/windows-x86_64/

迷你验收工程(论文案例)

故意带 bug 的小计算器:fixtures/mini_calc/(任务书 TASK.md)。

./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 个工具)。

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。

Build

Make(Linux 默认)

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。

CMake(推荐跨编译器 / 交叉)

# 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。

# 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。

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 只打印一条提示。

Termux

# 一键:装依赖、克隆到 ~/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 静态发行包

scripts/package_linux.sh x86_64     # 或 x86 / aarch64;CST_LINUX_CHECK=1 顺便跑 make check

用 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)。

Windows 发行包

见 docs/README-windows.md(安装、编码、沙箱、构建、已知限制)。

./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

CI 用 TinyCC 校验(构建、make check、WebUI 端到端),通过后用 gcc(-Werror)出发行包: Linux x86_64 / x86 / aarch64 静态包(x86 两种跑 make check,aarch64 用 qemu 冒烟), Windows x86_64 的 zip 和安装包(Debian 的 mingw-w64 UCRT gcc + NSIS)。 推送到 main 或 v* tag 时每个任务把自己的产物上传到 Gitea Release vVERSION(同名资源会被替换); 仓库可设 RELEASE_TOKEN(write:repository),否则用任务自带 token。 本地:GITEA_TOKEN=... scripts/release.sh dist/cst-agent-*.tar.gz dist/cst-agent-*.zip dist/cst-agent-*-setup.exe。

环境变量: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

“上次使用”记在配置目录的 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。

变量 作用(默认)
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

# TUI(工作目录 = 当前目录;Assistant Markdown 经 Sashidown CST 渲染)
cst-agent

# Local CTL demo (no API)
cst-agent --demo-ctl

# 在命令行输入并保存当前 provider 的 key(不回显)
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

工作目录默认就是当前目录(-w DIR 可指定别的目录)。

会话落盘:一个会话一个目录 <workspace>/.agent/sessions/<id>/(session.jsonl 转录、title、attachments/、子 agent 的 sub-N.jsonl)+ CURRENT 指向下次打开的会话;id 是 uuid,两台机器共用一份工作目录也不会撞。旧版本写的扁平会话仍然可读,--migrate-store 一次搬进新布局(幂等)。.agent/ 自带 .gitignore,不会被误提交。

内置工具

工具 类别 说明
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)

插件工具和 MCP 工具(mcp__<server>__<tool>)在运行时注册,和内置工具走同一套审批与 /tools 开关。 同一步里的多个只读调用(读文件、搜索、只读子 agent)会并行执行(最多 4 个)。

--tools minimal 只保留 read_file / run_shell / write_file / apply_patch(论文实验口径)。 TUI 中 /tools off NAME、/tools on NAME 可临时开关单个工具。

工作模式(coding / general)

--mode general(或 TUI 里 /mode general、WebUI 运行设置里的「工作模式」、CST_MODE=general)把默认口径 从"代码助手"换成"通用助手":工作流从改代码/跑测试换成"先弄清要什么、再动手、给出处和不确定的地方", 工具说明从"仓库"改成"文件与数据",并说明 web_fetch 可以拿外部资料;/status 第一行显示当前模式, 切换后 history 里会留一条系统提示。默认仍是 coding,选择记在 settings.json; --tools minimal(论文口径)的提示词按字节冻结,不受模式影响。

剪贴板与文档附件

  • 剪贴板: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。

权限、撤销与项目说明

  • 审批模式(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。
    • 更老的内核:没有沙箱,自动回落到规则判断(界面显示 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 配置指南。

--tools minimal 下这些都不加载(论文口径保持不变)。配置写法与示例见 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 退出

Thought(推理过程)默认折叠成一行“Thought · 3.2s”,生成中显示实时计时;/thinking on 改为默认展开。

自定义按键:~/.config/cst-agent/keybinds.json,键是动作名(/keys 里能看到),值是一个或多个按键, "none" 解除绑定:

{
  "leader": "ctrl+x",
  "new_session": ["<leader> n", "f2"],
  "toggle_thought": "ctrl+g",
  "todo": "none"
}

按键写法:ctrl+x、alt+b、shift+tab、f1…f12、pgup、home、<leader> n。 写错的条目会被跳过并在 /keys 里提示,其余照常生效。

斜杠命令

输入 / 弹出补全;唯一前缀即可(如 /st → /status)。标 * 的命令在模型运行中也能用。

命令 说明
/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

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.

Starvation experiment

make check
./scripts/replay_starvation.sh
./tests/test_replay_real      # 真实 DeepSeek 录制流上的逐字节截断(实验 C)

CTL vs JSON-buffer 截断数字写入 docs/eval_tool_cst.md 实验 A / C;与 mini_calc e2e 一起作为 Tool-loop CST 附录素材(不替代 SD 主论文 Markdown→HTML 实验)。