3.2 万行手写终端 UI,是本仓库最容易被质疑的投入。判断它值不值,要先看它解决的问题有多特殊。
Minimal terminal UI framework with differential rendering and synchronized output
for flicker-free interactive CLI applications.
- **Differential Rendering**: Updates only changed lines or viewport rows
- **Application-owned Scrolling**: Alternate-screen viewport supports mouse, trackpad, …
packages/tui 的 @earendil-works/* 内部依赖为空,也不依赖 React。它不知道 LLM、agent、会话的存在——第 01 章那张依赖图里唯一一个「叶子」级的大包。
这带来一个实际结果:它是这个仓库里最容易被单独拿走用的部分,而且 coding-agent 的无头模式(第 14 章)不需要 mock 掉任何 UI——直接不加载它就行。
packages/tui/native/darwin 与 native/win32 各有一份 README——说明为了终端行为一致性,某些平台特性下沉到了原生层。这是「自己写 UI 库」成本的一部分:你要为每个平台的终端怪癖负责。
Ink(React for CLI)之类的方案针对的是「表单、进度条、列表」这类结构化且更新局部的 UI。agent 的输出形态不同:
「只更新变化的行」+「一帧原子输出」正好对着这四条。用通用框架也能做,但你会花大量时间对抗它的重绘模型——而重绘模型正是这里唯一重要的东西。
3.2 万行 + 两个平台的原生模块 + 终端兼容性的长尾(docs/terminal-setup.md、docs/tmux.md、docs/termux.md、docs/windows.md 四份文档专门讲这个)。这是一条只有在「终端体验就是产品」时才划算的路。
对照 第 15 章:pi 拒绝做权限系统的理由是「做不彻底不如不做」;这里的选择是反过来的——终端体验做不彻底也不如不做,所以做彻底。判据一致:看这件事是不是产品的核心。
场景你的 agent CLI 每秒几十次 token 级更新,用户还会往回滚动看历史。直接用 Ink(React for CLI)最先撞到的问题是什么?
B。pi 自研 TUI 的判据就是「重绘模型是不是你要解决的主要问题」。是——就自己写;不是——用现成的。
场景把 @earendil-works/pi-tui 装进自己的项目,它会带上什么依赖?
C。tui 是依赖图里唯一的「叶子」级大包,不知道 LLM 的存在——这也是它最容易被单独复用的原因。
ac4ac9e(2026-08-07 快照)。