## 新增:基于 React/Ink 的 CLI 终端(cli/)
使用 Ink 框架构建完整的终端 UI,取代原有的纯 print 交互方式:
- App.tsx:主应用组件,管理对话状态、任务轮询、键盘输入、slash 命令
- components.tsx:Timeline、Composer、StatusLine、Picker、SlashMenu 等全部 UI 组件
- eventMapper.ts:将后端 SSE 事件流映射为 Timeline 条目,支持 thinking/tool/assistant/sub_agent 等类型
- api.ts:封装所有后端 REST 接口(任务、对话、模型、权限、工作区等)
- commands.ts:slash 命令定义(/new /resume /model /permission /execution /workspace /compact /tools 等)
- workspaces.ts:本地工作区目录的持久化管理
- types.ts:所有共享类型定义
- format.ts:context 格式化、路径缩写等工具函数
## 重大修复:去除固定高度全屏模式,恢复滚轮滚动
**问题根因**:根 Box 设置了 `height={stdout.rows}` 使 Ink 进入原地重绘模式
(类似 vim/htop),所有内容在同一块屏幕区域反复擦写,永远不会真正
"滚出"屏幕顶部,导致 terminal 的 scrollback buffer 始终为空,鼠标
滚轮无任何响应。
**修复方案**:
- 移除根 Box 的 `height` 约束和 `overflow="hidden"`
- 移除内层 Box 的 `flexGrow`/`justifyContent="flex-end"` 全屏布局
- Timeline 不再做行数截断,直接渲染全部条目
- 内容自然流入 terminal scrollback buffer,鼠标滚轮恢复正常
**同步清理**:删除 `getTimelineMaxRows`、`estimateTimelineRows`、
`scrollOffset` 状态及方向键滚动逻辑(这些都是全屏模式下的补丁,
去除固定高度后不再需要)
## 修复:Composer 光标位置偏移一行
`setCursorPosition` 中 y 轴使用 `lines.length` 导致单行时偏移 +1。
改为 `lines.length - 1`,与实际最后一行渲染位置对齐。
## 其他
- AGENTS.md / README.md:补充 CLI 启动方式与架构说明
- server/chat.py:补充任务轮询接口所需字段
- package.json:新增 cli 相关脚本入口
- docs/cli_slash_commands_spec.md、docs/cli_ui_display_spec.md:CLI 设计文档
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
765 lines
13 KiB
Markdown
765 lines
13 KiB
Markdown
# CLI Slash 命令设计规范(草案)
|
||
|
||
> 目标:定义 CLI 中 `/` 命令的命名、交互方式、显示方式与最小功能集。
|
||
> 关联文档:`docs/cli_ui_display_spec.md`
|
||
|
||
## 1. 总体原则
|
||
|
||
1. **所有主动操作都从 `/` 命令进入**:避免额外快捷键过多导致记忆负担。
|
||
2. **命令面板统一交互**:输入过滤、上下选择、Enter 确认。
|
||
3. **没有必要的命令不做**:后台内部操作、配置文件管理、文件浏览等不暴露成命令。
|
||
4. **审批不做独立命令**:有审批时直接占用输入栏显示审批交互。
|
||
5. **命令只负责 UI 入口**:真正执行仍通过后端 API / CLI 适配层完成。
|
||
|
||
---
|
||
|
||
## 2. 启动命令与工作区初始化
|
||
|
||
### 2.1 启动命令
|
||
|
||
正式启动命令建议为:
|
||
|
||
```bash
|
||
agents
|
||
```
|
||
|
||
开发期或兼容别名可保留:
|
||
|
||
```bash
|
||
agents-cli
|
||
```
|
||
|
||
命名理由:
|
||
|
||
- 和项目名一致
|
||
- 短、好记
|
||
- 类似 `codex` / `claude` 的产品级 CLI 命令
|
||
- 比 `agent` 更不容易和泛称混淆
|
||
|
||
### 2.2 默认工作区目录
|
||
|
||
用户在任意目录执行:
|
||
|
||
```bash
|
||
cd /Users/jojo/Desktop/test
|
||
agents
|
||
```
|
||
|
||
CLI 默认使用 `process.cwd()` 作为本次启动的工作区目录。
|
||
|
||
### 2.3 当前目录已是工作区
|
||
|
||
如果当前目录已经存在于工作区列表中:
|
||
|
||
1. 自动选择该工作区
|
||
2. 进入 CLI 主界面
|
||
|
||
### 2.4 当前目录不是工作区
|
||
|
||
如果当前目录不在工作区列表中,启动时先显示确认提示:
|
||
|
||
```text
|
||
当前目录尚未添加为工作区:
|
||
|
||
/Users/jojo/Desktop/test
|
||
|
||
Agent 将在此目录中读取文件、执行命令和修改内容。
|
||
是否将此目录添加为工作区?
|
||
|
||
› 1. 确认,添加并继续
|
||
2. 拒绝,退出
|
||
```
|
||
|
||
选择 `确认`:
|
||
|
||
```text
|
||
• 已添加工作区 test
|
||
└ /Users/jojo/Desktop/test
|
||
```
|
||
|
||
然后进入 CLI 主界面。
|
||
|
||
选择 `拒绝`:
|
||
|
||
```text
|
||
已取消,退出 Agents CLI。
|
||
```
|
||
|
||
并退出程序。
|
||
|
||
### 2.5 工作区匹配规则
|
||
|
||
v1 只做精确路径匹配:
|
||
|
||
- 当前目录路径与已有工作区路径完全一致:视为已有工作区
|
||
- 当前目录是已有工作区的子目录:仍视为新目录,需要确认是否添加
|
||
|
||
这样可以保证行为明确:
|
||
|
||
> 在哪个目录启动,Agent 就在哪个目录工作。
|
||
|
||
### 2.6 自动工作区名称
|
||
|
||
自动创建工作区时:
|
||
|
||
- 默认名称使用目录 basename
|
||
- 如 `/Users/jojo/Desktop/test` → `test`
|
||
- 如果名称重复,可自动追加序号,例如 `test-2`
|
||
|
||
---
|
||
|
||
## 3. 命令面板交互
|
||
|
||
### 3.1 触发
|
||
|
||
用户在输入栏输入 `/` 后打开命令面板。
|
||
|
||
```text
|
||
› /
|
||
```
|
||
|
||
输入更多字符后实时过滤:
|
||
|
||
```text
|
||
› /a
|
||
|
||
/compact 压缩当前对话上下文
|
||
› /path 管理路径授权
|
||
/permission 切换权限模式
|
||
```
|
||
|
||
### 3.2 选择
|
||
|
||
- `↑` / `↓` 切换当前选中项
|
||
- 当前选中项使用高亮颜色
|
||
- `Enter` 执行当前命令
|
||
- `Esc` 关闭命令面板
|
||
|
||
### 3.3 展示格式
|
||
|
||
```text
|
||
› /mo
|
||
|
||
› /model 切换模型与思考模式
|
||
```
|
||
|
||
格式规则:
|
||
|
||
- 左侧显示命令名
|
||
- 右侧显示简短说明
|
||
- 说明必须短,不超过一行
|
||
|
||
---
|
||
|
||
## 4. 最终命令清单
|
||
|
||
| 命令 | 说明 | 类型 |
|
||
|---|---|---|
|
||
| `/new` | 新建对话 | 立即执行 / 可确认 |
|
||
| `/resume` | 查看对话列表并切换对话 | 选择器 |
|
||
| `/model` | 切换模型与思考模式 | 选择器 |
|
||
| `/versioning` | 管理版本控制 | 选择器 |
|
||
| `/permission` | 切换权限模式 | 选择器 |
|
||
| `/execution` | 切换执行环境 | 选择器 |
|
||
| `/workspace` | 选择或切换工作区 | 选择器 |
|
||
| `/compact` | 压缩当前对话上下文 | 立即执行 / 可确认 |
|
||
| `/tools` | 启用或禁用工具 | 选择器 |
|
||
| `/path` | 管理路径授权 | 选择器 / 表单 |
|
||
| `/skill` | 选择本轮要使用的 skill | 选择器 |
|
||
| `/status` | 查看当前状态 | 信息面板 |
|
||
| `/help` | 查看命令帮助 | 信息面板 |
|
||
| `/clear` | 清空当前 CLI 显示 | 立即执行 |
|
||
| `/exit` | 退出 CLI | 立即执行 / 可确认 |
|
||
|
||
---
|
||
|
||
## 5. 不做的命令
|
||
|
||
以下命令不做:
|
||
|
||
| 命令 | 不做原因 |
|
||
|---|---|
|
||
| `/approval` | 有待审批内容时直接在输入栏显示审批交互,无需手动进入 |
|
||
| `/memory` | 属于后端/Agent 内部操作,不作为 CLI 常用入口 |
|
||
| `/files` | CLI 不做文件浏览器,文件操作由 Agent 工具执行 |
|
||
| `/tasks` | 后台任务数量放在底部状态栏;详细逻辑先不暴露 |
|
||
| `/focus` | 暂不做额外显示模式 |
|
||
|
||
---
|
||
|
||
## 6. 各命令详细设计
|
||
|
||
### 6.1 `/new`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/new 新建对话
|
||
```
|
||
|
||
行为:
|
||
|
||
- 创建一个空白对话
|
||
- 清空当前 CLI 消息区
|
||
- 切换到底部输入待命态
|
||
|
||
如果当前有未完成任务:
|
||
|
||
```text
|
||
当前任务仍在运行,是否新建对话?
|
||
|
||
› 1. 新建并停止当前任务
|
||
2. 等待当前任务完成
|
||
3. 取消
|
||
```
|
||
|
||
---
|
||
|
||
### 6.2 `/resume`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/resume 查看对话列表并切换对话
|
||
```
|
||
|
||
行为:
|
||
|
||
- 打开历史对话选择器
|
||
- 显示最近对话
|
||
- 选择后切换当前会话
|
||
|
||
显示示例:
|
||
|
||
```text
|
||
Resume conversation
|
||
|
||
› 今天 14:32 修复 CLI 设计文档
|
||
今天 13:10 调研 Claude Code CLI
|
||
昨天 22:45 Android 发布联动
|
||
```
|
||
|
||
字段建议:
|
||
|
||
- 时间
|
||
- 对话标题 / 首条用户消息摘要
|
||
- 当前工作区(可选)
|
||
- 模型(可选)
|
||
|
||
---
|
||
|
||
### 6.3 `/model`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/model 切换模型与思考模式
|
||
```
|
||
|
||
行为:
|
||
|
||
- 打开模型选择器
|
||
- 支持模型和运行模式一起切换
|
||
|
||
显示示例:
|
||
|
||
```text
|
||
Model
|
||
|
||
› 1. kimi-k2.5 当前模型
|
||
2. gpt-5.5 高质量编码
|
||
3. gpt-5.4-mini 快速低成本
|
||
|
||
Run mode
|
||
|
||
› 1. thinking 思考模式
|
||
2. fast 快速模式
|
||
3. deep 深度思考
|
||
```
|
||
|
||
规则:
|
||
|
||
- 当前选中项标记为 `current`
|
||
- 被管理员禁用的模型显示为 disabled,不可选
|
||
- fast-only / deep-only 模型需要显示提示
|
||
|
||
---
|
||
|
||
### 6.4 `/versioning`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/versioning 管理版本控制
|
||
```
|
||
|
||
为什么用 `versioning`:
|
||
|
||
- 比 `/version` 更明确是“版本控制”
|
||
- 避免和模型版本混淆
|
||
|
||
行为:
|
||
|
||
- 打开版本控制设置 / 恢复面板
|
||
|
||
显示示例:
|
||
|
||
```text
|
||
Versioning
|
||
|
||
› 1. 开启版本控制
|
||
2. 关闭版本控制
|
||
3. 查看版本记录
|
||
4. 恢复到选定版本
|
||
```
|
||
|
||
字段建议:
|
||
|
||
- 当前是否开启
|
||
- 当前跟踪模式
|
||
- 最近版本点
|
||
- 是否与当前工作区匹配
|
||
|
||
---
|
||
|
||
### 6.5 `/permission`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/permission 切换权限模式
|
||
```
|
||
|
||
行为:
|
||
|
||
- 打开权限模式选择器
|
||
|
||
显示示例:
|
||
|
||
```text
|
||
Permission Mode
|
||
|
||
› 1. Readonly 只读,不允许写入
|
||
2. Approval 需要审批后执行写入/敏感操作
|
||
3. Auto Approval 由自动审批智能体审核
|
||
4. Unrestricted 不做权限拦截
|
||
```
|
||
|
||
规则:
|
||
|
||
- 当前权限模式显示 `current`
|
||
- 高风险项需要二次确认
|
||
|
||
---
|
||
|
||
### 6.6 `/execution`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/execution 切换执行环境
|
||
```
|
||
|
||
为什么用 `execution`:
|
||
|
||
- 覆盖 `sandbox` 与 `direct`
|
||
- 比 `/env` 更明确
|
||
- 比 `/runtime` 更贴近用户动作
|
||
|
||
行为:
|
||
|
||
- 打开执行环境选择器
|
||
|
||
显示示例:
|
||
|
||
```text
|
||
Execution Environment
|
||
|
||
› 1. Sandbox 使用 OS 沙箱执行命令
|
||
2. Direct 在宿主机直接执行命令
|
||
```
|
||
|
||
规则:
|
||
|
||
- `Direct` 需要风险提示
|
||
- 如果 direct 有 TTL,显示剩余时间
|
||
|
||
---
|
||
|
||
### 6.7 `/workspace`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/workspace 选择或切换工作区
|
||
```
|
||
|
||
行为:
|
||
|
||
- 打开工作区列表
|
||
- 支持选择已有工作区
|
||
- 支持新建工作区
|
||
|
||
显示示例:
|
||
|
||
```text
|
||
Workspace
|
||
|
||
› 1. agents /Users/jojo/Desktop/agents/正在修复中/agents current
|
||
2. test /Users/jojo/Desktop/test
|
||
3. 新建工作区...
|
||
```
|
||
|
||
新建工作区时,输入栏切换成表单:
|
||
|
||
```text
|
||
Workspace path
|
||
› /Users/jojo/Desktop/new-project
|
||
```
|
||
|
||
可选第二步:
|
||
|
||
```text
|
||
Workspace name
|
||
› new-project
|
||
```
|
||
|
||
---
|
||
|
||
### 6.8 `/compact`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/compact 压缩当前对话上下文
|
||
```
|
||
|
||
行为:
|
||
|
||
- 触发当前对话压缩
|
||
- 压缩前可确认
|
||
|
||
显示示例:
|
||
|
||
```text
|
||
确认压缩当前对话上下文?
|
||
|
||
› 1. 压缩
|
||
2. 取消
|
||
```
|
||
|
||
完成后:
|
||
|
||
```text
|
||
• 对话已压缩
|
||
└ 当前上下文 24k/200k
|
||
```
|
||
|
||
---
|
||
|
||
### 6.9 `/tools`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/tools 启用或禁用工具
|
||
```
|
||
|
||
行为:
|
||
|
||
- 打开工具分类选择器
|
||
- 支持启用/禁用工具分类
|
||
|
||
显示示例:
|
||
|
||
```text
|
||
Tools
|
||
|
||
› [x] terminal 终端命令
|
||
[x] file 文件读写
|
||
[ ] web 网络访问
|
||
[x] sub_agent 子智能体
|
||
```
|
||
|
||
规则:
|
||
|
||
- 空格切换选中
|
||
- Enter 保存
|
||
- Esc 取消
|
||
|
||
---
|
||
|
||
### 6.10 `/path`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/path 管理路径授权
|
||
```
|
||
|
||
行为:
|
||
|
||
- 查看已授权路径
|
||
- 添加可读写路径
|
||
- 添加只读路径
|
||
- 删除授权路径
|
||
|
||
显示示例:
|
||
|
||
```text
|
||
Authorized Paths
|
||
|
||
› 1. 添加可读写路径
|
||
2. 添加只读路径
|
||
3. 删除授权路径
|
||
|
||
Current
|
||
rw /Users/jojo/Desktop/agents
|
||
ro /Users/jojo/Downloads
|
||
```
|
||
|
||
添加路径表单:
|
||
|
||
```text
|
||
Path
|
||
› /Users/jojo/Desktop/project
|
||
```
|
||
|
||
---
|
||
|
||
### 6.11 `/skill`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/skill 选择本轮要使用的 skill
|
||
```
|
||
|
||
这是 CLI 新增能力,Web 端暂无对应入口。
|
||
|
||
行为:
|
||
|
||
- 打开 skill 列表
|
||
- 用户选择一个 skill
|
||
- 下一次发送用户消息时,CLI 在用户消息下方附加一条 user 消息:
|
||
|
||
```text
|
||
先阅读 docs skill
|
||
```
|
||
|
||
### 显示示例
|
||
|
||
```text
|
||
Skill
|
||
|
||
› docs 阅读文档相关技能
|
||
frontend 前端开发相关技能
|
||
backend 后端开发相关技能
|
||
```
|
||
|
||
选择后输入栏状态栏显示:
|
||
|
||
```text
|
||
skill: docs
|
||
```
|
||
|
||
发送消息时:
|
||
|
||
```text
|
||
› 帮我整理一下 CLI 文档
|
||
+ 先阅读 docs skill
|
||
```
|
||
|
||
规则:
|
||
|
||
- v1 先做单选
|
||
- 选择后只作用于下一条用户消息
|
||
- 消息发送后清空当前 skill
|
||
- 后续可扩展为多选
|
||
|
||
---
|
||
|
||
### 6.12 `/status`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/status 查看当前状态
|
||
```
|
||
|
||
行为:
|
||
|
||
- 打开状态信息面板
|
||
- 类似 Codex CLI 的状态卡
|
||
|
||
显示示例:
|
||
|
||
```text
|
||
╭────────────────────────────────────────────────────────────────────╮
|
||
│ >_ Agents CLI │
|
||
│ │
|
||
│ Model: kimi-k2.5 │
|
||
│ Directory: ~/Desktop/agents/正在修复中/agents │
|
||
│ Workspace: agents │
|
||
│ Permissions: auto_approval │
|
||
│ Execution: sandbox │
|
||
│ Session: 019e253e-7310-7330-ac02-859338456535 │
|
||
│ Context window: 99% left (14.6K used / 258K) │
|
||
╰────────────────────────────────────────────────────────────────────╯
|
||
```
|
||
|
||
#### 字段说明
|
||
|
||
| 字段 | 说明 |
|
||
|---|---|
|
||
| `Model` | 当前模型 |
|
||
| `Directory` | 当前工作目录 |
|
||
| `Workspace` | 当前工作区名称 |
|
||
| `Permissions` | 当前权限模式 |
|
||
| `Execution` | 当前执行环境 |
|
||
| `Session` | 当前会话 ID |
|
||
| `Context window` | 上下文窗口使用情况 |
|
||
|
||
---
|
||
|
||
### 6.13 `/help`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/help 查看命令帮助
|
||
```
|
||
|
||
显示命令列表:
|
||
|
||
```text
|
||
Commands
|
||
|
||
/new 新建对话
|
||
/resume 查看对话列表并切换对话
|
||
/model 切换模型与思考模式
|
||
/versioning 管理版本控制
|
||
/permission 切换权限模式
|
||
/execution 切换执行环境
|
||
/workspace 选择或切换工作区
|
||
/compact 压缩当前对话上下文
|
||
/tools 启用或禁用工具
|
||
/path 管理路径授权
|
||
/skill 选择本轮要使用的 skill
|
||
/status 查看当前状态
|
||
/clear 清空当前 CLI 显示
|
||
/exit 退出 CLI
|
||
```
|
||
|
||
---
|
||
|
||
### 6.14 `/clear`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/clear 清空当前 CLI 显示
|
||
```
|
||
|
||
行为:
|
||
|
||
- 只清空 CLI 当前显示区
|
||
- 不删除对话历史
|
||
- 不影响后端会话
|
||
|
||
---
|
||
|
||
### 6.15 `/exit`
|
||
|
||
说明:
|
||
|
||
```text
|
||
/exit 退出 CLI
|
||
```
|
||
|
||
行为:
|
||
|
||
- 如果当前无任务,直接退出
|
||
- 如果有运行任务,显示确认:
|
||
|
||
```text
|
||
当前任务仍在运行,是否退出?
|
||
|
||
› 1. 退出并停止当前任务
|
||
2. 后台继续运行并退出
|
||
3. 取消
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 审批交互与命令系统的关系
|
||
|
||
审批不是 `/approval` 命令。
|
||
|
||
当有待审批操作时,输入栏临时切换为审批态:
|
||
|
||
```text
|
||
需要批准:运行 rm -rf dist
|
||
|
||
› 1. 允许一次
|
||
2. 切换到无限制
|
||
3. 拒绝
|
||
```
|
||
|
||
审批完成后恢复普通输入态。
|
||
|
||
---
|
||
|
||
## 8. 底部状态栏与 `/status` 的关系
|
||
|
||
底部状态栏只显示短信息:
|
||
|
||
```text
|
||
5 后台智能体 3 后台指令 版本控制: 开 自动审批 沙箱 24k/200k
|
||
```
|
||
|
||
`/status` 显示完整信息卡。
|
||
|
||
---
|
||
|
||
## 9. 实现建议
|
||
|
||
### 9.1 命令定义结构
|
||
|
||
```ts
|
||
type SlashCommand = {
|
||
name: string;
|
||
aliases?: string[];
|
||
description: string;
|
||
kind: 'immediate' | 'picker' | 'panel' | 'form';
|
||
run: () => void | Promise<void>;
|
||
};
|
||
```
|
||
|
||
### 9.2 命令状态
|
||
|
||
```ts
|
||
type CliInputMode =
|
||
| 'composer'
|
||
| 'slash_menu'
|
||
| 'picker'
|
||
| 'approval'
|
||
| 'form'
|
||
| 'status_panel'
|
||
| 'help_panel';
|
||
```
|
||
|
||
### 9.3 命令过滤
|
||
|
||
- 前缀匹配优先
|
||
- 模糊匹配其次
|
||
- 当前项默认选第一条
|
||
|
||
---
|
||
|
||
## 10. 一句话总结
|
||
|
||
CLI 的 `/` 命令系统目标是:
|
||
|
||
> 用一个统一命令入口覆盖 Web 对话页的主要直接操作,同时保持终端交互简单、可键盘驱动、低噪声。
|