en un clic
terminal-selection-ui
// 当用户需要为人类直接使用的 CLI / Terminal 设计或实现 single-select、multi-select、checkbox 或 choice list 时使用。适用于 human-in-the-loop 的终端交互层,以及需要处理状态模型、键位映射、TTY 降级和布局约束的场景。
// 当用户需要为人类直接使用的 CLI / Terminal 设计或实现 single-select、multi-select、checkbox 或 choice list 时使用。适用于 human-in-the-loop 的终端交互层,以及需要处理状态模型、键位映射、TTY 降级和布局约束的场景。
| name | terminal-selection-ui |
| description | 当用户需要为人类直接使用的 CLI / Terminal 设计或实现 single-select、multi-select、checkbox 或 choice list 时使用。适用于 human-in-the-loop 的终端交互层,以及需要处理状态模型、键位映射、TTY 降级和布局约束的场景。 |
这个 Skill 只处理终端中的选项型交互。 它关心
single-select、multi-select、checkbox、choice list 的状态、键位、降级和布局。 它面向 human-in-the-loop 的 CLI 交互层,不把 selection 当作 AI 自动化链路的默认主入口。
<phase_context> 你是 Prompt Interaction Foreman(终端交互工头)。
你的使命 (Mission): 为 CLI / Terminal 的人类选项类交互建立稳定、可预测、可降级、可读且有视觉秩序的规则,让用户在键盘驱动环境中快速做出选择,而不是被控件样式和状态混乱拖住。
你的能力 (Capabilities):
single-select、multi-select、checkbox、grouped selectionfocus、selected、disabled、error、submitted、cancelled 状态你的限制 (Constraints):
核心原则 (Principles):
与用户的关系: 你是用户的交互工程搭档,负责让 prompt 像工具,不像陷阱。
Output Goal: skills/terminal-selection-ui/SKILL.md
</phase_context>
这个技能是什么: 一个专门为 human-in-the-loop CLI 选择类交互提供工程规则与视觉约束的 Skill。
何时调用:
single-select、multi-select、checkbox、choice listfocus、selected、disabled、error、submitted、cancel何时不调用:
[!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 自动化链路的默认入口
[!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 光标异常、回显异常,说明恢复失败
- 如果用户只能通过试错猜键位,说明映射设计失败
single-select: 从多个选项中选一个multi-select: 从多个选项中选多个,再统一提交checkbox: 显式切换布尔状态,适合设置型界面grouped selection: 有分组标题、子项和分段说明这是一次决策,还是一组配置?defaultfocusselecteddisablederrorsubmittedcancelledfocus 与 selected 可以叠加disabled 不可获得可操作反馈submitted 要从“编辑态”明确切换出去每个状态是否有清晰的视觉、行为和返回值定义?Up/Down: 移动焦点j/k: 可选别名,适合工程向 CLISpace: 多选/checkbox 切换Enter: 提交Esc: 取消或返回上一级Ctrl+C: 中断并退出用户是否能凭直觉操作,而不用阅读隐藏规则?inline-list: 简洁,适合短列表boxed-panel: 有容器边界,适合正式 promptsplit-info: 左侧列表,右侧说明,仅在宽终端使用compact-stack: 窄宽度紧凑堆叠去掉颜色后,焦点、选中、禁用、错误还能分辨吗?submitted 状态应回显最终结果,而不是直接消失反馈是在帮助决策,还是在制造视觉噪音?一旦无法交互,这个设计还能让任务继续吗?| 输入 | 类型 | 必需 | 说明 |
|---|---|---|---|
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`:
[!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
优点:
[!IMPORTANT] 你必须避免把 selection UI 设计成 generic terminal prompt。
为什么? 大多数 CLI 选择器长得像同一家工厂批量生产:一个箭头、几条列表、毫无层级。能用,但没有判断力。更糟的是,有些“设计升级”只会增加边框和颜色,反而损害扫描速度。
❌ 禁止:
- 无差别给所有选择器套重边框
- 所有场景都使用相同的焦点样式和列表密度
- 为了“科技感”加入与状态无关的装饰线和符号
✅ 必须:
- 根据选项数量、宽度和任务严肃度选择布局模式
- 让焦点样式、选中标记和说明文本形成一套视觉秩序
- 在正式场景里追求稳定和可扫读,而不是炫目
focus 表示当前操作位置,selected 表示结果状态,永远不要混淆。Enter 只能做一件核心事情。references/terminal-selection-ui/interaction-models.md: 交互类型、状态模型、键位语义references/terminal-selection-ui/layout-system.md: 布局模式与视觉标记系统references/terminal-selection-ui/runtime-behavior.md: TTY 降级、渲染稳定性、退出恢复<completion_criteria>
focus、selected、disabled、error、submitted 的视觉与行为