Appearance
Wave Code CLI
基于 React Ink 构建的 CLI 终端界面,提供交互式 AI 编程助手体验。
1. 安装与启动
1.1 安装
bash
npm install wave-code -g1.2 运行模式
Wave CLI 提供三种运行模式,适用于不同场景:
交互模式(默认)
启动基于 React Ink 的终端 UI,支持实时对话、流式输出和完整的交互体验。
bash
wave打印模式(--print / -p)
非交互式运行,接收输入并一次性输出结果,适用于脚本集成和自动化流水线。
bash
wave -p "解释这个项目的架构"
echo "分析这段代码的问题" | wave -p配合 --show-stats 可在输出末尾显示耗时和 Token 用量统计。
2. 命令行选项
2.1 会话控制
| 选项 | 简写 | 描述 |
|---|---|---|
--restore <id> | -r | 按 session ID 恢复会话;不指定 ID 则列出可用会话 |
--continue | -c | 自动继续上次会话 |
bash
# 列出可恢复的会话
wave -r
# 恢复指定会话
wave -r <session-id>
# 继续上次会话
wave -c2.2 模型与工具
| 选项 | 描述 |
|---|---|
--model <name> | 指定 AI 模型 |
--tools <list> | 启用的工具列表(逗号分隔) |
--allowed-tools <list> | 始终允许的工具列表 |
--disallowed-tools <list> | 始终禁用的工具列表 |
--mcp-config <json> | MCP 服务器配置(JSON 字符串) |
bash
# 指定模型并限制工具
wave --model gpt-4o --disallowed-tools Bash,Write2.3 权限与安全
| 选项 | 描述 |
|---|---|
--permission-mode <mode> | 设置权限模式:default、acceptEdits、bypassPermissions、dontAsk、plan |
--dangerously-skip-permissions | 跳过所有权限检查(危险) |
--add-dir <path> | 将目录加入会话安全区域,可重复指定(仅当前会话生效) |
bash
# 将 /data/exports 加入当前会话的安全区域
wave --add-dir /data/exports2.4 工作目录
| 选项 | 简写 | 描述 |
|---|---|---|
--worktree [name] | -w | 在 git worktree 中启动,可选指定名称 |
bash
# 自动命名 worktree
wave -w
# 指定 worktree 名称
wave -w my-feature2.5 其他
| 选项 | 简写 | 描述 |
|---|---|---|
--plugin-dir <path> | 从指定目录加载插件 | |
--show-stats | 打印模式下显示耗时和 Token 统计 | |
--version | -v | 显示版本号 |
--help | -h | 显示帮助信息 |
3. 子命令
3.1 插件管理
bash
# 市场管理
wave plugin marketplace add <input> # 添加插件市场
wave plugin marketplace update [name] # 更新已注册的市场
wave plugin marketplace list # 列出所有已注册市场
# 插件操作
wave plugin install <plugin> # 从市场安装插件
wave plugin list # 列出市场中可用插件
wave plugin uninstall <plugin> # 卸载插件
wave plugin update <plugin> # 更新插件(卸载后重新安装)安装插件时支持指定作用域(不指定时默认 user 作用域,安装即启用):
bash
wave plugin install my-plugin@official --scope user # 全局安装(默认)
wave plugin install my-plugin@official --scope project # 项目级安装
wave plugin install my-plugin@official --scope local # 本地安装3.2 更新
bash
wave update # 更新 Wave CLI 到最新版本Windows 上更新时提示「更新将在后台完成」并立即退出当前进程,由分离的后台子进程完成安装,避免更新程序自身占用 bin 文件句柄导致安装失败(EPERM/EBUSY)。
3.3 Daemon 客户端命令
wave --daemon <socket> 在远端主机上以守护进程方式启动 Wave,托管后台 agent 会话(桌面端经 SSH 隧道访问)。与之对应,wave daemon <子命令> 是访问该 daemon 的客户端命令组,可在远端主机上(或经 ssh <host> wave daemon ...)查看、续聊与审批 daemon 托管的会话,无需打开完整 UI。所有子命令非交互式运行:结果输出到 stdout、诊断输出到 stderr,便于脚本与管道消费。
bash
# 列出 daemon 当前托管(进程内存中 live)的全部会话:会话 ID、工作目录、状态、消息数
wave daemon list
# 查看指定会话的实时状态(生成中/空闲/等待审批)与最近消息(默认只展示最后 1 条)
wave daemon status <sessionId> [--lines 1]
# 阻塞盯住指定会话,等它空闲(或挂起等待审批)就退出,退出时打印最终快照
# 退出码:0=等到空闲 / 3=挂起等待审批(立刻返回)/ 1=错误(连不上、会话不存在或在等待期间被销毁、--timeout 到点)
wave daemon wait <sessionId> [--lines 1] [--from-busy] [--timeout 600]
# 向会话注入一条消息(默认异步派单:发完即退,不等待回复;进度用 status 查看)
wave daemon send <sessionId> "继续"
# 需要同步等待回复时传 --wait <秒>:等待该消息对应的回复完成后输出助手最终回复
wave daemon send <sessionId> "继续" --wait 600
# 处理会话挂起的权限请求:允许 / 拒绝(可附原因)
wave daemon respond <sessionId> <requestId> --allow
wave daemon respond <sessionId> <requestId> --deny --reason "原因"
# 中断会话正在生成的回复(含子代理、bash 命令与排队消息)
wave daemon abort <sessionId>
# 优雅关闭 daemon(各会话存盘收尾后进程退出;未运行时幂等成功)
wave daemon stop
# 重启 daemon(CLI 升级后使用:先优雅停旧进程,再拉起当前 CLI 的新 daemon)
wave daemon restart要点:
- 所有子命令固定连接默认 socket(
~/.wave/daemon.sock),不提供--socket覆盖参数 - 语义区分:
wave --daemon <socket>是启动 daemon(服务端),wave daemon <子命令>是访问 daemon(客户端),两者互不干扰 - daemon 一经拉起即常驻运行(空闲不退出),仅在被 kill / 升级重启 / 机器重启后消失;daemon 未运行时,任一子命令自动以 nohup 方式拉起 daemon 并重试连接,仅当拉起的 daemon 在启动超时内未就绪时才以非零退出码报错退出,不进入 TUI、不挂起
wave daemon list仅展示当前 daemon 进程内存中 live 的会话(不扫磁盘索引);知道 sessionId 时即使不在列表中,也可经status/send重新载入wave daemon status默认只展示最后 1 条消息(消息正文完整不截断,默认值保持输出有界);--lines N展示最近 N 条,--lines 0只输出 session 头与Status:行。status始终是「取一次快照、立刻返回」的契约;需要阻塞等到状态变化(生成中 → 空闲,或挂起审批)时用wave daemon wait。Status:与wait用同一空闲判据(无回合、无后台任务/子 agent、无排队消息):前台回合已结束但后台任务/子 agent 仍在跑的会话显示generating,不会出现「status说 idle、wait却不返回」的矛盾取值wave daemon wait是「盯会话」的正式入口:订阅 daemon 推送的loadingChange与backgroundTasksChange(后台任务起止)作唤醒、醒来读注册表判空闲(不轮询),退出时按wave daemon status <id> --lines N的同格式把最终快照打到 stdout(msg=$(wave daemon wait <id>)拿到的就是汇报本身),进度提示走 stderr;退出码为契约——0=等到空闲、3=会话挂起等待权限审批(立刻返回并打印待审批清单,respond后可重新wait)、1=错误(daemon 连不上 / sessionId 不存在或在等待期间被销毁 /--timeout到点)。「空闲」的判据与wave -p(print mode)一致:无进行中的回合、无运行中的后台任务/子 agent、无待处理消息,三项同时成立——只结束了前台回合、后台任务/子 agent 还在跑的会话不算空闲(这是刻意为之:否则会在后台任务还没跑完时就假报「已完成」),因此挂着长跑后台任务的会话(如长期跑着的 dev server)永远不会空闲、必须显式传--timeout。调用时已空闲则立即退出 0;--from-busy要求先观察到一次本会话的「非空闲」再判空闲(消除紧跟异步send之后立刻wait的 stale 快照竞态,运行中的后台任务同样算「忙」);--timeout <秒>默认无限等待status/wait的推送按 sessionId 分路:daemon 把每条会话级通知广播给所有已连接客户端(信封标注sessionId,一个连接可承载多个会话,如桌面端远端),因此命令订阅后先按本次 attach 的 sessionId 过滤再写状态——别的会话的loadingChange/userMessageAdded/assistantMessageAdded不得翻转Status:、不得结束等待、也不得替--from-busy满足「忙」- 无人值守监控不需要外层 shell 轮询脚本:
wave daemon wait的三种终止已覆盖全部终止情形——0=目标会话完成(stdout 即最终快照)、3=卡在审批(去respond后续等)、1=出错(含等待期间该会话被其它客户端destroy:命令会按「会话已不存在」明确报错退出,绝不挂住、也绝不把已消失的会话误报成「已完成」;daemon 侧保证销毁是「先摘注册表条目、再做耗时收尾」,因此整个销毁窗口内该会话都已按「不存在」对待)。因此调用方直接msg=$(wave daemon wait <id>)取汇报、按退出码分支即可;权限审批与会话是否仍存活这两类事实施信不了推送(会话被销毁只伴随一次loadingChange:false,与「本轮生成结束」同形),由同一个 2 秒兜底查询覆盖(不是每 N 秒查一次status的状态轮询) - 换键与就地重建不等于销毁:会话在存活期间可以换 sessionId(清空对话铸出新 id)——daemon 会广播新 id,
wait/send --wait跟着重绑到同一个会话(不因旧 id 消失而报退出码 1 / 假超时);配置保存触发的就地重建期间会话仍在注册表中并被报为「生成中」(绝不出现「条目在 + 未生成」这个会被误判成空闲的组合),读类请求照常、写类请求以可重试错误拒绝,重建完成后照常判定,只有重建失败才会话消失(走「已不存在」退出码 1) wave daemon send默认异步派单:注入消息后立即退出码 0(stdout 输出Sent message to session: <sessionId>确认,不等待回复、不输出回复文本),消息照常在 daemon 中处理,进度用wave daemon status查看;需要同步等待回复时传--wait <秒>(如--wait 600,等待超过 N 秒无回复即以非零退出码退出;会话挂起等待审批时超时退出,提示先经wave daemon respond处理)wave daemon respond按工具智能补全决策:EnterPlanMode的--allow自动附带 plan 模式切换;AskUserQuestion需用--answer '{"问题":"答案"}'提供答案;--rule "Bash(ls)"持久化允许规则(后续同类调用不再询问);--mode acceptEdits切换会话权限模式wave daemon abort中断指定会话正在生成的回复(含子代理、bash 命令与排队消息),不清除已完成的对话历史;对空闲会话是幂等 no-op(仍成功退出);sessionId 不存在时以非零退出码报错;attach 是短暂访问、随用随断,中断后会话在 daemon 中继续存活wave daemon stop优雅关闭 daemon(非强杀):先销毁全部托管会话(各自存盘收尾)再退出;daemon 未运行时幂等成功(不自动拉起);wave daemon restart先优雅停掉旧 daemon、再以当前 CLI 拉起新 daemon(未运行时等价于直接拉起)——CLI 升级后运行它让 daemon 跑新代码
4. 斜杠命令
在交互模式中,输入 / 可触发命令选择器,快速调用以下内置命令:
| 命令 | 描述 |
|---|---|
/help | 显示帮助和快捷键 |
/status | 显示 Agent 状态和配置信息 |
/model | 切换 AI 模型 |
/tasks | 管理后台任务 |
/mcp | 管理 MCP 服务器连接 |
/plugin | 管理插件 |
/workflows | 查看和管理工作流运行 |
/rewind | 回滚到历史检查点 |
/resume | 恢复历史对话(会话内切换,无需退出进程) |
/rename | 给当前对话设自定义标题 |
/login | SSO 企业认证登录 |
/logout | 清除 SSO 认证 |
/clear | 清除当前对话历史 |
/compact | 压缩对话历史,减少 Token 占用 |
/add-dir | 将目录加入会话安全区域(可带 --remember 持久化) |
/agents | 查看当前会话可见的所有 agent(子代理)定义,按来源分组展示 |
/skills | 查看当前会话可见的所有技能,按来源分组展示并可查看详情 |
/btw | 旁路提问,不调用工具的快速问答 |
了解更多:详见 SDK 文档 - 斜杠命令
5. 键盘快捷键
5.1 输入与导航
| 快捷键 | 功能 |
|---|---|
Enter | 发送消息 / 确认选择 |
Ctrl+J | 输入换行(多行输入) |
↑ / ↓ | 浏览输入历史 / 选择器导航 |
@ | 触发文件选择器,将文件添加到上下文 |
/ | 触发命令选择器 |
! | Shell 命令前缀(如 !ls -la) |
Ctrl+R | 搜索 Prompt 历史(会话选择器内为给该会话改名) |
Ctrl+V / Alt+V(Windows) | 粘贴剪贴板图片 |
Ctrl+A | 光标移到行首 |
Ctrl+E | 光标移到行尾 |
Ctrl+U | 删除光标前到行首的内容 |
Ctrl+K | 删除光标后到行尾的内容 |
Ctrl+W | 删除光标前一个词 |
占位符整块删除: 粘贴长文本或图片会生成 [LongText#N] / [Image #N] 占位符。当光标位于占位符末尾且其后为空白或行尾时,按 Backspace 会整块删除占位符(连同对应的长文本/图片附件),不会留下残缺片段;Ctrl+U/Ctrl+K/Ctrl+W 等行编辑键仍按普通字符串处理。
5.2 视图控制
| 快捷键 | 功能 |
|---|---|
Ctrl+O | 展开/折叠消息 |
Ctrl+T | 切换任务列表显示 |
Ctrl+B | 将当前任务放到后台执行 |
5.3 权限与确认
| 快捷键 | 功能 |
|---|---|
Shift+Tab | 循环切换权限模式 |
Tab | 在确认对话框中切换选项 |
PgUp/PgDn | 确认详情超高时翻页滚动内容区 |
Ctrl+U/Ctrl+D | 确认详情超高时上/下滚半页 |
Esc | 中断 AI 响应 / 取消选择器 / 关闭帮助 |
Esc ×2 | 空闲时双击清空输入(并保存到历史) |
确认详情(超长 plan 或大 diff)超高时,内容区可独立滚动(PgUp/PgDn 翻页、Ctrl+U/Ctrl+D 半页),选项列表固定底部始终可见,底部显示滚动快捷键提示(内容不超高时不显示)。
6. 权限模式
Wave 提供五种权限管理模式,控制 AI 调用工具时的确认行为:
| 模式 | 描述 |
|---|---|
default | 受限工具需要用户确认,最安全的模式 |
acceptEdits | 自动接受文件编辑操作,其他工具仍需确认 |
bypassPermissions | 自动接受所有工具调用,无需任何确认(危险) |
plan | 计划模式,AI 只能修改计划文件,适合项目规划阶段 |
dontAsk | 自动拒绝受限工具,AI 不会请求确认也不会执行 |
切换方式:
- 交互模式中按
Shift+Tab循环切换 - 启动时通过
--permission-mode指定 - 使用
--dangerously-skip-permissions等同于bypassPermissions
默认自动放行的只读命令:
default 模式下,以下只读 git 命令默认直接执行、不触发权限确认:git status、git diff、git log、git show、git branch(含 --list / -a / -r / -v 等变体)、git tag、git remote、git ls-files、git rev-parse、git config --list、git cat-file、git count-objects。命令带全局作用域参数(如 git -C <path> status、git --work-tree <path> diff)时同样匹配自动放行;写操作(git push、git commit、git branch -D 等)不受影响,仍按正常权限流程确认。
7. 特色功能
7.1 Bash 模式
在输入框中以 ! 开头直接执行 Shell 命令,无需离开聊天界面。
bash
!ls -la
!git status
!npm test命令以 user 消息 + bash tool block 形态显示在消息流中,输出实时显示、全量展示;失败时在输出前标注 [exit code: N]。长时间运行的命令支持随时中止。
7.2 BTW 旁路提问
/btw <question> 向 AI 快速提问,AI 不会调用任何工具,仅基于已有上下文直接回答。适合快速确认思路或获取解释,不产生工具调用开销。
/btw 这个函数的时间复杂度是多少?回答期间显示 ✻ Answering 加载提示,其后实时展示当前流式文本的最后 30 个字符(超出截断、换行折叠),按 Esc 可中止请求。
7.3 Git Worktree
通过 --worktree 在隔离的 git worktree 中启动,安全实验新功能而不影响主分支。
bash
wave -w my-feature在交互模式中也可通过内置工具 EnterWorktree 切换到 worktree。
在退出对话框选择 "Remove worktree"(或打印模式 -p 正常退出清理、WorktreeRemove hook 接管)删除 worktree 时,会显示 Deleting worktree ... 进度提示,完成后显示 Done.;删除失败显示错误信息而非完成提示。选择 "Keep worktree" 保留时无提示。
7.4 Compact 压缩
/compact 压缩当前对话历史,将冗长的上下文总结为精简摘要,减少后续请求的 Token 占用。支持附加自定义指令引导压缩方向。
/compact 重点保留 API 设计相关的讨论压缩进行中消息列表下方显示 ✻ Compacting 提示,其后实时展示当前流式文本的最后 30 个字符(超出截断、换行折叠),压缩完成后提示消失。
7.5 Rewind 回滚
/rewind 将对话回滚到历史检查点,撤销后续的对话记录和文件更改。
7.6 图片粘贴
按 Ctrl+V 粘贴剪贴板中的图片,支持跨平台(macOS、Linux、Windows)。AI 可识别截图中的 UI 设计、错误信息或架构图。Windows 终端将 Ctrl+V 保留为系统文本粘贴,按键不会到达 CLI,因此 Windows 下使用 Alt+V(与 Claude Code 一致)。
7.7 MCP 集成
通过 /mcp 管理 MCP(Model Context Protocol)服务器连接,扩展 AI 的外部工具能力。支持在项目根目录的 .mcp.json 中配置,或通过 --mcp-config 命令行传入。
7.8 插件系统
通过插件扩展 AI 的 Skill 和命令。支持插件市场的发现、安装和管理,插件可在 user、project、local 三种作用域下激活。
详见 第 3.1 节 插件管理。
7.9 Workflow 工作流
通过 /workflows 查看和管理正在运行的工作流。工作流支持多阶段编排、并行执行和确定性控制流。
7.10 后台任务
通过 /tasks 查看后台任务列表,或通过 Ctrl+B 将当前前台任务放到后台执行。支持 shell 命令和子代理两种任务类型,任务完成后自动通知。
7.11 SSO 认证
通过 /login 进行企业 SSO 认证,授权码通过 localhost 回调自动交换为 JWT。登录后 API 请求自动通过 Wave AI 服务端代理路由,无需手动配置 API Key。通过 /logout 清除认证状态。
7.12 会话管理
支持多会话的创建、恢复和管理:
bash
wave # 启动新会话
wave -c # 继续上次会话
wave -r # 列出可恢复的会话
wave -r <id> # 恢复指定会话会话文件的元数据头持久化真实的创建时间、工作目录与 git 分支;wave -r 选择器中会话行尾显示 git 分支标签(如 [main]),多 worktree 场景下可区分同仓库不同分支的会话。
7.13 附加工作目录
默认情况下,Agent 只能在当前工作目录内读写文件。通过附加目录(additional working directories)将安全区域扩展到工作目录之外,目录内的文件操作不再触发权限确认,并在系统提示词中列出。
bash
# 启动时加入(仅当前会话生效,可重复指定)
wave --add-dir /data/exports
# 会话进行中加入(--remember 追加到 .wave/settings.local.json 的
# permissions.additionalDirectories,后续会话自动加载)
/add-dir /data/exports
/add-dir --remember /data/exports无参数执行 /add-dir 显示用法及当前会话的附加目录列表。此功能为 CLI 专属入口;配置键 permissions.additionalDirectories 为通用配置,各端(CLI、VS Code 等)均生效。
7.14 Token 用量统计
在打印模式下配合 --show-stats 使用,输出结果末尾显示耗时和 Token 用量统计信息。
bash
wave -p --show-stats "分析这个项目的依赖关系"7.15 会话内热切换
/resume 在 TUI 内打开会话选择器,切换到另一段对话,不必退出进程重开:
/resume选择器与 wave -r 共用同一组件与同一套会话归属判定(↑ ↓ 选择、Enter 确认、Esc 取消):
- 范围:默认列出当前目录的会话;
Ctrl+W展开同仓库的全部 worktree(含主仓库),Ctrl+A展开全部项目——展开时行尾显示会话所属项目路径。 - 原地恢复:选中当前目录的会话即原地恢复,工作目录不变。
- 自动切换工作目录:选中同仓库其它 worktree 的会话时直接恢复,并把会话转录文件、项目规则与记忆改按该目录解析。
- 跨项目:选中其它项目的会话时不在当前进程恢复,选择器内显示可复制的
cd <路径> && wave --restore <sessionId>(同时写入剪贴板),按Esc返回——关闭提示后原会话与内容不受影响。目标 worktree 目录已被删除时按同样方式处理。 - 运行中:正在生成回复时按
/resume提示Cannot resume a conversation while the agent is running.(Esc返回),不中断当前回合。 - 切换后:当前会话先自动存盘,消息流、Token 用量与任务列表整体换成目标会话的状态,输入框草稿清空。
- 失败:目标会话记录不存在或损坏时不切换,提示失败原因,当前会话保持可用。
切换会触发 SessionEnd / SessionStart 钩子(来源为 resume),与 wave -r 启动时一致。
7.16 会话重命名
给当前对话设一个自定义标题,替代默认的「首条用户消息截断」显示:
/rename 修复登录页样式不带标题执行 /rename 只打印用法(Usage: /rename <title>),成功时回显 Conversation renamed to "…".。
会话选择器(/resume 与 wave -r 共用同一组件)里也能就地改名:↑ / ↓ 选中某行后按 Ctrl+R,该行标题变成输入框并全选原标题,Enter 保存、Esc 取消——选择器内 Ctrl+R 是重命名,与输入框里的 Ctrl+R(搜索 Prompt 历史)互不冲突。
- 显示优先级:自定义标题 > 首条用户消息截断(30 字符)>
新对话;已设的自定义标题不会被后续消息按「首条消息」重新推导覆盖。 - 存储与一致性:标题以
custom-title保留条目追加在会话自己的 JSONL 文件里(唯一权威来源),因此wave -r、插件端与桌面端读到的都是同一个标题。 - 空标题:
trim后为空时只提示用法、不作改动(没有「清除标题」语义)。 - 失败:写盘失败时报错并保持原标题不变(不静默)。
8. 环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
LOG_LEVEL | INFO | 日志级别:DEBUG、INFO、WARN、ERROR |
LOG_KEYWORDS | - | 日志关键词过滤,仅输出包含指定关键词的日志 |
LOG_FILE | ~/.wave/logs/cli.log | 日志文件路径(桌面端/IDE 插件分别为 desktop.log/vscode.log/jetbrains.log) |
了解更多:详见 SDK 文档 - 环境变量