0%

Claude Code 源码解析 (15):88+ 命令的架构设计

Claude Code 源码解析 (15):88+ 命令的架构设计

导读: 这是 Claude Code 20 个功能特性源码解析系列的第 15 篇,深入分析命令系统的架构设计。


📋 目录

  1. 问题引入:为什么需要命令系统?
  2. 技术原理:命令系统架构
  3. 设计思想:为什么这样设计
  4. 解决方案:完整实现详解
  5. OpenClaw 最佳实践
  6. 总结

问题引入:为什么需要命令系统?

痛点场景

场景 1:自然语言不够精确

1
2
3
4
5
6
用户:"帮我看看文件"

AI:打开哪个文件?怎么看?

→ 需要多轮对话澄清
→ 效率低

场景 2:复杂操作难表达

1
2
3
4
5
6
7
8
用户:"把项目里所有 Python 文件中的
print 语句都改成 logging,
然后运行测试,
把结果发到 Slack"

→ 自然语言太长
→ 容易理解错误
→ 需要精确命令

场景 3:重复操作繁琐

1
2
3
4
5
6
7
每天都要做:
- 检查天气
- 查看日历
- 阅读新闻

每天都要说一遍
→ 需要快捷命令

核心问题

设计 AI 助手的命令系统时,面临以下挑战:

  1. 组织问题

    • 如何组织大量命令?
    • 如何避免命令冲突?
  2. 发现问题

    • 用户如何知道有哪些命令?
    • 如何快速找到需要的命令?
  3. 执行问题

    • 如何解析命令参数?
    • 如何处理命令错误?
  4. 扩展问题

    • 如何添加自定义命令?
    • 如何支持命令插件?

Claude Code 用 88+ 子命令 + 命令注册机制解决了这些问题。


技术原理:命令系统架构

整体架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
┌─────────────────────────────────────────────────────────────┐
│ 用户输入 │
│ "/mcp list" 或 "list mcp servers" │
└─────────────────────┬───────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ Command Parser (命令解析器) │
│ - 识别命令前缀 (/、!) │
│ - 提取命令名和参数 │
│ - 处理引用和管道 │
└─────────────┬───────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ Command Router (命令路由器) │
│ - 命令匹配 │
│ - 别名解析 │
│ - 权限检查 │
└─────────────┬───────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ Command Registry (命令注册表) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 内置命令 (Built-in Commands) │ │
│ │ - /help, /config, /session │ │
│ │ - /mcp, /plugins, /skills │ │
│ │ - /agents, /tasks, /memory │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 命令组 (Command Groups) │ │
│ │ - /mcp list, /mcp add, /mcp delete │ │
│ │ - /plugins install, /plugins uninstall │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 自定义命令 (Custom Commands) │ │
│ │ - 用户定义 │ │
│ │ - 插件注册 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────┬───────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ Command Executor (命令执行器) │
│ - 参数验证 │
│ - 执行命令 │
│ - 处理结果 │
│ - 错误处理 │
└─────────────────────────────────────────────────────────────┘

命令定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
interface Command {
// 基本信息
name: string;
description: string;
aliases?: string[];

// 参数定义
args?: CommandArg[];
options?: CommandOption[];

// 执行
handler: (args: ParsedArgs, context: CommandContext) => Promise<CommandResult>;

// 权限
permissions?: string[];
requireAuth?: boolean;

// 帮助
examples?: string[];
relatedCommands?: string[];

// 元数据
category: CommandCategory;
hidden?: boolean;
deprecated?: boolean;
}

interface CommandArg {
name: string;
type: 'string' | 'number' | 'boolean' | 'path' | 'url';
required: boolean;
description?: string;
default?: any;
completions?: string[]; // 自动补全选项
}

interface CommandOption {
name: string;
shortName?: string; // 如 -v
type: 'string' | 'number' | 'boolean' | 'array';
required?: boolean;
description?: string;
default?: any;
alias?: string[];
}

type CommandCategory =
| 'general' // 通用命令
| 'file' // 文件操作
| 'agent' // Agent 管理
| 'tool' // 工具管理
| 'config' // 配置管理
| 'session' // 会话管理
| 'system'; // 系统命令

interface CommandResult {
success: boolean;
output?: string;
data?: any;
error?: string;
exitCode?: number;
}

命令解析器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
class CommandParser {
private prefixes = ['/', '!', '!'];
private quoteChars = ['"', "'", '`'];

// 解析命令输入
parse(input: string): ParsedCommand | null {
const trimmed = input.trim();

// 1. 检查是否是命令
if (!this.isCommand(trimmed)) {
return null;
}

// 2. 提取命令名和参数
const tokens = this.tokenize(trimmed);

if (tokens.length === 0) {
return null;
}

const commandName = tokens[0].substring(1); // 移除前缀
const args = tokens.slice(1);

// 3. 解析选项和参数
const parsedArgs = this.parseArgs(args);

return {
name: commandName,
args: parsedArgs.positional,
options: parsedArgs.options,
raw: input,
};
}

private isCommand(input: string): boolean {
return this.prefixes.some(prefix => input.startsWith(prefix));
}

private tokenize(input: string): string[] {
const tokens: string[] = [];
let currentToken = '';
let inQuote = false;
let quoteChar = '';

for (let i = 0; i < input.length; i++) {
const char = input[i];

// 处理引号
if (this.quoteChars.includes(char) && !inQuote) {
inQuote = true;
quoteChar = char;
continue;
}

if (char === quoteChar && inQuote) {
inQuote = false;
quoteChar = '';
continue;
}

// 处理空格
if (char === ' ' && !inQuote) {
if (currentToken) {
tokens.push(currentToken);
currentToken = '';
}
continue;
}

// 处理转义
if (char === '\\' && i < input.length - 1) {
i++;
currentToken += input[i];
continue;
}

currentToken += char;
}

// 添加最后一个 token
if (currentToken) {
tokens.push(currentToken);
}

return tokens;
}

private parseArgs(args: string[]): ParsedArgs {
const positional: string[] = [];
const options: Record<string, any> = {};

let i = 0;
while (i < args.length) {
const arg = args[i];

// 处理长选项 (--name=value 或 --name value)
if (arg.startsWith('--')) {
const [name, value] = arg.substring(2).split('=');

if (value !== undefined) {
// --name=value 格式
options[name] = this.parseValue(value);
} else if (i + 1 < args.length && !args[i + 1].startsWith('-')) {
// --name value 格式
options[name] = this.parseValue(args[i + 1]);
i++;
} else {
// 布尔选项
options[name] = true;
}
}
// 处理短选项 (-v 或 -abc)
else if (arg.startsWith('-') && arg.length === 2) {
const name = arg[1];

if (i + 1 < args.length && !args[i + 1].startsWith('-')) {
options[name] = this.parseValue(args[i + 1]);
i++;
} else {
options[name] = true;
}
}
// 处理组合短选项 (-abc = -a -b -c)
else if (arg.startsWith('-') && arg.length > 2) {
for (const char of arg.substring(1)) {
options[char] = true;
}
}
// 位置参数
else {
positional.push(arg);
}

i++;
}

return { positional, options };
}

private parseValue(value: string): any {
// 自动类型转换
if (value === 'true') return true;
if (value === 'false') return false;
if (value === 'null') return null;
if (/^\d+$/.test(value)) return parseInt(value);
if (/^\d+\.\d+$/.test(value)) return parseFloat(value);

// JSON 数组/对象
if (value.startsWith('[') || value.startsWith('{')) {
try {
return JSON.parse(value);
} catch {
// 不是有效 JSON,返回字符串
}
}

return value;
}
}

interface ParsedCommand {
name: string;
args: string[];
options: Record<string, any>;
raw: string;
}

interface ParsedArgs {
positional: string[];
options: Record<string, any>;
}

命令注册表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
class CommandRegistry {
private commands: Map<string, Command> = new Map();
private aliases: Map<string, string> = new Map();
private groups: Map<string, Command[]> = new Map();

// 注册命令
register(command: Command): void {
// 验证命令
this.validateCommand(command);

// 注册主命令
this.commands.set(command.name, command);

// 注册别名
if (command.aliases) {
for (const alias of command.aliases) {
this.aliases.set(alias, command.name);
}
}

// 添加到命令组
if (!this.groups.has(command.category)) {
this.groups.set(command.category, []);
}
this.groups.get(command.category)!.push(command);

console.log(`[CommandRegistry] Registered: ${command.name}`);
}

// 注册命令组
registerGroup(groupName: string, commands: Command[]): void {
for (const command of commands) {
const fullName = `${groupName}.${command.name}`;
command.name = fullName;
this.register(command);
}
}

// 获取命令
get(name: string): Command | undefined {
// 直接查找
if (this.commands.has(name)) {
return this.commands.get(name);
}

// 通过别名查找
const realName = this.aliases.get(name);
if (realName) {
return this.commands.get(realName);
}

return undefined;
}

// 列出所有命令
list(options?: ListOptions): Command[] {
let commands = Array.from(this.commands.values());

// 过滤隐藏命令
if (!options?.includeHidden) {
commands = commands.filter(cmd => !cmd.hidden);
}

// 过滤已废弃命令
if (!options?.includeDeprecated) {
commands = commands.filter(cmd => !cmd.deprecated);
}

// 按类别过滤
if (options?.category) {
commands = commands.filter(cmd => cmd.category === options.category);
}

// 搜索
if (options?.search) {
const search = options.search.toLowerCase();
commands = commands.filter(cmd =>
cmd.name.toLowerCase().includes(search) ||
cmd.description.toLowerCase().includes(search)
);
}

// 排序
commands.sort((a, b) => a.name.localeCompare(b.name));

return commands;
}

// 获取命令帮助
getHelp(commandName: string): string {
const command = this.get(commandName);

if (!command) {
return `Command not found: ${commandName}`;
}

let help = `\n# ${command.name}\n\n`;
help += `${command.description}\n\n`;

// 用法
help += `**用法**:\n`;
help += `\`/${command.name}\`;
if (command.args) {
for (const arg of command.args) {
help += arg.required ? ` <${arg.name}>` : ` [${arg.name}]`;
}
}
if (command.options) {
for (const opt of command.options) {
help += ` [--${opt.name}]`;
}
}
help += `\n\n`;

// 选项
if (command.options?.length) {
help += `**选项**:\n`;
for (const opt of command.options) {
const names = [`--${opt.name}`];
if (opt.shortName) names.push(`-${opt.shortName}`);
help += ` ${names.join(', ')}\t${opt.description}\n`;
}
help += `\n`;
}

// 示例
if (command.examples?.length) {
help += `**示例**:\n`;
for (const example of command.examples) {
help += `\`/${example}\`\n`;
}
help += `\n`;
}

// 相关命令
if (command.relatedCommands?.length) {
help += `**相关命令**:\n`;
for (const related of command.relatedCommands) {
help += `- /${related}\n`;
}
}

return help;
}

private validateCommand(command: Command): void {
if (!command.name) {
throw new Error('Command must have a name');
}

if (!command.description) {
throw new Error(`Command ${command.name} must have a description`);
}

if (!command.handler) {
throw new Error(`Command ${command.name} must have a handler`);
}
}
}

interface ListOptions {
includeHidden?: boolean;
includeDeprecated?: boolean;
category?: CommandCategory;
search?: string;
}

命令执行器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
class CommandExecutor {
private registry: CommandRegistry;
private context: CommandContext;

constructor(registry: CommandRegistry, context: CommandContext) {
this.registry = registry;
this.context = context;
}

// 执行命令
async execute(input: string): Promise<CommandResult> {
// 1. 解析命令
const parsed = new CommandParser().parse(input);

if (!parsed) {
return {
success: false,
error: 'Not a valid command',
exitCode: 1,
};
}

// 2. 查找命令
const command = this.registry.get(parsed.name);

if (!command) {
return {
success: false,
error: `Command not found: ${parsed.name}`,
exitCode: 1,
};
}

// 3. 检查权限
if (command.permissions) {
const hasPermission = await this.checkPermissions(command.permissions);
if (!hasPermission) {
return {
success: false,
error: 'Permission denied',
exitCode: 13,
};
}
}

// 4. 验证参数
const validation = this.validateArgs(command, parsed.args, parsed.options);
if (!validation.valid) {
return {
success: false,
error: validation.error,
exitCode: 1,
};
}

// 5. 执行命令
try {
const result = await command.handler(parsed, this.context);
return result;
} catch (error) {
return {
success: false,
error: error.message,
exitCode: 1,
};
}
}

private validateArgs(
command: Command,
positional: string[],
options: Record<string, any>
): ValidationResult {
// 检查必需参数
if (command.args) {
for (let i = 0; i < command.args.length; i++) {
const arg = command.args[i];

if (arg.required && i >= positional.length) {
return {
valid: false,
error: `Missing required argument: ${arg.name}`,
};
}
}
}

// 检查必需选项
if (command.options) {
for (const opt of command.options) {
if (opt.required && !(opt.name in options)) {
return {
valid: false,
error: `Missing required option: --${opt.name}`,
};
}
}
}

return { valid: true };
}

private async checkPermissions(permissions: string[]): Promise<boolean> {
// 检查用户权限
for (const permission of permissions) {
if (!this.context.user.permissions.includes(permission)) {
return false;
}
}
return true;
}
}

interface ValidationResult {
valid: boolean;
error?: string;
}

interface CommandContext {
user: {
id: string;
name: string;
permissions: string[];
};
cwd: string;
env: Record<string, string>;
}

内置命令示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// /help 命令
const helpCommand: Command = {
name: 'help',
description: '显示命令帮助信息',
aliases: ['h', '?'],
category: 'general',

args: [
{
name: 'command',
type: 'string',
required: false,
description: '要查询的命令名',
completions: () => registry.list().map(c => c.name),
},
],

handler: async (args, context) => {
if (args.positional.length > 0) {
const commandName = args.positional[0];
const help = registry.getHelp(commandName);
return { success: true, output: help };
}

// 列出所有命令
const commands = registry.list();
let output = '可用命令:\n\n';

const byCategory: Record<string, Command[]> = {};
for (const cmd of commands) {
if (!byCategory[cmd.category]) {
byCategory[cmd.category] = [];
}
byCategory[cmd.category].push(cmd);
}

for (const [category, cmds] of Object.entries(byCategory)) {
output += `**${category}**:\n`;
for (const cmd of cmds) {
output += ` /${cmd.name}\t${cmd.description}\n`;
}
output += '\n';
}

return { success: true, output };
},
};

// /mcp 命令组
const mcpCommands: Command[] = [
{
name: 'mcp.list',
description: '列出 MCP 服务器',
category: 'tool',
handler: async () => {
const servers = await mcpManager.listServers();
return {
success: true,
output: formatServerList(servers),
};
},
},
{
name: 'mcp.add',
description: '添加 MCP 服务器',
category: 'tool',
args: [
{ name: 'name', type: 'string', required: true },
{ name: 'config', type: 'string', required: true },
],
handler: async (args) => {
await mcpManager.addServer(args.positional[0], args.positional[1]);
return { success: true, output: `Server added: ${args.positional[0]}` };
},
},
{
name: 'mcp.delete',
description: '删除 MCP 服务器',
category: 'tool',
args: [
{ name: 'name', type: 'string', required: true },
],
handler: async (args) => {
await mcpManager.deleteServer(args.positional[0]);
return { success: true, output: `Server deleted: ${args.positional[0]}` };
},
},
];

设计思想:为什么这样设计

思想 1:命令分层

问题: 88+ 命令如何组织?

解决: 命令组 + 子命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
命令组:
├── /mcp
│ ├── list # 列出服务器
│ ├── add # 添加服务器
│ └── delete # 删除服务器
├── /plugins
│ ├── install # 安装插件
│ ├── uninstall # 卸载插件
│ └── list # 列出插件
└── /agents
├── create # 创建 Agent
├── delete # 删除 Agent
└── list # 列出 Agent

设计智慧:

命令组让大量命令有序组织。

思想 2:别名支持

问题: 命令太长难记。

解决: 别名机制。

1
2
3
4
5
6
// 长命令
/mcp list --format table

// 别名
/ml # /mcp list 的别名
/plugins i xxx # /plugins install xxx 的别名

思想 3:智能补全

问题: 记不住命令参数。

解决: 自动补全。

1
2
3
4
5
6
7
# 输入 /mcp 后按 Tab
/mcp list
/mcp add
/mcp delete

# 输入 /mcp add -- 后按 Tab
/mcp add --name <name> --config <config>

思想 4:命令管道

问题: 复杂操作需要组合多个命令。

解决: 管道支持。

1
2
3
# 类似 Unix 管道
/mcp list | grep github
/plugins list --format json | jq '.[].name'

思想 5:错误友好

问题: 命令错误提示不友好。

解决: 详细错误信息。

1
2
3
4
5
6
7
错误:Command not found: mcp-ls

建议:
- 您是不是想找:/mcp list
- 可用命令:/mcp list, /mcp add, /mcp delete

使用 /help mcp 查看更多

解决方案:完整实现详解

CommandTool 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
export class CommandTool extends Tool {
name = 'command';
description = '执行 CLI 命令';

inputSchema = {
type: 'object',
properties: {
input: {
type: 'string',
description: '命令输入',
},
cwd: {
type: 'string',
description: '工作目录',
},
},
required: ['input'],
};

private registry: CommandRegistry;
private executor: CommandExecutor;

constructor() {
super();
this.registry = new CommandRegistry();
this.registerBuiltInCommands();
}

async execute(input: CommandInput, context: ToolContext): Promise<ToolResult> {
this.executor = new CommandExecutor(this.registry, {
user: {
id: context.userId,
name: context.userName,
permissions: context.userPermissions,
},
cwd: input.cwd || context.cwd,
env: context.env,
});

const result = await this.executor.execute(input.input);

return {
success: result.success,
output: result.output,
error: result.error,
exitCode: result.exitCode,
};
}

private registerBuiltInCommands(): void {
// 注册通用命令
this.registry.register(helpCommand);
this.registry.register(configCommand);
this.registry.register(sessionCommand);

// 注册命令组
this.registry.registerGroup('mcp', mcpCommands);
this.registry.registerGroup('plugins', pluginCommands);
this.registry.registerGroup('agents', agentCommands);
this.registry.registerGroup('tasks', taskCommands);
}
}

配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# ~/.openclaw/config/commands.yaml

# 命令别名
aliases:
ml: mcp list
ma: mcp add
md: mcp delete
pi: plugins install
pu: plugins uninstall
pl: plugins list

# 自定义命令
custom_commands:
- name: morning
description: 晨间例行检查
commands:
- /weather
- /calendar
- /news

- name: deploy
description: 部署流程
commands:
- /git pull
- /npm install
- /npm run build
- /docker build
- /docker push

# 命令默认选项
defaults:
mcp.list:
format: table
plugins.list:
format: table
agents.list:
format: table

OpenClaw 最佳实践

实践 1:查看命令帮助

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 查看所有命令
/help

# 查看特定命令
/help mcp

# 输出:
# mcp

管理 MCP 服务器

用法:
/mcp list [--format]
/mcp add <name> <config>
/mcp delete <name>

选项:
--format 输出格式 (table/json)

示例:
/mcp list --format json
/mcp add github {...}

相关命令:
- /plugins
- /tools

实践 2:使用命令别名

1
2
3
4
5
6
7
8
# 完整命令
/mcp list --format table

# 使用别名
/ml -f table

# 自定义别名
/openclaw config set aliases.ml="mcp list"

实践 3:命令管道

1
2
3
4
5
6
7
8
# 过滤输出
/mcp list | grep github

# JSON 处理
/plugins list --format json | jq '.[].name'

# 多命令组合
/git status && /npm test && /docker build

实践 4:自定义命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 创建自定义命令
/openclaw config set custom_commands.morning '[
"/weather",
"/calendar",
"/news"
]'

# 使用自定义命令
/morning

# 输出:
执行晨间例行检查...
- 天气:晴,25°C
- 今日日程:3 个会议
- 新闻摘要:...

实践 5:命令自动补全

1
2
3
4
5
6
7
8
9
10
# 输入 /m 后按 Tab
/mcp
/memory
/model

# 输入 /mcp l 后按 Tab
/mcp list

# 输入 /mcp list -- 后按 Tab
/mcp list --format

总结

核心要点

  1. 命令分层 - 命令组 + 子命令组织
  2. 别名支持 - 简化常用命令
  3. 智能补全 - 提升用户体验
  4. 命令管道 - 支持复杂操作
  5. 错误友好 - 详细错误提示

设计智慧

好的命令系统让操作”精确且高效”。

Claude Code 的命令系统设计告诉我们:

  • 命令组适应大量命令管理
  • 别名提升常用操作效率
  • 智能补全减少记忆负担
  • 管道支持复杂工作流

命令分类

类别 命令数 示例
通用 5 /help, /config, /version
MCP 5 /mcp list, /mcp add
插件 6 /plugins install, /plugins list
Agent 8 /agents create, /agents list
任务 6 /tasks create, /tasks list
会话 5 /session list, /session resume
文件 10 /read, /write, /edit
其他 43

下一步

  • 定义命令 Schema
  • 注册内置命令
  • 配置命令别名
  • 添加自动补全

系列文章:

  • [1] Bash 命令执行的安全艺术 (已发布)
  • [2] 差异编辑的设计艺术 (已发布)
  • [3] 文件搜索的底层原理 (已发布)
  • [4] 多 Agent 协作的架构设计 (已发布)
  • [5] 技能系统的设计哲学 (已发布)
  • [6] MCP 协议集成的完整指南 (已发布)
  • [7] 后台任务管理的完整方案 (已发布)
  • [8] Web 抓取的 SSRF 防护设计 (已发布)
  • [9] 多层权限决策引擎设计 (已发布)
  • [10] 插件生命周期的设计智慧 (已发布)
  • [11] 会话持久化的架构设计 (已发布)
  • [12] 上下文压缩与恢复技术 (已发布)
  • [13] AI 记忆存储与检索机制 (已发布)
  • [14] 配置系统的分层设计 (已发布)
  • [15] 88+ 命令的架构设计 (本文)
  • [16+] 更多高级功能 (继续中…)

进度:15/N

上一篇: Claude Code 源码解析 (14):配置系统的分层设计


关于作者: John,OpenClaw 平台开发者,专注 AI 助手架构设计与实现。