## 新增:基于 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>
13 KiB
13 KiB
CLI Slash 命令设计规范(草案)
目标:定义 CLI 中
/命令的命名、交互方式、显示方式与最小功能集。 关联文档:docs/cli_ui_display_spec.md
1. 总体原则
- 所有主动操作都从
/命令进入:避免额外快捷键过多导致记忆负担。 - 命令面板统一交互:输入过滤、上下选择、Enter 确认。
- 没有必要的命令不做:后台内部操作、配置文件管理、文件浏览等不暴露成命令。
- 审批不做独立命令:有审批时直接占用输入栏显示审批交互。
- 命令只负责 UI 入口:真正执行仍通过后端 API / CLI 适配层完成。
2. 启动命令与工作区初始化
2.1 启动命令
正式启动命令建议为:
agents
开发期或兼容别名可保留:
agents-cli
命名理由:
- 和项目名一致
- 短、好记
- 类似
codex/claude的产品级 CLI 命令 - 比
agent更不容易和泛称混淆
2.2 默认工作区目录
用户在任意目录执行:
cd /Users/jojo/Desktop/test
agents
CLI 默认使用 process.cwd() 作为本次启动的工作区目录。
2.3 当前目录已是工作区
如果当前目录已经存在于工作区列表中:
- 自动选择该工作区
- 进入 CLI 主界面
2.4 当前目录不是工作区
如果当前目录不在工作区列表中,启动时先显示确认提示:
当前目录尚未添加为工作区:
/Users/jojo/Desktop/test
Agent 将在此目录中读取文件、执行命令和修改内容。
是否将此目录添加为工作区?
› 1. 确认,添加并继续
2. 拒绝,退出
选择 确认:
• 已添加工作区 test
└ /Users/jojo/Desktop/test
然后进入 CLI 主界面。
选择 拒绝:
已取消,退出 Agents CLI。
并退出程序。
2.5 工作区匹配规则
v1 只做精确路径匹配:
- 当前目录路径与已有工作区路径完全一致:视为已有工作区
- 当前目录是已有工作区的子目录:仍视为新目录,需要确认是否添加
这样可以保证行为明确:
在哪个目录启动,Agent 就在哪个目录工作。
2.6 自动工作区名称
自动创建工作区时:
- 默认名称使用目录 basename
- 如
/Users/jojo/Desktop/test→test - 如果名称重复,可自动追加序号,例如
test-2
3. 命令面板交互
3.1 触发
用户在输入栏输入 / 后打开命令面板。
› /
输入更多字符后实时过滤:
› /a
/compact 压缩当前对话上下文
› /path 管理路径授权
/permission 切换权限模式
3.2 选择
↑/↓切换当前选中项- 当前选中项使用高亮颜色
Enter执行当前命令Esc关闭命令面板
3.3 展示格式
› /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
说明:
/new 新建对话
行为:
- 创建一个空白对话
- 清空当前 CLI 消息区
- 切换到底部输入待命态
如果当前有未完成任务:
当前任务仍在运行,是否新建对话?
› 1. 新建并停止当前任务
2. 等待当前任务完成
3. 取消
6.2 /resume
说明:
/resume 查看对话列表并切换对话
行为:
- 打开历史对话选择器
- 显示最近对话
- 选择后切换当前会话
显示示例:
Resume conversation
› 今天 14:32 修复 CLI 设计文档
今天 13:10 调研 Claude Code CLI
昨天 22:45 Android 发布联动
字段建议:
- 时间
- 对话标题 / 首条用户消息摘要
- 当前工作区(可选)
- 模型(可选)
6.3 /model
说明:
/model 切换模型与思考模式
行为:
- 打开模型选择器
- 支持模型和运行模式一起切换
显示示例:
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
说明:
/versioning 管理版本控制
为什么用 versioning:
- 比
/version更明确是“版本控制” - 避免和模型版本混淆
行为:
- 打开版本控制设置 / 恢复面板
显示示例:
Versioning
› 1. 开启版本控制
2. 关闭版本控制
3. 查看版本记录
4. 恢复到选定版本
字段建议:
- 当前是否开启
- 当前跟踪模式
- 最近版本点
- 是否与当前工作区匹配
6.5 /permission
说明:
/permission 切换权限模式
行为:
- 打开权限模式选择器
显示示例:
Permission Mode
› 1. Readonly 只读,不允许写入
2. Approval 需要审批后执行写入/敏感操作
3. Auto Approval 由自动审批智能体审核
4. Unrestricted 不做权限拦截
规则:
- 当前权限模式显示
current - 高风险项需要二次确认
6.6 /execution
说明:
/execution 切换执行环境
为什么用 execution:
- 覆盖
sandbox与direct - 比
/env更明确 - 比
/runtime更贴近用户动作
行为:
- 打开执行环境选择器
显示示例:
Execution Environment
› 1. Sandbox 使用 OS 沙箱执行命令
2. Direct 在宿主机直接执行命令
规则:
Direct需要风险提示- 如果 direct 有 TTL,显示剩余时间
6.7 /workspace
说明:
/workspace 选择或切换工作区
行为:
- 打开工作区列表
- 支持选择已有工作区
- 支持新建工作区
显示示例:
Workspace
› 1. agents /Users/jojo/Desktop/agents/正在修复中/agents current
2. test /Users/jojo/Desktop/test
3. 新建工作区...
新建工作区时,输入栏切换成表单:
Workspace path
› /Users/jojo/Desktop/new-project
可选第二步:
Workspace name
› new-project
6.8 /compact
说明:
/compact 压缩当前对话上下文
行为:
- 触发当前对话压缩
- 压缩前可确认
显示示例:
确认压缩当前对话上下文?
› 1. 压缩
2. 取消
完成后:
• 对话已压缩
└ 当前上下文 24k/200k
6.9 /tools
说明:
/tools 启用或禁用工具
行为:
- 打开工具分类选择器
- 支持启用/禁用工具分类
显示示例:
Tools
› [x] terminal 终端命令
[x] file 文件读写
[ ] web 网络访问
[x] sub_agent 子智能体
规则:
- 空格切换选中
- Enter 保存
- Esc 取消
6.10 /path
说明:
/path 管理路径授权
行为:
- 查看已授权路径
- 添加可读写路径
- 添加只读路径
- 删除授权路径
显示示例:
Authorized Paths
› 1. 添加可读写路径
2. 添加只读路径
3. 删除授权路径
Current
rw /Users/jojo/Desktop/agents
ro /Users/jojo/Downloads
添加路径表单:
Path
› /Users/jojo/Desktop/project
6.11 /skill
说明:
/skill 选择本轮要使用的 skill
这是 CLI 新增能力,Web 端暂无对应入口。
行为:
- 打开 skill 列表
- 用户选择一个 skill
- 下一次发送用户消息时,CLI 在用户消息下方附加一条 user 消息:
先阅读 docs skill
显示示例
Skill
› docs 阅读文档相关技能
frontend 前端开发相关技能
backend 后端开发相关技能
选择后输入栏状态栏显示:
skill: docs
发送消息时:
› 帮我整理一下 CLI 文档
+ 先阅读 docs skill
规则:
- v1 先做单选
- 选择后只作用于下一条用户消息
- 消息发送后清空当前 skill
- 后续可扩展为多选
6.12 /status
说明:
/status 查看当前状态
行为:
- 打开状态信息面板
- 类似 Codex CLI 的状态卡
显示示例:
╭────────────────────────────────────────────────────────────────────╮
│ >_ 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
说明:
/help 查看命令帮助
显示命令列表:
Commands
/new 新建对话
/resume 查看对话列表并切换对话
/model 切换模型与思考模式
/versioning 管理版本控制
/permission 切换权限模式
/execution 切换执行环境
/workspace 选择或切换工作区
/compact 压缩当前对话上下文
/tools 启用或禁用工具
/path 管理路径授权
/skill 选择本轮要使用的 skill
/status 查看当前状态
/clear 清空当前 CLI 显示
/exit 退出 CLI
6.14 /clear
说明:
/clear 清空当前 CLI 显示
行为:
- 只清空 CLI 当前显示区
- 不删除对话历史
- 不影响后端会话
6.15 /exit
说明:
/exit 退出 CLI
行为:
- 如果当前无任务,直接退出
- 如果有运行任务,显示确认:
当前任务仍在运行,是否退出?
› 1. 退出并停止当前任务
2. 后台继续运行并退出
3. 取消
7. 审批交互与命令系统的关系
审批不是 /approval 命令。
当有待审批操作时,输入栏临时切换为审批态:
需要批准:运行 rm -rf dist
› 1. 允许一次
2. 切换到无限制
3. 拒绝
审批完成后恢复普通输入态。
8. 底部状态栏与 /status 的关系
底部状态栏只显示短信息:
5 后台智能体 3 后台指令 版本控制: 开 自动审批 沙箱 24k/200k
/status 显示完整信息卡。
9. 实现建议
9.1 命令定义结构
type SlashCommand = {
name: string;
aliases?: string[];
description: string;
kind: 'immediate' | 'picker' | 'panel' | 'form';
run: () => void | Promise<void>;
};
9.2 命令状态
type CliInputMode =
| 'composer'
| 'slash_menu'
| 'picker'
| 'approval'
| 'form'
| 'status_panel'
| 'help_panel';
9.3 命令过滤
- 前缀匹配优先
- 模糊匹配其次
- 当前项默认选第一条
10. 一句话总结
CLI 的 / 命令系统目标是:
用一个统一命令入口覆盖 Web 对话页的主要直接操作,同时保持终端交互简单、可键盘驱动、低噪声。