Claw Code TUI 增强计划:把 Rust REPL 打造成现代终端界面的分阶段路线图(rusty-claude-cli)
本文基于 Claw Code 仓库中的 TUI 增强计划 展开,系统梳理 rusty-claude-cli 终端界面的现状诊断、六阶段增强方案与架构建议。读完本文,你可以理解该 CLI 的渲染/输入/REPL 三层结构如何与 Rust 工作区各 crate 协作,掌握分阶段(Phase 0–6)落地 TUI 改进的任务分解与优先级,并能结合仓库源码定位到每个结论对应的实现位置。
1. 现状架构:TUI 由哪些 crate 共同支撑
计划文档首先给出了一张工作区 crate 地图,说明终端界面并非单一 crate 的产物,而是五个 crate 协作的结果:
| Crate | 职责 | 规模(计划文档口径) | 与 TUI 的关系 |
|---|---|---|---|
rusty-claude-cli |
主二进制:REPL 循环、参数解析、渲染、API 桥接 | ~3,600 行 | 首要 TUI 表面 |
runtime |
会话、对话循环、配置、权限、压缩 | ~5,300 行 | 提供数据与状态 |
api |
Anthropic HTTP 客户端 + SSE 流式 | ~1,500 行 | 提供流事件 |
commands |
斜杠命令元数据/解析/帮助 | ~470 行 | 驱动命令分发 |
tools |
18 个内置工具实现 | ~3,500 行 | 工具执行展示 |
文档中有一个重要脚注:遗留原型文件 app.rs 与 args.rs 已于 2026-04-05 删除,文中对它们的引用描述的是“未来的抽取目标”,而非当前仓库中真实存在的源文件。这一点在 main.rs 中得到印证——当前的 LiveCli 结构体直接定义在主入口文件内(约第 7,135 行起),而 parse_args() 仍是主文件内的手写解析器(约第 1,479 行)。
1.1 三个核心 TUI 组件
| 组件 | 文件 | 当前行为 | 文档评价 |
|---|---|---|---|
| 输入 | input.rs | 基于 rustyline 的行编辑器:斜杠命令 Tab 补全、Shift+Enter 换行、历史记录 |
✅ 扎实 |
| 渲染 | render.rs | Markdown→终端渲染(标题、列表、表格、带 syntect 高亮的代码块、引用块),spinner 组件 | ✅ 良好 |
| 应用/REPL 循环 | main.rs | 单体 LiveCli 结构体:REPL 循环、全部斜杠命令处理、流式输出、工具调用展示、权限询问、会话管理 |
⚠️ 单体化 |
1.2 关键依赖(以 Cargo.toml 为准)
rusty-claude-cli/Cargo.toml 声明了与计划文档一致的终端相关依赖:
- crossterm 0.28 —— 终端控制(光标、颜色、清屏)
- pulldown-cmark 0.13 —— Markdown 解析
- syntect 5 —— 语法高亮
- rustyline 15 —— 带补全能力的行编辑
- serde_json —— 工具 I/O 格式化
二进制目标名为 claw,即编译后得到的可执行文件。
1.3 源码级印证:组件实现细节
渲染管线:TerminalRenderer 在 render.rs 中持有三样东西——syntect 的 SyntaxSet、语法主题(默认取 base16-ocean.dark),以及终端配色主题 ColorTheme。后者是一个纯结构体(render.rs),字段涵盖 heading、emphasis、strong、inline_code、link、quote、table_border、code_block_border 以及 spinner 的 active/done/failed 三色;Default 实现把标题定为青色、强调为品红、粗体为黄色、行内代码为绿色,恰好对应计划文档指出的“硬编码 ColorTheme::default()、无主题定制”这一短板——所有颜色集中在这一个类型里,也为 Phase 5 的“命名主题”改造预留了明确的挂载点。
Spinner:render.rs 中的 Spinner 维护一个 10 帧的盲文点阵(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏),tick() 使用 crossterm 的 SavePosition/MoveToColumn/Clear(RestorePosition) 序列原地刷新,finish() 与 fail() 分别以 ✔/✘ 收尾——这正是计划文档“优点”一节提到的“工具调用获得 ╭─ name ─╮ 边框、结果展示 ✓/✗ 图标”的实现基础(工具盒的边框字符 ╭─ 出现在 render.rs 附近,并有单元测试断言其输出)。
输入层:input.rs 的 LineEditor 包装 rustyline::Editor,通过 SlashCommandHelper(实现 Completer/Highlighter/Hinter)完成斜杠命令前缀补全,并把 Ctrl+J 与 Shift+Enter 都绑定为换行(Cmd::Newline)。读取结果收敛为 ReadOutcome::{Submit, Cancel, Exit} 三态枚举,接口干净。计划文档 Phase 4.6 中“扩展 SlashCommandHelper 以补全工具参数(/export 后的文件路径、/model 后的模型名)”正是针对这个 completions: Vec<String> 列表的扩展。
1.4 优势与短板
计划文档总结的优势包括:渲染管线结构清晰(状态跟踪、表格渲染、代码高亮);工具展示丰富;15 个斜杠命令覆盖模型切换、权限、会话、配置、diff、导出;完整的会话持久化/恢复/列表/切换/压缩;交互式 Y/N 权限询问;以及覆盖每个格式化函数与解析路径的单元测试。
短板与缺口共 15 条,是整份计划的诊断基础,完整继承如下:
main.rs是 3,159 行的单体——REPL 逻辑、格式化、API 桥接、会话管理与测试全在一个文件- 无备用屏/全屏布局——全部输出为内联滚动
- 无进度条——只有一个盲文 spinner,生成期间看不到流式进度或 token 数
- 无可视化 diff 渲染——
/diff直接倾倒原始 git diff 文本 - 流式输出无语法高亮——Markdown 渲染只作用于工具结果,不作用于助手响应主流
- 无状态栏/HUD——交互过程中看不到模型、token、会话信息
- 无图片/附件预览——
SendUserMessage解析了附件但从不在界面上展示 - 流式输出逐字符且带人为延迟——
stream_markdown每个空白分词 chunk sleep 8ms - 无颜色主题定制——硬编码
ColorTheme::default() - 无窗口尺寸感知——没有换行、截断或布局的尺寸处理
- 历史上的双应用分裂——仓库曾同时存在
CliApp原型与LiveCli,原型已删除,但单体main.rs仍待拆解 - 长输出无分页器——
/status、/config、/memory可能撑爆视口 - 工具结果不可折叠——大段 bash 输出淹没屏幕
- 无思考/推理指示器——模型处于“thinking”模式时缺乏视觉区分
- 工具参数无自动补全——只有斜杠命令名可补全
从当前仓库结构看,短板第 1 条的风险仍在延续:main.rs 如今已增长到近 2 万行(LiveCli 定义约在第 7,135 行),进一步印证了 Phase 0“拆单体”作为一切 TUI 工作前置条件的必要性。
2. 六阶段增强计划(Phase 0–6)
Phase 0:结构清理(地基)
目标:拆解单体、清除死代码、为 TUI 工作建立模块结构。
| 任务 | 内容 | 工作量 |
|---|---|---|
| 0.1 | 把 LiveCli 抽成 app.rs —— 将整个 LiveCli 结构体、其 impl 与辅助函数(format_*、render_*、会话管理)从 main.rs 移入聚焦模块:app.rs(核心)、format.rs(报表格式化)、session_manager.rs(会话 CRUD) |
M |
| 0.2 | 保持旧 CliApp 已删除状态 —— 旧原型已删;若其中有仍然有价值的想法(如流事件处理器模式),应有意识地在新引入的 LiveCli 抽取中重新引入,而不是整体恢复旧文件 |
S |
| 0.3 | 抽取 main.rs 参数解析 —— 当前 parse_args() 仍是 main.rs 中的手写解析器;若日后抽取,应有意识地放入新引入的模块,而不是意外恢复已被删除的 args.rs 原型 |
S |
| 0.4 | 创建 tui/ 模块 —— 引入 crates/rusty-claude-cli/src/tui/mod.rs 作为所有新 TUI 组件的命名空间:status_bar.rs、layout.rs、tool_panel.rs 等 |
S |
Phase 1:状态栏与实时 HUD
目标:交互过程中的持久化信息展示。
| 任务 | 内容 | 工作量 |
|---|---|---|
| 1.1 | 感知终端尺寸的状态行 —— 用 crossterm::terminal::size() 渲染底部固定的状态栏:模型名、权限模式、会话 ID、累计 token 数、估算成本 |
M |
| 1.2 | 实时 token 计数 —— 流式期间随 AssistantEvent::Usage 与 AssistantEvent::TextDelta 事件到达而实时更新状态栏 |
M |
| 1.3 | 回合耗时计时器 —— 展示当前回合已耗时(showTurnDuration 配置已存在于 Config 工具中但尚未接线) |
S |
| 1.4 | Git 分支指示器 —— 在状态栏展示当前 git 分支(仓库中已有 parse_git_status_metadata 完成分支解析) |
S |
从源码看,Phase 1.2 的事件基础已经就位:api crate 的事件类型中既有 TextDelta { text: String }(types.rs)也有 Usage 结构体(types.rs),意味着状态栏所需的增量数据源已经存在,缺的只是展示层。任务 1.3 提到的 showTurnDuration 也可以在实际配置中查到——它作为 ConfigSettingSpec 定义在 tools/src/lib.rs 中。
Phase 2:增强流式输出
目标:让主响应流既视觉丰富又响应迅速。
| 任务 | 内容 | 工作量 |
|---|---|---|
| 2.1 | 实时 Markdown 渲染 —— 不再逐字倾倒原始文本,而是缓冲 text delta 并随到达增量渲染 Markdown(标题检测、粗斜体、行内代码);现有 TerminalRenderer::render_markdown 可改造为增量式 |
L |
| 2.2 | 思考指示器 —— 当扩展思考/推理激活时,显示专属动画指示(如带脉冲点的 🧠 Reasoning... 或不同 spinner),而非通用的 🦀 Thinking... |
S |
| 2.3 | 流式进度条 —— 在 spinner 下方添加可选的水平进度指示(依据 max_tokens 与已产出的 output_tokens 估算完成度) | M |
| 2.4 | 移除人为流式延迟 —— 当前 stream_markdown 每 chunk sleep 8ms;工具结果场景可接受,但主响应流应立即渲染或可配置 |
S |
值得指出的是,当前仓库中已经能观察到这两项任务的落地痕迹:stream_markdown(render.rs)现在的实现是先 markdown_to_ansi 再直写输出,源码中已找不到计划提到的 8ms 逐 chunk sleep——即任务 2.4 的效果已经体现;而增量渲染方面,MarkdownStreamState(render.rs)提供 push(delta)/flush() 接口,内部用 find_stream_safe_boundary(render.rs)寻找“流安全边界”,只在 Markdown 结构不被截断的位置输出已就位的片段——这正是任务 2.1 所描述的“缓冲 delta + 增量渲染”思路的雏形实现。
Phase 3:工具调用可视化
目标:让工具执行可读、可导航。
| 任务 | 内容 | 工作量 |
|---|---|---|
| 3.1 | 可折叠工具输出 —— 结果超过 N 行(可配置,默认 15)时显示摘要加 [+] Expand 提示,按键展开完整输出;初期可实现为截断 + “完整输出已存文件”的降级方案 |
M |
| 3.2 | 工具结果语法高亮 —— 当工具结果含代码(按工具名判定:bash stdout、read_file 内容、REPL 输出)时应用 syntect 高亮而非纯文本 |
M |
| 3.3 | 工具调用时间线 —— 多工具回合结束后展示紧凑摘要:🔧 bash → ✓ | read_file → ✓ | edit_file → ✓ (3 tools, 1.2s) |
S |
| 3.4 | Diff 感知的 edit_file 展示 —— edit_file 成功时显示彩色 unified diff,而不只是一句 ✓ edit_file: path |
M |
| 3.5 | 权限询问增强 —— 用边框字符排版审批提示、给工具名上色、附一行该工具将要做什么的摘要 | S |
任务 3.2 的高亮能力已有现成函数可用:TerminalRenderer::highlight_code(render.rs)按语言 token 查找语法、逐行 highlight_line,并以 24 位色转义加 48;5;236 深色背景渲染——把同一入口接到工具结果流即可。
Phase 4:增强斜杠命令与导航
目标:改善信息展示并补齐缺失功能。
| 任务 | 内容 | 工作量 |
|---|---|---|
| 4.1 | 彩色 /diff 输出 —— 解析 git diff 并按删除/新增渲染红绿色,类似 delta 或 diff-so-fancy |
M |
| 4.2 | 长输出分页器 —— /status、/config、/memory、/diff 输出超过终端高度时,经内部分页器(j/k/q 滚动)或外部 $PAGER |
M |
| 4.3 | /search 命令 —— 按关键词搜索会话历史 |
M |
| 4.4 | /undo 命令 —— 利用 write_file/edit_file 工具结果中的 originalFile 数据回滚最后一次文件编辑 |
M |
| 4.5 | 交互式会话选择器 —— 用可模糊过滤的交互列表(上下键选择、回车切换)替代纯文本 /session list |
L |
| 4.6 | 工具参数 Tab 补全 —— 扩展 SlashCommandHelper:/export 后补全文件路径、/model 后补全模型名、/session switch 后补全会话 ID |
M |
这些命令并非空中楼阁:commands crate 中的 SlashCommand 枚举已经覆盖 /config(支持 env|hooks|model|plugins 分区)、/memory、/diff、/status、/model、/session(list|exists|switch|fork|delete)、/export 等(见 commands/src/lib.rs 的解析与用法字符串),Phase 4 是在既有命令体系上叠加展示层与少量新命令。
Phase 5:颜色主题与配置
目标:用户可定制的视觉外观。
| 任务 | 内容 | 工作量 |
|---|---|---|
| 5.1 | 命名颜色主题 —— 新增 dark(当前默认)、light、solarized、catppuccin 主题,接入既有 Config 工具的 theme 设置 |
M |
| 5.2 | ANSI-256 / truecolor 能力探测 —— 探测终端能力并优雅降级(无彩 → 16 色 → 256 色 → truecolor) | M |
| 5.3 | 可配置 spinner 样式 —— 允许选择盲文点、条形、月相等样式 | S |
| 5.4 | Banner 定制 —— 让 ASCII art 启动横幅可关闭或可配置 | S |
当前 Spinner::FRAMES 是写死的 10 帧盲文序列(render.rs),任务 5.3 的改造点就是把这组常量抽成可注入的配置。
Phase 6:全屏 TUI 模式(Stretch)
目标:面向高级用户的可选备用屏布局。
| 任务 | 内容 | 工作量 |
|---|---|---|
| 6.1 | 引入 ratatui 依赖 —— 作为全屏模式的可选依赖 |
S |
| 6.2 | 分屏布局 —— 上格:带 scrollback 的会话;下格:输入区;右侧栏(可选):工具状态/待办列表 | XL |
| 6.3 | 可滚动会话视图 —— PgUp/PgDn 翻阅历史消息,会话内搜索 | L |
| 6.4 | 快捷键面板 —— ? 呼出显示全部键位的帮助浮层 |
M |
| 6.5 | 鼠标支持 —— 点击展开工具结果、滚动会话、选择文本复制 | L |
截至目前,rusty-claude-cli/Cargo.toml 中尚无 ratatui 依赖或 full-tui feature 声明,说明 Phase 6 尚未启动——与计划“先交付 Phase 0–3 再评估”的节奏一致。
3. 优先级建议
计划文档给出的实施排序是:
立即做(高影响、中等工作量)
- Phase 0 —— 必要的清理。3,159 行的
main.rs是第一维护风险,阻塞一切干净的 TUI 增量开发 - Phase 1.1–1.2 —— 带实时 token 的状态栏。影响力最高的 UX 改进:用户始终想知道 token 用量
- Phase 2.4 —— 移除人为延迟。工作量小、改进立竿见影
- Phase 3.1 —— 可折叠工具输出。大段 bash 输出目前严重破坏可读性
近期(下个 Sprint)
- Phase 2.1 —— 实时 Markdown 渲染,让核心交互显得精致
- Phase 3.2 —— 工具结果语法高亮
- Phase 3.4 —— Diff 感知的编辑展示
- Phase 4.1 ——
/diff彩色输出
长期
- Phase 5 —— 颜色主题(由用户需求驱动)
- Phase 4.2–4.6 —— 增强导航与命令
- Phase 6 —— 全屏模式(工程量大,在前序阶段交付后再评估)
4. Phase 0 之后的目标模块结构与五条设计原则
计划给出的目标目录结构:
crates/rusty-claude-cli/src/
├── main.rs # 仅入口与参数分发(~100 行)
├── args.rs # CLI 参数解析(合并现有两个解析器)
├── app.rs # LiveCli 结构体、REPL 循环、回合执行
├── format.rs # 全部报表格式化(status、cost、model、permissions 等)
├── session_mgr.rs # 会话 CRUD:create、resume、list、switch、persist
├── init.rs # 仓库初始化(不变)
├── input.rs # 行编辑器(不变,少量扩展)
├── render.rs # TerminalRenderer、Spinner(扩展)
└── tui/
├── mod.rs # TUI 模块根
├── status_bar.rs # 底部持久状态行
├── tool_panel.rs # 工具调用可视化(边框、时间线、可折叠)
├── diff_view.rs # 彩色 diff 渲染
├── pager.rs # 长输出内部分页器
└── theme.rs # 颜色主题定义与选择
其中 init.rs、input.rs、render.rs 在当前仓库中已真实存在(init.rs、input.rs、render.rs),tui/ 目录则是待新建的目标命名空间。
关键设计原则(五条,全部继承自原文档):
- 保持内联 REPL 为默认 —— 全屏 TUI 应为显式开启(
--tui标志) - 所有东西可在无终端环境下测试 —— 格式化函数一律接收
&mut impl Write,绝不直接假设 stdout(stream_markdown、Spinner::tick等现有签名正是这一风格的体现) - 流式优先 —— 渲染必须能增量工作,而不是缓冲整个响应
- 终端控制一律走
crossterm—— 不要混合裸 ANSI 转义与 crossterm(原文档指出当前启动横幅处存在这种混用) - 重依赖做 feature 门控 ——
ratatui应放在full-tuifeature flag 之后
5. 风险评估与缓解
| 风险 | 缓解措施 |
|---|---|
| 重构期间弄坏可用 REPL | Phase 0 是纯结构重组,以既有测试覆盖作为安全网 |
| 终端兼容性问题(tmux、SSH、Windows) | 依赖 crossterm 的抽象;在降级环境下实测 |
| 富渲染带来的性能回退 | 前后对比剖析;始终保留快速路径(原始流式) |
| 范围蔓延到 Phase 6 | 先以连贯发布交付 Phase 0–3,再启动 Phase 6 |
历史上的 app.rs 与 main.rs 混淆 |
保持旧原型删除状态,抽取过程中避免意外引入第二个应用表面 |
6. 小结
这份 TUI 增强计划 的价值在于把“CLI 界面如何现代化”拆成了可独立验证的 25+ 个任务,并给每项标了工作量与依赖关系:Phase 0 解耦是地基,Phase 1–2 提供最高性价比的体验提升(状态栏、实时 token、去延迟、增量 Markdown),Phase 3–4 解决工具输出与长信息的可读性,Phase 5–6 把外观定制与全屏模式留作后续。从当前仓库状态交叉验证可以看到该计划正在被吸收:stream_markdown 已无人为 8ms 延迟,MarkdownStreamState 已提供基于安全边界的增量 Markdown 输出,而 ratatui 尚未引入、tui/ 模块尚未建立——即“近期”与“长期”项仍处于待办状态。对于维护者而言,这份计划与其配套源码(main.rs、render.rs、input.rs、commands/src/lib.rs)共同构成了一份可直接落地的 TUI 改造路线图。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00