# WebUI(内置 HTTP + SSE 前端) `cst-agent --web` 让同一个进程同时提供命令行以外的前端:浏览器(或任何 HTTP 客户端) 连上后能看到流式回答、工具卡片、审批弹窗和任务清单。它是 TUI 之外的第二个前端, **引擎没有为它改一行**——两边用的都是 `cst_agent_hooks_t` 这组回调。 这份文档同时是**引擎 API v1 的规范**:以后专门客户端(Tauri / Qt / 移动端)直接照它实现, 不需要读 C 代码。 ## 快速开始 ```bash # 默认只监听 127.0.0.1:8787 cst-agent --web # 指定端口;0 = 让系统分配(启动日志里会打印实际 URL) cst-agent --web --web-port 8787 # 让手机/另一台机器访问(必须给 token,否则拒绝启动在非 loopback 上) cst-agent --web --web-host 0.0.0.0 --web-token 我自己定的口令 # 开发前端:直接从目录读 web/,改完刷新页面即可,不用重新编译 cst-agent --web --web-dev ./web # 启动后自动打开浏览器 cst-agent --web --web-open # 启动即跑一轮(不点页面也能用) cst-agent --web -p "看看这个仓库有什么问题" ``` 启动日志: ``` webui: http://127.0.0.1:8787/ webui: token 3f9a… (append #token=3f9a… to the URL) ``` 带 token 时把 `#token=…` 贴到浏览器地址栏后面即可(`#` 之后不会发给服务器, 页面会用 `?token=` 再请求一次)。 环境变量:`CST_WEB_PORT`、`CST_WEB_HOST`、`CST_WEB_TOKEN`、`CST_WEB_ROOT`。 退出:终端里 Ctrl+C,或 `POST /api/quit`。 ## 安全模型 | 场景 | 行为 | |---|---| | 默认 `127.0.0.1` | 不需要 token;`Host` 必须是 loopback(防 DNS rebinding) | | `--web-host 0.0.0.0` | 没给 `--web-token` 时自动生成随机 token 并打印;所有 `/api/*` 都要 token | | token 传递 | `Authorization: Bearer `、`Cookie: cst_token=` 或 `?token=`(`EventSource` 不能设 header,所以查询参数是必需的一条路) | | 资源 | 只有白名单路由;路径里的 `..`/编码 NUL 一律 400;静态资源来自二进制内嵌(或 `--web-dev DIR`) | | 输出渲染 | 模型与工具输出都当不可信内容:Markdown 由服务端渲染,并经过标签/属性白名单(`javascript:` 链接、站外图片、`