docs/design/slash-command/roadmap.md
用 Qwen 内部架构风格,交付一个在外部体验上 95% 对齐 Claude Code 的 command 平台,同时修复三模式分裂、命令来源单一、prompt command 无法被模型调用三个核心问题。
建立统一的命令元数据模型和跨模式管理机制,为后续所有 Phase 提供底层支撑。
SlashCommand 元数据模型在现有 SlashCommand 接口上新增以下字段:
来源字段
source: CommandSource:命令来源枚举(builtin-command / bundled-skill / skill-dir-command / plugin-command / mcp-prompt 等)sourceLabel?: string:展示用的来源标签(如 "Built-in" / "MCP: github-server")模式能力字段
supportedModes: ExecutionMode[]:声明在哪些运行模式下可用(interactive / non_interactive / acp)执行类型字段
commandType: CommandType:声明执行类型(prompt / local / local-jsx)可见性字段
userInvocable: boolean:用户是否可通过 slash command 调用(默认 true)modelInvocable: boolean:模型是否可通过 tool call 调用(默认 false)辅助元数据字段(为 Phase 3 预留,Phase 1 仅定义,不使用)
argumentHint?: string:参数提示,如 "<model-id>" / "show|list|set"whenToUse?: string:何时调用该命令的说明(供模型使用)examples?: string[]:使用示例每个 Loader 在构建 SlashCommand 时必须填充 source 和 commandType:
| Loader | source | commandType |
|---|---|---|
BuiltinCommandLoader | builtin-command | 由各命令声明(local / local-jsx) |
BundledSkillLoader | bundled-skill | prompt |
FileCommandLoader(用户/项目) | skill-dir-command | prompt |
FileCommandLoader(插件) | plugin-command | prompt |
McpPromptLoader | mcp-prompt | prompt |
supportedModes 和 commandType为所有 built-in 命令显式声明:
commandType:local(无 UI 依赖)或 local-jsx(依赖 dialog/React)supportedModes:local 类命令声明 ['interactive', 'non_interactive', 'acp'];local-jsx 类命令声明 ['interactive']ALLOWED_BUILTIN_COMMANDS_NON_INTERACTIVE 常量filterCommandsForNonInteractive 函数filterCommandsForMode(commands, mode) 函数,基于 supportedModes 字段过滤getEffectiveSupportedModes(cmd) 工具函数(考虑 CommandKind 默认策略)handleSlashCommand / getAvailableCommands 函数签名,移除 allowedBuiltinCommandNames 参数getCommandsForMode(mode: ExecutionMode) 方法getModelInvocableCommands() 方法(Phase 2/3 使用,Phase 1 提供接口)getCommands() 保持不变(interactive 使用)SlashCommand 接口包含所有新字段,TypeScript 编译通过source 和 commandType 字段commandType 和 supportedModesALLOWED_BUILTIN_COMMANDS_NON_INTERACTIVE 已删除,被 capability filter 取代CommandService.getCommandsForMode('non_interactive') 返回正确的命令集基于 Phase 1 的元数据基础,扩展三种模式下的命令可用范围,并打通 prompt command 的模型调用通路。
ACP 语义设计原则
将命令扩展到 ACP/non-interactive 模式前,需遵循以下设计原则:
action 内部新增模式判断——interactive 路径保持现有 UI 渲染逻辑不变,non_interactive/acp 路径返回适合机器消费的 message 或 submit_prompt。两条路径共存于同一个 action 函数中。-p 参数),/model set、/language set 等有状态命令的变更仅在本次 session 内有效,应在命令响应文本中注明。/about、/stats)直接返回当前状态文本;有副作用命令(如 /model set、/language set)需在响应中确认操作结果。/docs、/insight)、操作剪贴板(/copy)等依赖图形环境的操作,在 non_interactive/acp 路径下应跳过,改为在响应文本中返回相关 URL 或内容本身。待扩展命令总览
注:
btw、bug、compress、context、init、summary已在 Phase 1 中扩展到全模式,不在本阶段列表中。
以下 13 个命令将在 Phase 2 中扩展到 non_interactive 和 acp 模式:
A 类:action 已返回 message 或 submit_prompt,只需扩展 supportedModes 并设计 ACP 消息内容
| 命令 | 返回类型 | ACP/non-interactive 处理要点 |
|---|---|---|
/copy | message | ACP 下无剪贴板,改为在响应文本中返回内容本身或提示 |
/export | message | 返回导出文件的完整路径 |
/plan | submit_prompt | 无需改动,直接扩展模式 |
/restore | message | 返回恢复操作的结果描述 |
/language | message | 返回当前语言设置或变更确认文本 |
/statusline | submit_prompt | 无需改动,直接扩展模式 |
A' 类:有参数时正常执行,无参数时触发 dialog(需增加无参数路径的 non-interactive 处理)
| 命令 | 无参数 interactive 行为 | 无参数 non_interactive/acp 行为 |
|---|---|---|
/model | 打开模型选择 dialog | 返回当前模型名称及说明文本 |
/approval-mode | 打开审批模式 dialog | 返回当前审批模式及说明文本 |
B 类:action 内部使用 context.ui.addItem() 渲染 React 组件,需增加模式分支返回纯文本
| 命令 | interactive 行为 | non_interactive/acp 返回内容 |
|---|---|---|
/about | 渲染版本/配置 React 组件 | 版本号、当前模型、关键配置的纯文本摘要 |
/stats | 渲染 token/费用统计组件 | session 统计数据的纯文本格式 |
/insight | 渲染分析组件 + 打开浏览器 | non_interactive 同步生成返回文件路径;acp 通过 stream_messages 推送进度和结果 |
/docs | 渲染文档入口 + 打开浏览器 | 返回文档 URL,不打开浏览器 |
C 类:特殊处理
| 命令 | interactive 行为 | non_interactive/acp 行为 |
|---|---|---|
/clear | 调用 context.ui.clear() 清空终端显示 | 返回上下文边界标记 message,内容为 "Context cleared. Previous messages are no longer in context." |
CommandService(或 CommandRegistry)中实现 getModelInvocableCommands(),返回所有 modelInvocable: true 的命令BundledSkillLoader、FileCommandLoader(用户/项目命令)加载的命令标记为 modelInvocable: truemodelInvocable:MCP prompt 通过独立的 MCP tool call 机制由模型调用,无需经过 SkillTool 中转SkillTool:从只消费 SkillManager.listSkills() 改为同时消费 CommandService.getModelInvocableCommands()SkillTool 的 descriptionInputPrompt 中检测光标附近的 slash token(不限于行首)modelInvocable: true 的命令(skill / file command)2.1 命令扩展
/copy、/export、/plan、/restore、/language、/statusline 在 non-interactive 和 acp 模式下可正常执行并返回有意义的文本输出/model、/approval-mode 无参数时在 non-interactive/acp 下返回当前状态文本(不触发 dialog);有参数时执行变更并返回确认文本/about、/stats、/docs 在 non-interactive/acp 下返回纯文本,/docs 不打开浏览器;/insight 在 non_interactive 下同步生成并返回文件路径 message,在 acp 下通过 stream_messages 推送进度/clear 在 non-interactive/acp 下返回上下文边界标记 message,不调用 context.ui.clear()2.2 模型调用
SkillTool 调用 bundled skill、file command(用户/项目)SkillTool,通过 MCP tool call 机制由模型原生调用userInvocable: true,modelInvocable: false)SkillTool 的 description 包含所有 modelInvocable 命令的描述2.3 mid-input slash
/ 后通过 inline ghost text 提示最佳匹配命令(Tab 接受)在 Phase 1/2 的元数据和命令能力基础上,补齐补全体验,并补充 Claude Code 中存在而 Qwen Code 缺失的命令。
source badge
[MCP] 已有,扩展为 [Skill]、[Custom] 等)source / sourceLabel 字段渲染argument hint
argumentHint(如 set <model-id>)argumentHint 由 Phase 1 元数据字段提供recently used 排序
alias 命中高亮
altNames 而非主名时,在展示时注明(如 help (alias: ?))冲突策略对齐
pluginName.commandName)/he 时显示 /help 的淡色提示)将 /help 从平铺列表改为分组目录:
每条命令展示:名称、argumentHint、description、source、supportedModes 标记
在 sendAvailableCommandsUpdate() 中将更多元数据暴露给 ACP 客户端:
argumentHintsourcesupportedModessubcommands(名称列表)modelInvocable补充 Qwen Code 当前没有、Claude Code 有且常用的命令:
| 命令 | 类型 | 说明 |
|---|---|---|
/doctor | local | 环境自检,输出配置/连接/工具状态诊断 |
/release-notes | local | 展示当前版本的更新日志 |
/cost | local | 展示当前 session 的 token 消耗和费用估算 |
注:
/review、/commit等任务类命令以 bundled skill 形式提供,不在此列。
[MCP]、[Skill]、[Custom])set <model-id>)/help 输出按来源分组,每条命令展示支持模式标记argumentHint、source、subcommands 字段/doctor、/release-notes、/cost 三个命令可用/doctor 在 non-interactive 模式下可执行(返回 message)Phase 1(元数据 + 统一过滤)
│
├──► Phase 2(能力扩展)
│ │
│ ├──► slash command 子命令拆分
│ └──► prompt command 模型调用(需要 getModelInvocableCommands())
│
└──► Phase 3(体验对齐)
│
├──► source badge(需要 Phase 1 source 字段)
├──► argument hint(需要 Phase 1 argumentHint 字段)
└──► Help 分组(需要 Phase 1 source 字段)
Phase 2 和 Phase 3 不互相依赖,可以并行推进(或根据优先级调换部分子项)。