---
url: /wave-agent/specs/commands/agents-command.md
description: '`/agents` 查看与管理当前会话可见的 agent 定义'
---

# 功能规格说明：Agents 命令

**创建日期**：2026-08-12

> 对齐 Claude Code 的 `/agents` 命令（AgentsMenu：allAgents + activeAgents 两个数据来源，按来源分组展示）。
> wave 范围为**查看与管理**：列出当前会话可见的所有 agent 定义（名字 + 模型 + 描述等关键字段），并可新建 / 编辑 / 删除用户级与项目级子代理（2026-08-29 用户拍板：子代理从只读浏览升级为管理，GUI 三端设置页「子代理」选项卡提供新建 / 编辑 / 删除，CLI `/agents` 保持只读查看）。
> 不做活跃子代理展示（CC AgentsMenu 仅展示 agent 定义，无运行实例区块）。
> 子代理通过 markdown 文件定义（YAML frontmatter + 正文），新建 / 编辑由 AI 根据自然语言生成文件内容，删除为二次确认后直接删除文件。
> 交互形式遵循 wave 现有斜杠命令弹窗规范（closable overlay，参照 `/tasks`、`/mcp`），不用 showCommandResult 发消息的形式。
> 覆盖 CLI 与图形界面三端（VS Code 扩展 / JetBrains 插件 / 桌面端）两种入口：CLI 为终端弹窗，图形界面三端打开设置页并选中「子代理」选项卡（`/agents` → 子代理，`/skills` → 技能；复用设置页导航，不另起对话框）。

## 用户场景与测试 *（必填）*

### 用户故事：查看 agent 定义列表（优先级：P1）

作为用户，我希望通过 `/agents` 弹窗查看当前会话可见的所有 agent 定义（名字 + 模型 + 描述等关键字段），以便了解当前有哪些子代理可用、各自职责与来源。

**验收场景**：

1. **假设** 用户处于 CLI 交互模式，**当** 用户输入 `/agents` 并按下 Enter 时，**则** 打开 agents 弹窗覆盖层，弹窗内展示当前会话可见的所有 agent 定义。
2. **假设** agents 弹窗已打开，**则** 每个 agent 定义行展示名字、模型（未显式配置时显示默认模型或占位符）、描述等关键字段。
3. **假设** agent 定义来自不同来源（内置 / 用户 / 项目 / 插件），**则** 弹窗按来源分组展示（内置、用户、项目、插件），或至少以来源标签标识每个 agent。
4. **假设** agent 由插件提供，**则** 展示插件限定名（`插件名:agent名`），便于用户识别归属。
5. **假设** 同一名字在多个来源定义（高优先级覆盖低优先级），**则** 仅展示生效的定义，被覆盖的定义以弱化样式或 shadowed 标识展示（对齐 Claude Code `resolveAgentOverrides` 语义）。

### 用户故事：弹窗交互（优先级：P1）

作为用户，我希望 agents 弹窗遵循现有斜杠命令弹窗的交互规范（可关闭、可导航），以便与 `/tasks`、`/mcp` 等命令体验一致。

**验收场景**：

1. **假设** agents 弹窗已打开，**当** 用户按下 `Esc` 时，**则** 弹窗关闭，输入框恢复，用户回到之前的交互状态。
2. **假设** agents 弹窗已打开，**当** 用户按下 `Up` / `Down` 方向键时，**则** 在 agent 定义列表或活跃子代理列表中移动选中项。
3. **假设** agents 弹窗已打开且列表项可展开详情，**当** 用户按下 `Enter` 时，**则** 选中项展开详情（显示完整描述、工具列表、来源、系统提示词等，正文全量展开）。
4. **假设** agent 定义数量超过弹窗可视区域，**当** 用户滚动时，**则** 列表窗口滑动展示更多项，不破坏布局。

### 用户故事：详情页正文全量展示（优先级：P1）

作为用户，我希望详情页中的系统提示词 markdown 正文全量展开渲染（不限制高度、不裁剪、不滚动），与 Claude Code AgentDetail 行为一致，以便完整阅读 agent 的提示词。

**验收场景**：

1. **假设** 详情页包含系统提示词正文，**则** 正文全量展开渲染，无高度上限、无滚动条与滚动提示。
2. **假设** 正文内容超出终端可视高度，**则** 弹窗不裁剪正文，超出部分由终端 scrollback 兜底（用户可滚动终端查看）。
3. **假设** 详情页打开，**当** 用户按下 `Esc` 或 `Enter` 时，**则** 返回列表视图（对齐 CC AgentDetail 的 Esc / Enter 返回行为）。

***

### 用户故事：图形界面三端打开设置页子代理选项卡（优先级：P2）

作为 图形界面三端（VS Code 扩展 / JetBrains 插件 / 桌面端）用户，我希望通过 `/agents` 斜杠命令直接唤起设置页面并选中「子代理」选项卡，以查看当前会话可见的所有 agent 定义（名字 + 模型 + 描述，按来源分 Tab），并能进入详情查看完整配置，以便在不切换到 CLI 的情况下了解可用的子代理。

**为什么是这个优先级**：CLI 已有 `/agents`；IDE 用户需要对等能力。设置页（批次 2）已提供「子代理」导航项，`/agents` 复用设置页入口避免维护独立的 agent 对话框（2026-08-29 用户拍板：弹窗内容迁移到设置页选项卡）。

**独立测试**：在 IDE 中输入 `/agents`，验证打开设置页并选中「子代理」选项卡，按来源 Tab 列出 agent 定义；选中某项进入详情视图显示完整配置；点击「返回」关闭设置页回到会话。

**验收场景**：

1. **假设** 用户处于图形界面三端（VS Code 扩展 / JetBrains 插件 / 桌面端），**当** 用户输入 `/agents` 并发送，**则** 打开设置页并选中「子代理」选项卡（桌面端打开全页设置，IDE 打开编辑器区域设置标签页），不再弹出独立对话框。
2. **假设** 设置页「子代理」选项卡已打开，**则** 顶部展示「插件子代理 / 内置子代理 / 用户子代理 / 项目子代理」四个来源 Tab，默认选中首个包含子代理的 Tab，每项展示名字、模型（未显式配置时显示默认模型或占位符）、描述等关键字段。
3. **假设** agent 由插件提供，**则** 列表项展示插件限定名（`插件名:agent名`），便于用户识别归属。
4. **假设** 同一名字在多个来源定义（高优先级覆盖低优先级），**则** 仅展示生效的定义，被覆盖的定义以弱化样式或 shadowed 标识展示（对齐 CLI 语义）。
5. **假设** 用户选中某个 agent 定义，**当** 用户点击列表项，**则** 进入详情视图，展示完整配置（描述、模型、来源、工具列表、文件路径、系统提示词正文），并提供「返回列表」操作。
6. **假设** 详情页系统提示词正文较长，**则** 正文在详情区域内完整渲染、可滚动阅读，不截断内容（对齐现有对话框正文展示规范）。
7. **假设** 设置页已打开，**当** 用户点击「返回」或切换其他选项卡，**则** 回到会话视图或切换到对应选项卡，设置页不产生任何消息。

***

### 用户故事：按来源 Tab 展示子代理（优先级：P1）

作为 GUI 用户，我希望设置页「子代理」选项卡按来源以 Tab 形式展示子代理，其中项目子代理在「项目子代理」Tab 下平铺展示（仅当前项目，不做多项目分组），以便快速定位某个来源下的子代理，并知道它属于哪一类（用户 / 项目 / 插件 / 内置）。

**为什么是这个优先级**：子代理来源决定其适用范围与可信度，Tab 化让长列表可扫读，与技能页形态统一（2026-08-29 用户拍板：子代理与技能页一致，4 个来源 Tab + 项目分组卡片；2026-09-01 用户拍板：设置页只针对当前项目，删除项目分组卡片，项目 Tab 直接平铺）。

**独立测试**：在具备多种来源子代理的环境中打开设置页子代理选项卡，验证四个来源 Tab 存在、项目子代理在「项目子代理」Tab 平铺列出并可执行管理操作。

**验收场景**：

1. **假设** 环境中存在插件、内置、用户、项目四种来源的子代理，**当** 子代理选项卡打开，**则** 顶部展示四个来源 Tab（插件子代理 / 内置子代理 / 用户子代理 / 项目子代理），点击切换显示对应来源的子代理
2. **假设** 存在项目子代理，**当** 用户位于「项目子代理」Tab，**则** 子代理平铺展示（不按项目分组、无项目卡片）
3. **假设** 项目 Tab 下存在多个子代理，**当** 列表展示，**则** 列出所有子代理（名称、描述、模型、工具），并提供「编辑」「删除」操作入口
4. **假设** 项目子代理来源可写（项目目录或用户目录），**当** 项目 Tab 展示，**则** 提供「新增指令」入口用于新建子代理
5. **假设** 某来源没有任何子代理，**当** 切换到该来源 Tab，**则** 显示空状态提示，不渲染空白分组

***

### 用户故事：新建子代理（优先级：P1）

作为 GUI 用户，我希望在子代理页点击「新增子代理」后打开 AI 对话框并预填一条新建子代理提示词，通过自然语言描述子代理用途、工具与模型即可创建子代理，新子代理创建后出现在对应来源分组中并带来源标识。

**为什么是这个优先级**：手动创建子代理 markdown 文件门槛高；由 AI 根据自然语言生成文件是用户需求的核心（2026-08-29 用户需求：打开 AI 对话框，让用户通过自然语言描述创建子代理）。

**独立测试**：在子代理页点击「新增子代理」，验证 AI 对话框打开并预填提示词；补充描述发送后子代理文件被创建；返回子代理页验证新子代理出现在对应来源分组且带来源标识。

**验收场景**：

1. **假设** 用户在子代理页，**当** 用户点击「新增子代理」入口，**则** 关闭设置页回到会话视图，AI 对话框（主输入框）打开并预填用户级提示词，如 `帮我新建用户级子代理<名字>：用于<用途>，工具用<工具列表>，模型用<模型>`
2. **假设** 用户在「项目子代理」Tab 点击「新增指令」，**当** 输入框预填，**则** 预填项目级提示词并带上项目名，如 `帮我在【项目名称】新建子代理<名字>：用于<用途>，工具用<工具列表>，模型用<模型>`
3. **假设** 提示词已预填，**当** 用户补充子代理名字、用途、工具与模型后发送，**则** 消息以普通用户消息发送（预填文本可编辑），由 AI 在对应来源目录创建子代理 markdown 文件
4. **假设** 子代理创建成功，**当** 用户重新打开子代理页或列表刷新，**则** 新子代理出现在对应来源分组（Tab）中，并带来源标识（用户 / 项目 / 插件）
5. **假设** 新建的是项目子代理，**当** 子代理页「项目子代理」Tab 展示，**则** 新子代理出现在该 Tab 的列表中

***

### 用户故事：编辑子代理（优先级：P2）

作为 GUI 用户，我希望在子代理页点击「编辑」后打开 AI 对话框并预填一条编辑提示词，同时在编辑器中打开该子代理的 markdown 文件，以便基于当前内容描述修改点，由 AI 更新子代理。

**为什么是这个优先级**：子代理内容修改通过 AI 自然语言描述更顺畅；同时打开 markdown 文件让用户与 AI 都能直接看到/编辑实际文件（2026-08-29 用户需求：打开 AI 对话框，给出编辑提示词，同时打开子代理文件）。

**独立测试**：在子代理页点击某子代理的「编辑」，验证 AI 对话框打开并预填编辑提示词、子代理 markdown 文件在编辑器打开；描述修改点并发送后子代理文件被更新；返回子代理页验证描述等元数据已更新。

**验收场景**：

1. **假设** 用户在子代理页某子代理条目上，**当** 用户点击「编辑」，**则** 关闭设置页回到会话视图，AI 对话框打开并预填编辑提示词，如 `帮我编辑子代理<名字>：把<要改的内容>改成<新内容>`
2. **假设** 用户点击「编辑」，**则** 该子代理的 markdown 文件同时打开便于对照修改（桌面端在右侧文件面板打开该文件，即消息中 read/edit/write 工具路径点击同款只读面板；IDE 在 VS Code / JetBrains 自身编辑器打开标签页）
3. **假设** 编辑提示词已预填，**当** 用户补充具体修改点后发送，**则** 消息以普通用户消息发送，由 AI 更新子代理 markdown 文件
4. **假设** 子代理修改成功，**当** 用户重新打开子代理页或列表刷新，**则** 子代理描述等元数据反映修改后的内容

***

### 用户故事：删除子代理（优先级：P1）

作为 GUI 用户，我希望在子代理页对用户级 / 项目级子代理执行「删除」时先出现二次确认，确认后子代理文件被直接删除并从列表移除，以便清理不再需要的子代理。

**为什么是这个优先级**：删除不可逆，需要确认；用户需求明确「二次确认后删除」且删除不依赖 AI（2026-08-29 用户拍板：确认框 + 直接删除文件）。

**独立测试**：在子代理页点击某子代理「删除」，验证出现确认对话框；确认后子代理文件被删除、列表移除该子代理；取消则无任何变化。

**验收场景**：

1. **假设** 用户在子代理页某用户级 / 项目级子代理条目上，**当** 用户点击「删除」，**则** 弹出二次确认对话框，说明将删除的子代理名及其文件路径
2. **假设** 确认对话框已显示，**当** 用户点击「取消」或关闭对话框，**则** 不执行删除，子代理保持原样
3. **假设** 确认对话框已显示，**当** 用户点击「确认删除」，**则** 子代理 markdown 文件被直接删除，列表移除该子代理，不经过 AI
4. **假设** 删除成功，**当** 用户重新打开子代理页或列表刷新，**则** 该子代理不再出现在任何来源分组中
5. **假设** 子代理为内置或插件提供，**当** 列表展示，**则** 不提供「删除」入口（只读来源不可删除）

***

### 边界情况

* **agent 定义尚未加载完成怎么办？** 弹窗展示加载中或空态占位，不抛错；待配置就绪后展示完整列表。
* **插件 agent 与内置 agent 重名怎么办？** 插件 agent 使用 `插件名:agent名` 限定名，不与内置 agent 冲突。
* **弹窗打开期间 agent 被销毁 / 会话切换怎么办？** 弹窗随输入框状态关闭或清空，不残留过期引用。
* **用户快速重复打开 `/agents` 怎么办？** 不创建多个重叠视图，打开新弹窗前关闭旧的（与现有命令一致）。
* **agent 定义字段缺失怎么办？** 缺失字段（如未配置 model / tools）显示占位符或省略，不崩溃。
* **详情页系统提示词正文超长怎么办？** 正文全量展开渲染（对齐 CC AgentDetail），不限制高度、不裁剪、不引入滚动；超出终端部分由终端 scrollback 兜底。
* **终端高度很小怎么办？** 正文不设高度上限；列表窗口仍按可用行数收缩（沿用现有弹窗窗口切片），弹窗不因正文裁剪丢失内容。
* **详情页打开时方向键行为？** 详情页不响应方向键（对齐 CC AgentDetail 仅 Esc / Enter 返回列表），返回列表后方向键恢复列表导航。
* **IDE 中 agent 定义尚未加载完成怎么办？** 设置页「子代理」选项卡展示加载中或空态占位，不抛错；待 host 返回配置后展示完整列表。
* **IDE 中 host 拉取 agent 定义失败怎么办？** 选项卡展示空态或错误提示，不阻塞输入、不影响会话。
* **IDE 中设置页打开期间会话切换 / 销毁怎么办？** 设置页为独立页面（desktop 全页 / IDE 编辑器区域标签页），不依赖会话生命周期；返回后会话状态不受影响。
* **新建/编辑子代理提示词怎么发送？** GUI 中预填文本作为普通用户消息原样发送给 AI（无本地斜杠命令拦截），AI 负责创建 / 更新子代理 markdown 文件
* **删除子代理失败怎么办？** host 删除文件失败（权限不足 / 文件已不存在）时，向 webview 返回错误提示，列表保持删除前状态，不静默失败
* **用户级 / 项目级子代理文件路径如何确定？** 用户级写 `~/.wave/agents/<名字>.md`，项目级写 `<项目工作目录>/.wave/agents/<名字>.md`（与现有子代理发现路径一致）
* **项目级子代理的目标项目是哪个？** 三端设置页均为单项目模型——展示/管理当前会话 workdir 的项目级配置；新建/编辑项目级子代理的目标项目 = 当前对话的 workdir，AI 对话框直接写入该项目目录（2026-08-29 用户拍板：不做跨项目选择；2026-09-01 项目 Tab 平铺展示，无项目分组归属推断）
