refactor: archive GUI clients; keep minimal TUI with hooks/API
ci / tcc-check (push) Successful in 1m8s
ci / linux (aarch64, 0) (push) Failing after 1h0m3s
ci / linux (x86, 1) (push) Failing after 1h0m3s
ci / linux (x86_64, 1) (push) Failing after 1h0m2s
ci / windows (push) Failing after 50s

Move Qt/Tauri/full Web SPA under archive/, ship hermit as CLI/TUI plus
libcstcore and cst-webui/1 HTTP+SSE (turn lifecycle hooks, capabilities).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WHC
2026-10-30 22:49:23 +08:00
co-authored by Cursor
parent ea38247161
commit 5538ed3412
184 changed files with 14098 additions and 1858 deletions
+23 -17
View File
@@ -1,32 +1,35 @@
# WebUI(内置 HTTP + SSE 前端)
# 引擎 HTTP + SSE API(`cst-webui/1`)
`cst-agent --web` 让同一个进程同时提供命令行以外的前端:浏览器(或任何 HTTP 客户端)
连上后能看到流式回答、工具卡片、审批弹窗和任务清单。它是 TUI 之外的第二个前端,
**引擎没有为它改一行**——两边用的都是 `cst_agent_hooks_t` 这组回调。
`hermit --web`(兼容 `cst-agent --web`)在同一进程上暴露 **远程客户端契约**:
任意 HTTP 客户端可订阅 SSE、发起 turn、回答审批。事件与嵌入式
`cst_agent_hooks_t` 一一对应——TUI 与 `--web` 共用引擎,不另开私有通道。
这份文档同时是**引擎 API v1 的规范**:以后专门客户端(Tauri / Qt / 移动端)直接照它实现,
不需要读 C 代码。
字段级摘要见 [webui-schema.md](webui-schema.md)。设备间 peer 套接字见
[parliament.md](parliament.md)(与本 API 无关)。
默认只嵌入**健康页**;完整浏览器 SPA 参考实现在 `archive/web-spa`。
## 快速开始
```bash
# 默认只监听 127.0.0.1:8787
cst-agent --web
# 默认只监听 127.0.0.1:8787(健康页 + /api/*)
hermit --web
# 指定端口;0 = 让系统分配(启动日志里会打印实际 URL)
cst-agent --web --web-port 8787
hermit --web --web-port 8787
# 让手机/另一台机器访问(必须给 token,否则拒绝启动在非 loopback 上)
cst-agent --web --web-host 0.0.0.0 --web-token 我自己定的口令
hermit --web --web-host 0.0.0.0 --web-token 我自己定的口令
# 开发前端:直接从目录读 web/,改完刷新页面即可,不用重新编译
cst-agent --web --web-dev ./web
# 开发:读磁盘上的静态目录(健康页或归档 SPA)
hermit --web --web-dev ./web
hermit --web --web-dev archive/web-spa
# 启动后自动打开浏览器
cst-agent --web --web-open
hermit --web --web-open
# 启动即跑一轮(不点页面也能用)
cst-agent --web -p "看看这个仓库有什么问题"
hermit --web -p "看看这个仓库有什么问题"
```
启动日志:
@@ -62,7 +65,8 @@ webui: token 3f9a… (append #token=3f9a… to the URL)
## 引擎 API(协议 `cst-webui/1`)
所有响应都是 JSON(`Content-Type: application/json`)。`GET /api/state` 的
`protocol` 字段给出版本号,客户端应当先看它再决定支持哪些端点。
`protocol` 字段给出版本号;`capabilities` 数组列出本进程会发出的 SSE `type`。
客户端应当先看它们再决定支持哪些端点/事件。
### 事件流
@@ -95,9 +99,11 @@ GET /api/events?since=<seq> → text/event-stream (chunked)
| `permission_done` | `id`,`answer` | 问题已结束(超时/取消也会发) |
| `ask_user` | `id`,`question`,`options[]` | 需要回答 |
| `session` | `id` | 切换/新建了会话,客户端应重新拉 `/api/session` |
| `turn_end` | `rc`,`error` | 本轮结束(`rc=0` 正常,非 0 见 `error`) |
| `turn_begin` | `text` | 一轮开始(用户提示原文);对应 `on_turn_begin` |
| `turn_end` | `rc`,`error` | 本轮结束(`rc=0` 正常,非 0 见 `error`);对应 `on_turn_end` |
| `error` | `kind`,`message` | 结构化错误(`turn` / `cancel` / …);对应 `on_error`,常在 `turn_end` 之前 |
`state` 字段:`workspace` `session` `provider` `model` `effort` `approval`
`state` 字段:`protocol` `capabilities[]` `workspace` `session` `provider` `model` `effort` `approval`
(`ask|auto|yolo`) `plan_mode` `protocol_tools` `status_busy` `todo`
`context_tokens` `undo_available` `pending_images[]` `usage{requests,prompt_tokens,
completion_tokens,cached_tokens,cache_miss_tokens,cost,priced,currency}`