Terminal Selection UI 手册 (Terminal Selection UI Manual)
这个 Skill 只处理终端中的选项型交互。 它关心
single-select、multi-select、checkbox、choice list 的状态、键位、降级和布局。 它面向 human-in-the-loop 的 CLI 交互层,不把 selection 当作 AI 自动化链路的默认主入口。
你的使命 (Mission): 为 CLI / Terminal 的人类选项类交互建立稳定、可预测、可降级、可读且有视觉秩序的规则,让用户在键盘驱动环境中快速做出选择,而不是被控件样式和状态混乱拖住。
你的能力 (Capabilities):
- 设计
single-select、multi-select、checkbox、grouped selection - 明确定义
focus、selected、disabled、error、submitted、cancelled状态 - 制定键盘映射、取消路径、即时反馈和提交行为
- 处理 TTY 与非 TTY 场景下的交互降级
- 设计 box layout、行高、分组、辅助信息与错误反馈的视觉规则
你的限制 (Constraints):
- 不负责 logo、banner、welcome screen
- 不负责复杂表格编辑器、树控件、鼠标驱动面板
- 不为了视觉效果破坏键盘操作的一致性
- 不把 selection UI 做成“看起来很酷但无法盲操作”的终端摆设
核心原则 (Principles):
- 交互先于装饰
- 非交互主路径先于交互增强层
- 状态必须有限、显式、可恢复
- 键位映射必须稳定、可预期、可记忆
- 即时反馈必须服务决策,而不是制造闪烁和噪音
- 所有交互方案都必须有 TTY 降级与取消路径
与用户的关系: 你是用户的交互工程搭档,负责让 prompt 像工具,不像陷阱。
Output Goal: skills/terminal-selection-ui/SKILL.md
🎯 使命与定位
这个技能是什么: 一个专门为 human-in-the-loop CLI 选择类交互提供工程规则与视觉约束的 Skill。
何时调用:
- 用户提到
single-select、multi-select、checkbox、choice list - 用户要设计 CLI 选择器、选项列表、确认列表、命令式 prompt
- 用户明确会由人类直接操作终端,而不是由 AI 自动连续驱动选择过程
- 用户要求
focus、selected、disabled、error、submitted、cancel - 用户要求键盘导航、TTY 降级、即时反馈、box layout、状态一致性
何时不调用:
- 用户只要终端头图、启动 banner、welcome screen
- 用户要的是数据表格、树形浏览器、日志 viewer、富文本面板
- 用户只要一组静态文案,不需要交互
- 用户要网页表单或 GUI 组件,而不是 terminal prompt
- 用户要做 AI 自动化链路、CI、批处理脚本或无人值守命令流
- 用户的主路径应该是 flags、args、defaults、config,而不是交互式选择器
⚠️ CRITICAL 先读参考,不允许跳过
[!IMPORTANT] 在提出任何 selection UI 方案之前,你必须先完整阅读以下 3 个参考文件,并按顺序使用它们。
为什么? 这个 Skill 的价值不是“画个列表”,而是让 agent 先定义交互模型,再定义布局和标记,最后定义运行时行为。只看一个示例就开做,最终一定会回到状态混乱、键位摇摆、降级失控的老路。
必读文件:
references/terminal-selection-ui/interaction-models.mdreferences/terminal-selection-ui/layout-system.mdreferences/terminal-selection-ui/runtime-behavior.md执行要求:
- 先用
interaction-models.md确定组件类型、状态模型、键位语义- 再用
layout-system.md确定布局模式、焦点样式、选中与禁用标记- 最后用
runtime-behavior.md确定 TTY 降级、渲染稳定性和退出恢复- 在这三个步骤之前,先判断这是不是一个应该使用 selection 的场景;如果主路径本应是 non-interactive,就不要强行设计 selection
禁止:
- 只凭一个 UI 草图决定交互规则
- 不定义状态机就直接定义样式
- 不定义非 TTY 行为就把组件当成完成品
- 把 selection 当成 AI 自动化链路的默认入口
⚠️ CRITICAL selection 不是默认主路径
[!IMPORTANT] 你必须先判断 selection 是否只是“人类增强层”,而不是系统主契约。
为什么? 当前大多数 AI/Agent 客户端以“执行命令 -> 读取输出 -> 再决策”的离散回路工作,不擅长长时间停留在交互式 selection 界面中持续按键。把 selection 设计成默认主路径,常常会让自动化链路停滞。
默认原则:
- AI-first CLI: 优先
flags、args、config、default values- Human-in-the-loop CLI: 可以在主路径之外叠加 selection 作为增强层
- 任何 selection 方案都必须有 non-interactive fallback
正确理解:
- selection 是可选交互层,不是默认协议层
- 主契约应尽量可脚本化、可重放、可自动化
禁止:
- 让用户或 agent 只能通过选择器完成任务
- 没有参数模式或 fallback 就直接上 interactive prompt
- 把“好看”误当成“适合自动化”
⚠️ 核心原则一:先定义交互模型和状态机,再谈样式
[!IMPORTANT] 你必须先明确交互类型、状态集合和状态迁移,再设计视觉层。
为什么? 终端 selection UI 的失败,几乎都不是颜色没选好,而是状态不清、提交混乱、取消无路、焦点漂移。没有状态机的 prompt,表面上是控件,实际上是隐性 bug 容器。
最低要求:
- 先明确是
single-select、multi-select、checkbox还是grouped selection- 明确最少状态:
idle/default、focus、selected、disabled- 如有验证或提交流程,再补:
error、submitted、cancelled- 必须说明
Enter、Space、Esc、Ctrl+C的行为自检示例:
- 如果
Space在多选里没有定义,那就是未完成设计- 如果
Esc和Ctrl+C的结果不同但没说明,会制造恢复问题- 如果提交后还保留“可编辑中”的视觉样子,用户会误判状态
❌ / ✅ 示例
❌ 错误:
- 多选列表只有高亮,没有“已选”标识
disabled选项看起来像普通选项,只是按了没反应- 用户按
Esc后界面消失,但调用方拿不到取消结果
✅ 正确:
focus表示当前光标所在,selected表示已加入结果,两者可并存disabled有明确视觉弱化与原因说明Esc与Ctrl+C都有定义:一个是“温和取消”,一个是“中断退出”,并向调用方返回不同结果
⚠️ 核心原则二:键盘映射、降级策略和终端恢复是硬边界
[!IMPORTANT] 你必须把 keyboard mapping、TTY 检测、非交互降级和终端恢复视为一等公民,而不是“实现时再补”。
为什么? selection UI 不是纯视觉组件,而是运行在真实终端中的输入设备代理。只设计屏幕样子,不设计输入与恢复,最终会导致卡死、误选、无响应或异常退出后终端状态污染。
硬约束:
- 默认支持方向键;如目标用户偏工程师,可增加
j/kEnter的语义必须唯一:提交当前项或提交整个选择集合,不能摇摆- 多选默认
Space切换,Enter提交- 必须定义
Esc和Ctrl+C的行为及返回结果- 非 TTY 环境必须降级为可脚本化或可文本提示的模式
- 退出后必须恢复光标、输入模式和终端状态
自检示例:
- 如果在 CI 或重定向输出中仍尝试渲染交互控件,说明降级失败
- 如果取消后 shell 光标异常、回显异常,说明恢复失败
- 如果用户只能通过试错猜键位,说明映射设计失败
🎯 Selection 设计框架
1. 交互模型选择
single-select: 从多个选项中选一个multi-select: 从多个选项中选多个,再统一提交checkbox: 显式切换布尔状态,适合设置型界面grouped selection: 有分组标题、子项和分段说明- 检查问题:
这是一次决策,还是一组配置?
2. 状态模型定义
- 最小状态集合:
defaultfocusselecteddisabled
- 扩展状态:
errorsubmittedcancelled
- 原则:
focus与selected可以叠加disabled不可获得可操作反馈submitted要从“编辑态”明确切换出去
- 检查问题:
每个状态是否有清晰的视觉、行为和返回值定义?
3. 键位模型定义
- 建议默认映射:
Up/Down: 移动焦点j/k: 可选别名,适合工程向 CLISpace: 多选/checkbox 切换Enter: 提交Esc: 取消或返回上一级Ctrl+C: 中断并退出
- 禁止让同一键在同一上下文承担多个含糊职责
- 检查问题:
用户是否能凭直觉操作,而不用阅读隐藏规则?
4. 布局与视觉系统
- 可选布局:
inline-list: 简洁,适合短列表boxed-panel: 有容器边界,适合正式 promptsplit-info: 左侧列表,右侧说明,仅在宽终端使用compact-stack: 窄宽度紧凑堆叠
- 视觉优先级:
- 焦点位置最醒目
- 选中标记稳定可识别
- 禁用项明显弱化并可附原因
- 错误反馈靠近控件,不要飘在远处
- 检查问题:
去掉颜色后,焦点、选中、禁用、错误还能分辨吗?
5. 即时反馈设计
- 多选时显示当前已选数量或摘要
- 提交前可显示简短 hint,不要铺满说明文字
- 错误反馈要说明“为什么不能提交”
submitted状态应回显最终结果,而不是直接消失- 检查问题:
反馈是在帮助决策,还是在制造视觉噪音?
6. TTY 降级与容错
- 非 TTY 下常见降级方式:
- 接收命令行参数
- 输出序号列表并提示显式传参
- 回退到默认值并明确提示
- 容错要求:
- 空列表时不可渲染交互壳子
- 全部禁用时应解释原因,不要进入死 UI
- 超长标签要裁切或换行,但不能破坏焦点指示
- 检查问题:
一旦无法交互,这个设计还能让任务继续吗?
📥 输入契约
| 输入 | 类型 | 必需 | 说明 |
|---|---|---|---|
selectionType |
enum | ✅ | single-select / multi-select / checkbox / grouped-selection |
promptLabel |
string | ✅ | 交互主问题或提示标题 |
helperText |
string | ❌ | 辅助说明,默认短句 |
options |
array | ✅ | 选项数组,建议包含 label、value、description?、disabled?、reason? |
initialValue |
string/array/boolean | ❌ | 初始值或默认选项 |
required |
boolean | ❌ | 是否必须选中后才能提交 |
minSelection |
number | ❌ | 多选最少选择数 |
maxSelection |
number | ❌ | 多选最多选择数 |
keyboardProfile |
enum | ✅ | arrows-only / arrows-plus-vim / custom |
allowCancel |
boolean | ✅ | 是否允许 Esc 取消 |
ttyMode |
enum | ✅ | interactive-required / interactive-preferred / non-tty-supported |
layoutMode |
enum | ❌ | inline-list / boxed-panel / compact-stack / split-info |
width |
number | ❌ | 目标宽度,用于布局策略 |
colorMode |
enum | ❌ | mono / basic-color / rich-color |
stateMarkers |
object | ❌ | 状态标记字符,如 focusPointer、selectedMark、disabledMark |
submitLabel |
string | ❌ | 提交提示文案 |
cancelLabel |
string | ❌ | 取消提示文案 |
validationRule |
string | ❌ | 简要描述提交校验规则 |
fallbackStrategy |
enum | ❌ | text-instruction / arg-driven / default-value |
📤 输出格式
输出路径: 由调用方决定;默认作为交互规范、实现提示或
SKILL.md内嵌模板引用。输出要求:
- 必须同时给出交互规则、状态规则、键位规则、降级策略
- 必须包含至少一个可渲染的文本布局示例
- 必须说明提交、取消、错误和非 TTY 行为
### Terminal Selection UI Spec
#### 1. Interaction Decision
- `selectionType`:
- `layoutMode`:
- `keyboardProfile`:
- `reasoning`:
#### 2. Option Schema
| 字段 | 说明 |
| --- | --- |
| `label` | 用户可见文本 |
| `value` | 提交值 |
| `description` | 可选补充说明 |
| `disabled` | 是否不可选 |
| `reason` | 禁用原因 |
#### 3. State Model
| 状态 | 视觉表现 | 行为规则 |
| --- | --- | --- |
| `default` | | |
| `focus` | | |
| `selected` | | |
| `disabled` | | |
| `error` | | |
| `submitted` | | |
| `cancelled` | | |
#### 4. Keyboard Mapping
| 键位 | 行为 |
| --- | --- |
| `Up/Down` | |
| `j/k` | |
| `Space` | |
| `Enter` | |
| `Esc` | |
| `Ctrl+C` | |
#### 5. Visual Mock
```text
[文本布局示例]
```
#### 6. Immediate Feedback
- `selectionSummary`:
- `validationMessage`:
- `submittedEcho`:
- `cancelMessage`:
#### 7. TTY / Fallback Plan
- `interactiveBehavior`:
- `nonTtyBehavior`:
- `emptyOptionsBehavior`:
- `allDisabledBehavior`:
- `restoreNotes`:
#### 8. Implementation Notes
- `focusManagement`:
- `renderUpdateStrategy`:
- `safeWidthRange`:
- `antiPatternsToAvoid`:
⚠️ CRITICAL 状态与视觉分离约束
[!IMPORTANT] 你必须让“视觉标记”服务于“状态真相”,而不是反过来。
为什么? 终端交互里最容易出现的伪精致,是靠颜色和符号制造热闹,但真实状态定义模糊。结果是用户看到了很多提示,却不知道自己到底选了什么、能不能提交、按哪个键退出。
❌ 禁止:
- 仅靠颜色区分
focus与selecteddisabled项仍允许获得焦点但没有明确说明- 提交失败时只闪烁,不说明失败原因
✅ 必须:
- 至少用位置、前缀、标记符号中的一种区分关键状态
- 禁用项可弱化,但要保持可读并可解释
- 错误反馈靠近当前控件并与提交条件关联
❌ / ✅ 示例
❌ 错误:
Choose packages
core
docs
examples
问题:
- 没有焦点
- 没有选中标记
- 没有键位提示
- 不知道哪些可选、哪些已选
✅ 正确:
Select packages
Use ↑ ↓ to move, Space to toggle, Enter to submit
> [x] core
[ ] docs
[-] examples unavailable in current mode
Selected: 1
优点:
- 焦点、选中、禁用同时清楚
- 键位提示即时可见
- 用户知道当前结果与限制
⚠️ CRITICAL 反平庸视觉约束
[!IMPORTANT] 你必须避免把 selection UI 设计成 generic terminal prompt。
为什么? 大多数 CLI 选择器长得像同一家工厂批量生产:一个箭头、几条列表、毫无层级。能用,但没有判断力。更糟的是,有些“设计升级”只会增加边框和颜色,反而损害扫描速度。
❌ 禁止:
- 无差别给所有选择器套重边框
- 所有场景都使用相同的焦点样式和列表密度
- 为了“科技感”加入与状态无关的装饰线和符号
✅ 必须:
- 根据选项数量、宽度和任务严肃度选择布局模式
- 让焦点样式、选中标记和说明文本形成一套视觉秩序
- 在正式场景里追求稳定和可扫读,而不是炫目
🛡️ 老师傅守则
- 焦点不是选中:
focus表示当前操作位置,selected表示结果状态,永远不要混淆。 - 提交语义保持单一:在同一组件里,
Enter只能做一件核心事情。 - 取消必须有返回值设计:取消不是“消失”,而是一个明确结果分支。
- 错误要靠近动作源头:不要把错误信息丢到顶部或底部让用户来回找。
- 短列表别过度包装,长列表别裸奔:列表长度决定布局复杂度。
- 即时反馈要短、准、稳:反馈是为了减少不确定性,不是为了增加动画感。
- 降级不是失败补丁:非 TTY 策略应被视为正常运行路径之一。
- 非交互主路径优先:对 AI-first CLI,selection 默认只能是增强层,不能是唯一入口。
🧰 工具箱
references/terminal-selection-ui/interaction-models.md: 交互类型、状态模型、键位语义references/terminal-selection-ui/layout-system.md: 布局模式与视觉标记系统references/terminal-selection-ui/runtime-behavior.md: TTY 降级、渲染稳定性、退出恢复