# Agent Note: 无 gutter bar 的可复制 TUI transcript

Status: implemented

[English](2026-07-27-copyable-transcript-no-gutter-bar.md) | 中文

## Problem

TUI 此前把用户提示词和工具卡片分组在一条彩色左侧 gutter bar（`▌ `）之后，该竖条被逐行加在每一行正文前面，并把 assistant 与系统块整体缩进一列。两者都是逐行前缀：在 transcript 上用鼠标框选时，每一行开头的 `▌ ` 或前导空格都会被一并选中，因此复制一条消息、一段工具输出或一个代码块时都会带上装饰字符，用户必须手动清理。该竖条又是 transcript 中唯一的逐条消息分隔标记，所以不能在没有其他区分方式的情况下直接删掉。

## Decision

transcript 不再带任何逐行前缀。消息仅通过以角色色渲染的粗体带下划线角色标题和空行分隔，而这两者本就由终端在每个块前后自动插入。下划线让每个角色获得清晰的视觉分带，且无需背景填充，因此在任何终端配色下都可读，也绝不会进入剪贴板：

- 用户提示词与 steering 提示词（`UserMessageComponent`）改为普通 `Container`：一行粗体带下划线的强调色 `You` / `Steering` 标题（经共享的 `messageHeader` 辅助函数生成），随后是位于第 0 列的提示词正文。
- Assistant 块渲染一行粗体带下划线的 `Assistant` 标题，随后 reasoning 与文本均在第 0 列渲染，timing 行位于块末尾（原先的 `paddingX = 1` 缩进已移除）。
- 工具卡片去掉 `GutterBox` 包装层。卡片状态（进行中 / 错误 / 成功）对整行标题着色——状态字形（`◌` / `✕` / `✓`）与标题文本共用一种颜色，并同角色标题一样加粗且带下划线——而不再是未着色标题旁的一条彩色竖条。正文无前缀渲染；正文行仍按终端宽度经 `Text` 处理，使过长的原始工具输出换行而非溢出。
- `GutterBox` 类被删除；没有其他地方使用它。

现在对上述任一区域框选，复制得到的正是消息文本本身。

## Alternatives considered

- **仅在用户消息上保留竖条、在工具卡片上去掉** —— 会让最常被复制的工具输出仍然带有污染。已否决：目标是让整个 transcript 都可复制。
- **仅在标题行上加一条顶部横线或竖条** —— 正文复制干净，但选中标题时仍会带上一个字形，且相比带下划线的角色标题并未带来额外的区分收益，却重新引入了装饰字符。
- **用缩进代替竖条对分组正文缩进** —— 前导空格仍会进入剪贴板，无法解决复制问题；已明确排除。
- **在标题上使用填充背景带**（反色，或 256 色柔和背景）—— 能给每个角色一块强烈的色块，但饱和的 ANSI 填充观感过重，且 256 色是固定色而非随主题重映射。下划线以远更轻的方式提供了同样的逐角色区分。

## Consequences

- 从 transcript 复制粘贴无需用户做任何后处理。这正是本次改动的核心收益。
- transcript 比 gutter bar 布局更扁平，但每个角色以角色色渲染的粗体带下划线标题加空行分隔，无需任何左缘填充即可让消息边界保持清晰。工具卡片状态仍通过彩色带下划线的字形与标题保持可读。
- 临时浮层（状态面板、模型选择器、恢复列表）上的制表符边框（`│`）保持不变。它们不属于 transcript 消息内容，且很少被复制。
- 受影响的 keyless TUI `*.expected.txt` 快照均通过 fixture 回放重新记录（无需 API 密钥；所记录的 LLM 会话未变，仅渲染不同）。交互式启动与一次往返提示已在 tmux 中验证。
