# Agent Note: 版本化 TUI 首次运行欢迎页

Status: implemented
Archived: 2026-08-03

[English](2026-07-30-versioned-tui-first-run-welcome.md) | 中文

## 问题

已交付的 `dsh` 终端会直接进入编辑器，没有为首次使用的内部测试者提供持久的产品成熟度说明或反馈渠道指引。现有单行 `welcome` banner 副标题无法容纳指定通知，否则会挤占正常的会话 header；如果把 onboarding 写入会话日志，还会创建一个与用户工作无关的用户轮次或模型可见上下文。

该通知还需要形成具有辨识度的 DeepSeek 视觉构图，同时不能复制其他产品的启动图形，也不能维护一份会偏离官方标志的手绘近似图。

## 决策

官方 `dsh` 启动器在解析后的 `DSH_HOME` 下持有一个版本化确认标记。它会在启动前检查该不可变标记，并仅在真实 TUI 服务可用后，挂载一个由 effect 持有的 `ctx.tui.openOverlay()` 消费方。Enter 是唯一确认操作：插件先创建并同步固定的逐版本标记，再关闭浮层。Escape 和无法识别的输入会让浮层保持打开；Ctrl+C 与 Ctrl+D 通过普通退出路径离开且不确认。资源释放会等待已经由 Enter 启动的确认任务；在按 Enter 前进行资源释放或退出进程不会写入任何内容。版本号属于标记文件名的一部分，因此只需递增集中持有的通知版本，即可让有实质修改的文案重新展示一次，无需迁移或改写聚合设置文档。

该标记属于启动器状态，而非会话持久化，因为展示资格跨越会话与 workspace，但作用域仅限一个 Harness 主目录。每次 Enter 都会先同步一个同目录随机文件，再以原子方式替换固定标记；并发启动发布的是同一个不可变事实，因此同值的最后写入者胜出不会丢失更新，也无需加锁或依赖设置栈。该通知绝不追加会话事件、注入模型上下文或创建用户轮次；因此，恢复会话只会在同一个 Harness 主目录尚未确认该版本时展示通知，也绝不会从会话日志中回放通知。

指定的官方 `24x24` DeepSeek SVG 作为视觉真源提交。静态的完整、紧凑和最小终端栅格图以逐级降低的方形分辨率对该精确路径取样，不会重新绘制轮廓。Unicode `▀`/`▄`/`█` 单元格让每个终端单元格保留两个垂直方向的源像素；明确仅支持 ASCII 的 locale 则使用位级等价的 `'`/`_`/`#` 回退。ANSI 样式与 SVG 和可编辑文案完全分离：`ctx.tui` 提供语义化 `brand` 角色，在真彩色可用时使用官方 `#4D6BFE` 色值，否则使用标准 ANSI 蓝色；禁用颜色时则使用纯文本。普通启动 banner 保留现有渐变。

浮层居中显示，并使用可用的终端宽度；高度则跟随实际内容，仅将 viewport 的 90% 作为上限。宽终端将完整图标置于标题与正文旁边；中等和窄终端把紧凑或最小图标堆叠在正文上方；高度不足时，先移除图标，再减少正文空间。正文可以滚动，而标题和唯一操作保持固定。所有 locale 共用同一份集中持有的中文文案，引用内容会提升为独立的视觉段落，但不会改变该字符串。通过 Enter 关闭浮层后，模态所有权会交还给现有 FIFO 管理器；该管理器恢复编辑器，同时保持正常的启动 banner、transcript（文本记录）和焦点行为不变。

## 验证

聚焦单元测试固定指定 SVG 与中文文案的 hash、版本递增、并发独占确认、格式错误的标记、持久化重试、Escape 行为、ASCII 回退、宽度分级选择、有界渲染和低高度滚动。真实 Loader/PTY 用例覆盖 60、80、120、160 列以及一个低高度 viewport，产出语义终端快照，证明同一个 `DSH_HOME` 下首次启动后再次启动会抑制展示，并证明恢复会话不会追加任何由通知衍生的用户消息或轮次；普通终端退出的生命周期事件保持不变。

## 曾考虑的替代方案

**复用 TUI 的 `welcome` 副标题。** 它是一行瞬态 header，正常职责是标识无标题会话。所需正文和操作要么会被裁剪，要么会永久挤占普通启动界面。

**复制 Claude Code 的启动图形或构图。** 其清晰的视觉层级是有用的产品证据，但图形、布局和品牌处理属于另一个产品。官方 DeepSeek SVG 提供直接的品牌来源，而终端构图围绕本通知的文案与响应式约束独立推导。

**手绘原创鲸鱼。** 自由绘制的轮廓可以具有辨识度，却仍可能与官方标志的身体、内部负空间、鳍和尾部不一致。对精确路径进行栅格取样，可以明确呈现终端限制，并让每个分级都能追溯到同一个源资产。

**在会话事件或共享设置文档中存储布尔值。** 会话状态的生命周期不正确，还会污染回放或模型可见历史。聚合文档为记录一个不可变事实，需要承担跨进程读取、修改、写入锁；以原子方式替换的版本标记不存在更新丢失问题。

**允许 Escape 或稍后提醒操作。** 两者都会让取消与确认无法区分，或引入本通知并不需要的提醒策略。正常退出进程仍是中止路径，并会让该版本保持未确认状态。

## 后果

每个 Harness 主目录在每个文案版本中都会收到一次通知，且仅在用户成功按 Enter 确认后停止展示。维护者可以在一个小型 owner 文件中编辑所有 locale 共用的中文文案和版本，也可以在独立的视觉 owner 中更新官方 SVG 与衍生静态栅格图，无需到各个快照中查找完整正文副本。

终端无法直接显示 SVG 矢量图，因此其忠实呈现受分辨率限制。较小分级会保留取样后的轮廓，但必然损失精细细节；低高度终端优先保障正文可读和操作始终可达，而非展示品牌图形。在预发布阶段，标记格式有意采用每个版本一个文件；旧标记无害，也无需兼容性读取器。
