Skip to content

命令路由

70+ 个斜杠命令,全靠 commands.ts 这 754 行代码调度。路由、过滤、安全隔离,麻雀虽小五脏俱全。

命令类型

Claude Code 定义了三种命令类型:

LocalCommand

本地命令,延迟加载模块:

typescript
interface LocalCommand {
  type: 'local'
  name: string
  description: string
  load: () => Promise<Module>
  supportsNonInteractive?: boolean
}

大部分命令都是这种。/help/clear/config 都是 LocalCommand。

LocalJSXCommand

返回 JSX 组件的命令,用于需要复杂 UI 交互的场景:

typescript
interface LocalJSXCommand {
  type: 'local-jsx'
  load: () => Promise<JSXModule>
}

PromptCommand

AI 技能命令,执行时会调用模型:

typescript
interface PromptCommand {
  type: 'prompt'
  progressMessage: string
  contentLength: number
  argNames?: string[]
  allowedTools?: string[]
}

/commit/review 这类需要 AI 参与的命令都是 PromptCommand。

命令分类

约 73 个基础命令,分五组:

类别命令示例
会话管理/init, /resume, /clear, /compact, /exit
代码操作/commit, /review, /diff, /pr_comments
配置/config, /permissions, /model, /theme, /vim
工具/help, /export, /stats, /cost, /doctor
高级/agents, /tasks, /bridge, /mcp, /ultraplan

安全过滤

不是所有命令在所有模式下都可用。三套过滤规则:

  • REMOTE_SAFE_COMMANDS(17 个)— 远程模式下可用的命令
  • BRIDGE_SAFE_COMMANDS(6 个)— Bridge 模式下可用的命令
  • INTERNAL_ONLY_COMMANDS(31 个)— 仅内部构建可用

为什么需要过滤?因为远程模式下执行 /clear 可能清掉别人的会话,Bridge 模式下某些文件操作可能越权。安全第一。

核心函数

loadAllCommands()

typescript
// memoized,只加载一次
const loadAllCommands = memoize(() => {
  // 合并所有命令源
  return [...localCommands, ...jsxCommands, ...promptCommands]
})

getCommands()

返回过滤后的命令列表,根据当前模式和权限做筛选。

clearConversation()

清除会话的函数,做的事情比你想的多——20+ 种缓存需要清理:

  • 消息历史
  • 工具状态
  • MCP 连接
  • 文件变更记录
  • UI 状态
  • ……