RFC: NeoCode TUI v2 — Ghost Console 独立实现
- RFC ID: NEO-RFC-001
- 状态: 草案
- 日期: 2026-05-18
- 作者: NeoCode Team
- 涉及模块:
cmd/neocode-tuiv2, internal/tuiv2(含 gateway/、fakegateway/ 子包)
摘要
本 RFC 提议为 NeoCode 新增 TUI v2(Ghost Console),作为与当前 TUI v1 并行独立 的第二套终端界面。TUI v2 采用独立二进制(neocode-tuiv2),通过 GatewayClient 接口契约与后端解耦,现阶段使用 FakeGatewayClient 进行设计验证,后续替换为真实 Gateway JSON-RPC 客户端。
TUI v1 保持不变,不受任何影响。
动机:为什么要做 TUI v2
当前痛点
TUI v1(internal/tui/)功能完整但存在结构性瓶颈:
- 视觉语言不统一:混用面板边框、内联消息、弹窗,缺乏一致的设计语言。大量
┌ ┐ ├ ┤ │ 字符产生"低配 IDE/后台管理"感。
- 信息层级不清晰:所有消息线性排列,长时间会话中难以快速定位关键信息。
- 组件高度耦合:
update.go 7603 行,view.go 985 行,app.go 458 行 — 修改风险高、测试困难、新人理解成本高。
- 键位系统不够灵活:单一输入模式,缺乏 Vim 风格的双模式操作(Normal Mode / Input Mode / Leader Key)。
- 缺乏产品气质:"能用的终端工具" vs "为 Agent 编程设计的黑客控制台"。
为什么不能渐进改造 v1
- 键位系统不兼容:v2 的
Esc=Normal Mode、Shift+Enter=换行、Ctrl+C=取消/双退 等语义与 v1 的 Esc=聚焦输入、Ctrl+J=换行、Ctrl+W=取消运行 完全冲突。两套键位语义无法共存于同一套 keyMap。
- 组件架构差异大:v2 采用独立的
tea.Model 子组件 + 集中式 ViewModel,v1 的 App struct 承载几乎所有状态。渐进式拆分 v1 的风险等同于重写。
- 零风险共存:v1 是稳定版本,用户不应被迫接受任何变更。v2 独立二进制允许用户自主选择。
设计概览
视觉方向:Ghost Console
终端原生 · 黑客控制台 · 命令界面 · Agent 行为流 · 环境状态
核心原则:
- 默认不画框 — 线框仅用于命令面板、帮助、会话选择器、危险确认、diff 预览、错误详情
- 语义标签代替标题栏 —
tool.read_file 而非 ┌─ Tool Call ─┐
- 状态符号建立节奏 —
✓ ◉ ○ ◌ × · 比进度条更终端原生
- 缩进表达层级 — 不用表格和竖线
- 单布局自动响应 — Focus-Only 布局随终端宽度自动调整,Soft Inspector ≥100 列自动显示/隐藏
键位系统:三层模式
| 层 |
进入 |
职责 |
| Input Mode |
默认 / Normal i |
输入、发送、命令 |
| Normal Mode |
Esc |
导航、搜索、:q 退出 |
| Leader Key |
Normal 下 Space |
Space p 面板, Space n 新会话等 |
与 v1 完全不兼容。
架构边界
neocode-tuiv2 (独立二进制)
└── internal/tuiv2/ (TUI v2 App)
├── gateway/ (Client 接口 + DTO + 真实适配器)
└── fakegateway/ (FakeClient + 场景)
TUI v2 禁止直接访问:
✗ internal/runtime
✗ internal/session
✗ internal/repository
✗ SQLite
构建策略:独立二进制
neocode # TUI v1(稳定,不动)
neocode-tuiv2 # TUI v2(新入口,默认 fake backend)
cmd/neocode/ — 不变
cmd/neocode-tuiv2/ — 新增,仅启动 TUI v2
- 同一仓库,同一
go.mod,独立入口
开发策略:FakeGatewayClient 驱动
TUI v2 从第一天就按真实架构写,所有数据来自 gateway.Client 接口。当前阶段 FakeGatewayClient 提供可控的假数据。
neocode-tuiv2 --scenario=default # 完整 Ghost Console 演示
neocode-tuiv2 --scenario=tool_approval # 权限审批流程
neocode-tuiv2 --scenario=gateway_offline # 离线/错误状态
这确保了后续替换真实 Gateway 时,TUI 代码零改动——只需换一个 Client 实现。
为什么这么做
为什么用 FakeGatewayClient 而不是 FakeRuntime
FakeRuntime 会让 TUI 组件直接依赖 Runtime 领域类型,破坏架构边界。FakeGatewayClient 模拟的是 Gateway 的对外契约(RPC 方法 + 事件流),TUI 只看到 DTO 和事件,不知道 Gateway 背后是什么。
为什么是独立二进制而不是 CLI flag
- v1 入口零改动,零风险
- v2 可以独立发布、独立测试、独立回滚
- 两个二进制可以同时运行(不同终端窗口),方便对比测试
为什么权限和 ask_user 不弹窗
权限确认和 ask_user 属于对话流内的交互,弹窗会打断用户对 Stream 上下文的感知。两者统一在底部 prompt 区域以内联方式处理,保持 Agent 行为流的连续性。
弹窗仅用于需要独立交互空间的场景:命令面板(搜索优先)、帮助(分组信息多)、会话选择(列表搜索)、危险操作确认(防误操作)。
实施阶段
完整 22 个阶段详见子issue。按优先级:
| 优先级 |
阶段 |
目标 |
| P0 |
Phase 0–9 |
骨架 + FakeGateway + 布局 + Stream/Prompt + 键位 + 核心流程 |
| P1 |
Phase 10–16 |
命令面板 + 弹窗 + 会话/模型闭环 + 鼠标 + 响应式 + 测试 |
| P2 |
Phase 17–22 |
真实 Gateway + 联调 + 打磨 + 发布 |
MVP 范围:Phase 0–9 子集,做到独立运行 + Ghost Console 视觉 + streaming + 基础键位即可验证设计方向。
验收标准
相关文档
| 文档 |
路径 |
| 架构导航 |
docs/tui-v2/tui-v2-architecture-hub.md |
| UI/UX 规范 |
docs/tui-v2/tui-v2-ui-ux-design.md |
| 数据与 Gateway 契约 |
docs/tui-v2/tui-v2-data-and-gateway.md |
| 工程实现指南 |
docs/tui-v2/tui-v2-implementation-guide.md |
| HTML 视觉原型 |
docs/design/tui-v2-terminal-preview.html |
RFC: NeoCode TUI v2 — Ghost Console 独立实现
cmd/neocode-tuiv2,internal/tuiv2(含gateway/、fakegateway/子包)摘要
本 RFC 提议为 NeoCode 新增 TUI v2(Ghost Console),作为与当前 TUI v1 并行独立 的第二套终端界面。TUI v2 采用独立二进制(
neocode-tuiv2),通过GatewayClient接口契约与后端解耦,现阶段使用FakeGatewayClient进行设计验证,后续替换为真实 Gateway JSON-RPC 客户端。TUI v1 保持不变,不受任何影响。
动机:为什么要做 TUI v2
当前痛点
TUI v1(
internal/tui/)功能完整但存在结构性瓶颈:┌ ┐ ├ ┤ │字符产生"低配 IDE/后台管理"感。update.go7603 行,view.go985 行,app.go458 行 — 修改风险高、测试困难、新人理解成本高。为什么不能渐进改造 v1
Esc=Normal Mode、Shift+Enter=换行、Ctrl+C=取消/双退 等语义与 v1 的Esc=聚焦输入、Ctrl+J=换行、Ctrl+W=取消运行 完全冲突。两套键位语义无法共存于同一套keyMap。tea.Model子组件 + 集中式 ViewModel,v1 的 App struct 承载几乎所有状态。渐进式拆分 v1 的风险等同于重写。设计概览
视觉方向:Ghost Console
终端原生 · 黑客控制台 · 命令界面 · Agent 行为流 · 环境状态
核心原则:
tool.read_file而非┌─ Tool Call ─┐✓ ◉ ○ ◌ × ·比进度条更终端原生键位系统:三层模式
iEsc:q退出SpaceSpace p面板,Space n新会话等与 v1 完全不兼容。
架构边界
构建策略:独立二进制
cmd/neocode/— 不变cmd/neocode-tuiv2/— 新增,仅启动 TUI v2go.mod,独立入口开发策略:FakeGatewayClient 驱动
TUI v2 从第一天就按真实架构写,所有数据来自
gateway.Client接口。当前阶段FakeGatewayClient提供可控的假数据。这确保了后续替换真实 Gateway 时,TUI 代码零改动——只需换一个
Client实现。为什么这么做
为什么用 FakeGatewayClient 而不是 FakeRuntime
FakeRuntime会让 TUI 组件直接依赖 Runtime 领域类型,破坏架构边界。FakeGatewayClient模拟的是 Gateway 的对外契约(RPC 方法 + 事件流),TUI 只看到 DTO 和事件,不知道 Gateway 背后是什么。为什么是独立二进制而不是 CLI flag
为什么权限和 ask_user 不弹窗
权限确认和 ask_user 属于对话流内的交互,弹窗会打断用户对 Stream 上下文的感知。两者统一在底部 prompt 区域以内联方式处理,保持 Agent 行为流的连续性。
弹窗仅用于需要独立交互空间的场景:命令面板(搜索优先)、帮助(分组信息多)、会话选择(列表搜索)、危险操作确认(防误操作)。
实施阶段
完整 22 个阶段详见子issue。按优先级:
MVP 范围:Phase 0–9 子集,做到独立运行 + Ghost Console 视觉 + streaming + 基础键位即可验证设计方向。
验收标准
neocode-tuiv2可独立运行,不影响neocodeinternal/runtime,internal/session,internal/repository, SQLitegateway.Client接口--scenario切换相关文档
docs/tui-v2/tui-v2-architecture-hub.mddocs/tui-v2/tui-v2-ui-ux-design.mddocs/tui-v2/tui-v2-data-and-gateway.mddocs/tui-v2/tui-v2-implementation-guide.mddocs/design/tui-v2-terminal-preview.html