命令系统负责处理用户显式输入的 /xxx 操作。它和 Tool System 是并行体系,不应混为一谈。
src/commands.ts命令总注册表src/types/command.ts或相关命令类型定义 命令 contractsrc/commands/*各个命令的具体实现src/skills/loadSkillsDir.tsskill 命令加载src/utils/plugins/loadPluginCommands.tsplugin 命令加载
- 面向用户显式输入
- 由
/commit、/review、/memory之类触发 - 更像“交互入口”或“操作模式切换”
- 面向模型内部推理
- 由
tool_use触发 - 更像“执行能力”
这两个体系并行存在,是 Claude Code 架构里最容易被误解的点之一。
flowchart LR
User[/用户输入 /]
Parser[命令解析]
Registry[commands.ts]
Builtin[内建命令]
Skills[skill dir commands]
Plugins[plugin commands]
Result[本地执行 / 生成 prompt / 模式切换]
User --> Parser
Parser --> Registry
Registry --> Builtin
Registry --> Skills
Registry --> Plugins
Builtin --> Result
Skills --> Result
Plugins --> Result
它不只是 import 所有命令,更重要的是把多种来源统一进一套注册体系:
- builtin commands
- feature-gated commands
- skills 派生命令
- plugin 派生命令
并且存在大量 lazy import,用来降低冷启动成本。
从结构上看,命令大致有几类:
- 本地执行类
- 生成 prompt 类
- 模式切换类
- 配置类
- 会话管理类
例如:
/compact/memory/resume/mcp/permissions
sequenceDiagram
participant U as User
participant R as REPL
participant C as commands.ts
participant CMD as specific command
U->>R: /command args
R->>C: 根据名字查找命令
C->>CMD: 执行命令 contract
CMD-->>R: 本地结果 / prompt / 状态更新
Claude Code 不把命令固定死,是因为它希望这几个体系都能扩展:
- skills
- plugins
- 产品 feature
- 环境差异
因此 commands.ts 更像一个“命令聚合器”,不是单纯索引。
重点观察:
- 哪些命令是同步 import
- 哪些命令走 lazy require
- skills/plugins 如何并入
这几个命令很适合作为代表样本:
- 一个偏状态管理
- 一个偏外部集成
- 一个偏 agent 工作流
- 命令和工具明确分层
- 注册中心能融合 builtin、skill、plugin 三种来源
- 大量使用延迟加载控制启动成本
- 很多命令本质上是“切换运行时行为”,不是单纯输出文本
先看 src/commands.ts,再挑 memory / mcp / resume / review / permissions 几组命令深入。