---
url: /wave-agent/specs/commands/skills-command.md
description: '`/skills` 浏览、新建、编辑与删除技能，按来源分组与 Tab 展示；CLI 终端覆盖层与 IDE 设置页技能选项卡两入口'
---

# 功能规格说明：/skills 斜杠命令

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

> 覆盖 CLI 与图形界面三端（VS Code 扩展 / JetBrains 插件 / 桌面端）两种入口：CLI 为终端管理器覆盖层，图形界面三端打开设置页并选中「技能」选项卡（`/skills` → 技能，`/agents` → 子代理；复用设置页导航，不另起对话框，数据经 `getSkillMetadata` RPC 由 host 下发）。

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

### 用户故事：浏览可用技能（优先级：P1）

作为用户，我希望通过 `/skills` 命令查看当前环境中所有可用的技能，以便了解 Wave 拥有哪些能力、技能来自哪里，并决定何时调用它们。

**为什么是这个优先级**：技能默认由 AI 自主调用，用户缺乏可见性；列表浏览是技能发现的基础功能（对齐 Claude Code 的 `/skills` 命令，但交互采用 Wave 现有的管理器覆盖层模式）。

**独立测试**：可以通过在聊天中输入 `/skills` 并验证覆盖层显示按来源分组的技能列表、可导航并关闭来完整测试。

**验收场景**：

1. **假设** 环境中存在至少一个技能，**当** 用户在聊天中输入 `/skills`，**则** 显示技能管理器覆盖层，按来源分组列出所有可用技能
2. **假设** 技能管理器覆盖层已打开，**当** 用户按 `↑`/`↓` 键，**则** 选中高亮在技能条目间移动（分组标题不可选中）
3. **假设** 技能管理器覆盖层已打开，**当** 用户按 `Esc` 键，**则** 覆盖层关闭，对话界面恢复且不产生任何消息
4. **假设** 环境中不存在任何技能，**当** 用户执行 `/skills`，**则** 显示空状态提示及技能创建位置指引

***

### 用户故事：按来源分组与排序（优先级：P1）

作为用户，我希望技能列表按来源分组（内置 / 用户 / 项目 / 插件），以便快速区分哪些技能随产品内置、哪些来自个人配置、项目共享或插件扩展。

**为什么是这个优先级**：来源是用户判断技能可信度与适用场景的首要信息，分组展示使长列表可扫读。

**独立测试**：可以通过在不同来源目录放置技能并验证覆盖层正确分组与排序来测试。

**验收场景**：

1. **假设** 存在内置、用户级、项目级和插件来源的技能，**当** 覆盖层显示列表，**则** 技能按「内置技能 / 用户技能 / 项目技能 / 插件技能」四个分组展示，每个分组有标题行
2. **假设** 某来源没有任何技能，**当** 覆盖层显示列表，**则** 该分组的标题行不显示
3. **假设** 同一分组内有多个技能，**当** 覆盖层显示列表，**则** 组内技能按名称字母序排列
4. **假设** 插件技能存在，**当** 覆盖层显示列表，**则** 插件技能显示在插件分组中，并标注其所属插件名

***

### 用户故事：斜杠指令弹窗标识技能来源（优先级：P1）

作为 GUI（VS Code 扩展 / JetBrains 插件 / 桌面端）用户，我希望在输入框输入 `/` 弹出的指令选择器中，每条技能命令旁带来源标签（内置 / 用户 / 项目 / 插件），以便在命令入口一眼区分技能来源，不必打开技能管理器也能判断技能归属。

**为什么是这个优先级**：技能以斜杠命令形态直接出现在指令弹窗的「技能」分组中，来源标签让用户在同列表里区分随产品内置 / 个人配置 / 项目共享 / 插件扩展的技能（Bug 3466449778535424；数据链路为 SDK `SlashCommand.skillSource` → host `slashCommandsResponse` 透传 → 弹窗行渲染标签）。

**独立测试**：构造内置、用户级、项目级、插件技能后打开指令弹窗，验证各技能行展示对应来源标签；无来源命令（系统指令、插件命令等）不展示标签。同时验证弹窗只有「系统指令」「技能」两个分组、分组判据是命令自身是否来自技能（`skillSource` 有无），宿主新增的内置指令不登记任何名单即落在「系统指令」。

**验收场景**：

1. **假设** 会话中存在来源不同的技能（内置 / 用户 / 项目 / 插件），**当** 用户在输入框输入 `/` 打开指令弹窗，**则** 每个技能命令行展示对应的来源标签（内置 / 用户 / 项目 / 插件），命令本身照常可选中执行
2. **假设** 技能由个人目录提供（personal，如 `~/.wave/skills`），**当** 弹窗展示该技能命令，**则** 标签为「用户」
3. **假设** 技能由插件提供（命令名带 `插件名:` 前缀），**当** 弹窗展示该技能命令，**则** 标签为「插件」
4. **假设** 弹窗列表包含系统指令 / 插件命令等非技能条目，**当** 展示列表，**则** 这些条目不显示来源标签（仅技能条目有标签）
5. **假设** 弹窗中某技能条目处于键盘选中/高亮态，**当** 展示，**则** 来源标签保持可读，不随选中态消失或失真
6. **假设** 技能条目同时承载命令名、来源标签与描述文字，**当** 弹窗在字体行高不同的宿主环境下展示，**则** 三类文本各自完整可读——标签不溢出命令名所在行、描述不与标签重叠
7. **假设** 宿主下发的命令列表里既有技能命令（带 `skillSource`）也有非技能命令（宿主本地指令、磁盘自定义命令、插件命令），**当** 弹窗展示列表，**则** 只有「系统指令」「技能」两个分组：「系统指令」在前且收纳全部非技能命令（含 `/plugin`——插件市场已外化为独立入口，不再单列「插件管理」分组），「技能」收纳全部带 `skillSource` 的命令；分组判据是数据本身（`skillSource` 有无）而非命令名名单，宿主新增内置指令（如 `/hooks` `/plan` `/resume` `/reload-plugins`）无须同步弹窗代码即落在「系统指令」

***

### 用户故事：查看技能详情（优先级：P2）

作为用户，我希望选中一个技能后查看其详细信息（描述、来源、路径、模型、工具限制、调用方式），以便判断该技能是否适合当前任务以及如何使用它。

**为什么是这个优先级**：仅凭名称和描述不足以评估技能，详情视图帮助用户做出调用决策；属于增强而非核心浏览功能。

**独立测试**：可以通过在列表中选择技能并按 `Enter` 验证详情视图渲染完整元数据来测试。

**验收场景**：

1. **假设** 技能管理器覆盖层已打开且某技能被选中，**当** 用户按 `Enter`，**则** 进入该技能的详情视图，显示描述、来源分组、文件路径等元数据
2. **假设** 技能定义了模型或关联代理，**当** 详情视图显示，**则** 展示配置的模型/代理信息
3. **假设** 技能定义了 `allowed-tools` 限制，**当** 详情视图显示，**则** 展示受限工具列表
4. **假设** 技能设置了 `user-invocable: false` 或 `disable-model-invocation: true`，**当** 详情视图显示，**则** 标注对应的调用限制
5. **假设** 详情视图已打开，**当** 用户按 `Esc` 或 `Enter`，**则** 返回列表视图

***

### 用户故事：技能变更实时反映（优先级：P2）

作为用户，我希望技能列表在技能文件新增、修改或删除后自动更新，以便无需重启会话即可看到最新技能集合。

**为什么是这个优先级**：技能是热加载的，列表应与实际可用技能保持一致，避免信息过期误导用户。

**独立测试**：可以通过在会话运行中新增/删除一个 SKILL.md 并重新打开 `/skills` 验证列表已更新来测试。

**验收场景**：

1. **假设** 会话运行中在技能目录新增了技能，**当** 用户重新执行 `/skills`，**则** 新技能出现在对应分组中
2. **假设** 会话运行中删除了某技能，**当** 用户重新执行 `/skills`，**则** 该技能不再出现在列表中
3. **假设** 技能管理器覆盖层正处于打开状态，**当** 技能文件发生变更，**则** 覆盖层不崩溃，下次打开时反映最新状态

***

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

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

**为什么是这个优先级**：CLI 已有 `/skills`；IDE 用户需要对等能力。设置页（批次 2）已提供「技能」导航项，`/skills` 复用设置页入口避免维护独立的技能对话框（2026-08-29 用户拍板：弹窗内容迁移到设置页选项卡；2026-08-29 用户拍板：技能页从分组列表改为「插件技能 / 内置技能 / 用户技能 / 项目技能」四个来源 Tab）。

**独立测试**：在 IDE 中输入 `/skills`，验证打开设置页并选中「技能」选项卡，按来源 Tab 列出技能；选中某项进入详情视图显示完整元数据；点击「返回」关闭设置页回到会话。

**验收场景**：

1. **假设** 用户处于图形界面三端（VS Code 扩展 / JetBrains 插件 / 桌面端），**当** 用户输入 `/skills` 并发送，**则** 打开设置页并选中「技能」选项卡（桌面端打开全页设置，IDE 打开编辑器区域设置标签页），不再弹出独立对话框。
2. **假设** 设置页「技能」选项卡已打开，**则** 顶部展示「插件技能 / 内置技能 / 用户技能 / 项目技能」四个来源 Tab，默认选中首个包含技能的 Tab，每项展示名字、所属插件名（插件技能）、描述等关键字段。
3. **假设** 技能由插件提供，**则** 列表项展示插件限定名（`插件名:技能名`）与所属插件名，便于用户识别归属。
4. **假设** 用户选中某个技能，**当** 用户点击列表项，**则** 进入详情视图，展示完整元数据（描述、来源、路径、模型、Agent、允许的工具、调用方式），并提供「返回列表」操作。
5. **假设** 技能设置了 `user-invocable: false` 或 `disable-model-invocation: true`，**当** 详情视图显示，**则** 标注对应的调用限制
6. **假设** 选项卡中不存在任何技能，**则** 显示空状态提示（对齐 CLI 空态语义）
7. **假设** 设置页已打开，**当** 用户点击「返回」或切换其他选项卡，**则** 回到会话视图或切换到对应选项卡，设置页不产生任何消息。

***

### 用户故事：按来源 Tab 展示技能（优先级：P1）

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

**为什么是这个优先级**：技能来源（用户/项目/插件/内置）决定其适用范围与可信度，Tab 化让长列表可扫读，是对齐设计稿的基础形态（2026-08-29 用户拍板：按截图改造，项目技能按项目分组卡片展示；2026-09-01 用户拍板：设置页只针对当前项目，删除项目分组卡片，项目 Tab 直接平铺）。

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

**验收场景**：

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

***

### 用户故事：新建技能（优先级：P1）

作为 GUI 用户，我希望在技能页点击「新建技能 / 新增指令」后打开 AI 对话框并预填一条新建技能提示词，通过自然语言描述技能用途与内容即可创建技能，新技能创建后出现在对应来源分组中并带来源标识。

**为什么是这个优先级**：手动创建技能目录与 SKILL.md 门槛高；由 AI 根据自然语言生成技能文件是用户需求的核心（2026-08-29 用户需求：打开 AI 对话框，给出新建技能提示词，让用户通过自然语言描述创建技能）。

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

**验收场景**：

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

***

### 用户故事：编辑技能（优先级：P2）

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

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

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

**验收场景**：

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

***

### 用户故事：删除技能（优先级：P1）

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

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

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

**验收场景**：

1. **假设** 用户在技能页某用户级 / 项目级技能条目上，**当** 用户点击「删除」，**则** 弹出二次确认对话框，说明将删除的技能名及其文件路径
2. **假设** 确认对话框已显示，**当** 用户点击「取消」或关闭对话框，**则** 不执行删除，技能保持原样
3. **假设** 确认对话框已显示，**当** 用户点击「确认删除」，**则** 该技能在其来源作用域内的全部同名副本目录（如用户技能分布于 `~/.wave/skills`、`~/.claude/skills`、`~/.agents/skills` 的副本；项目技能分布于项目下 `.wave/.claude/.agents/skills` 的副本）被一次直接删除，列表移除该技能，不经过 AI
4. **假设** 删除成功，**当** 用户重新打开技能页或技能列表刷新，**则** 该技能不再出现在任何来源分组中，且刷新前列表不会出现瞬时为空或已被删除技能残留（同名副本不会在下次扫描时重新出现）
5. **假设** 技能为内置或插件提供，**当** 列表展示，**则** 不提供「删除」入口（只读来源不可删除）

***

### 边界情况

* **无技能**：环境中没有任何技能时，显示空状态与创建指引（如 `.wave/skills/` 与 `~/.wave/skills/`），而不是空白面板
* **技能名冲突**：同名技能存在于多个来源（内置/用户/项目/插件）时，各来源独立看待，删除只清理被删条目的来源作用域；同一来源（如用户级）的同名副本分布于多个目录（`~/.wave/skills`、`~/.claude/skills`、`~/.agents/skills`）时按优先级合并为单条展示，删除一次清理全部副本
* **删除后的列表刷新**：删除触发技能重扫时，列表按原子快照刷新——不出现「先清空再回填」的瞬时空列表，也不残留已删技能（低优先级目录中的同名副本已在同一次删除中清理，不会在重扫后重新出现）
* **无效技能文件**：SKILL.md 校验失败的技能不进入列表，其错误已由现有技能加载流程记录日志
* **超长描述**：技能描述过长时在列表中截断显示，详情视图完整显示
* **大列表滚动**：技能数量超过可视区域时，列表可滚动且选中项保持在可视区域内
* **IDE 中技能元数据尚未加载完成怎么办？** 设置页「技能」选项卡展示加载中或空态占位，不抛错；待 host 返回元数据后展示完整列表
* **IDE 中 host 拉取技能元数据失败怎么办？** 选项卡展示空态或错误提示，不阻塞输入、不影响会话（host 返回空数组）
* **IDE 中设置页打开期间会话切换 / 销毁怎么办？** 设置页为独立页面（desktop 全页 / IDE 编辑器区域标签页），不依赖会话生命周期；返回后会话状态不受影响
* **新建/编辑技能提示词中的 `/settings` 前缀怎么办？** GUI 中 `/settings` 不是可拦截的本地斜杠命令，预填文本作为普通用户消息原样发送给 AI；提示词中的 `/settings` 前缀仅作为自然语言指令的一部分提示 AI 处理技能管理请求
* **删除技能失败怎么办？** host 删除文件失败（权限不足 / 文件已不存在）时，向 webview 返回错误提示，列表保持删除前状态，不静默失败
* **用户级 / 项目级技能名非法怎么办？** 技能目录名不符合技能命名规范（小写字母数字连字符）时，AI 创建时按规范处理；用户手动输入技能名不受 UI 校验约束，由 AI 在创建时规范化
* **项目技能的目标项目是哪个？** 三端设置页均为单项目模型——展示/管理当前会话 workdir 的项目级技能；「项目技能」Tab 平铺展示，无项目分组归属推断（2026-09-01 用户拍板：设置页只针对当前项目）
* **项目级配置的目标项目是哪个？** 三端设置页均为单项目模型——展示/管理当前会话 workdir 的项目级配置（desktop 跟随聚焦会话，VS Code 绑定 workspace 文件夹，JetBrains 绑定当前项目）；新建/编辑项目级配置的目标项目 = 当前对话的 workdir，AI 对话框直接写入该项目目录（2026-08-29 用户拍板：不做跨项目选择，多项目 chips 为设计稿后续扩展）
