Skip to content

CLI 命令解析

Commander.js 程序结构

Source: src/main.tsx:884-4512

Claude Code 使用 Commander.js 构建 CLI,核心在 run() 函数中定义。

typescript
// Source: src/main.tsx:887-890
const program = new CommanderCommand()
  .configureHelp(createSortedHelpConfig())
  .enablePositionalOptions();

根命令

根命令 claude 接受一个可选的位置参数 [prompt]

typescript
// Source: src/main.tsx:968-1007
program
  .name('claude')
  .description('Claude Code - starts an interactive session...')
  .argument('[prompt]', 'Your prompt', String)

主要选项

选项说明
-p, --printHeadless 模式:输出结果后退出
-d, --debug [filter]启用调试模式,可按分类过滤
-c, --continue恢复最近的对话
-r, --resume [id]通过会话 ID 恢复
--model <model>覆盖默认模型
--permission-mode <mode>权限模式覆盖
--system-prompt <prompt>覆盖系统提示词
--bare最小模式:跳过 hooks、LSP、插件
--verbose详细输出模式

高级选项

选项说明
--mcp-config <configs...>MCP 服务器配置(可多个)
--tools <tools...>工具白名单
--plugin-dir <path>插件目录(可重复)
--settings <file-or-json>设置文件或 JSON
--max-turns <n>最大对话轮数
--max-budget-usd <n>最大预算(美元)
--sdk-url <url>SDK 模式 URL
--prefill <text>预填充输入
--worktree在 git worktree 中运行
--tmux在 tmux 会话中运行(需配合 --worktree)

模式选择

核心决策点

Source: src/main.tsx:797-815, 2523-2860

Headless 模式路径

typescript
// Source: src/main.tsx:2523-2860
if (getIsNonInteractiveSession()) {
  const { runHeadless } = await import('src/cli/print.js');
  void runHeadless(inputPrompt, getState, setState, commands, tools, {
    continue: options.continue,
    resume: options.resume,
    verbose,
    outputFormat,
    maxTurns: options.maxTurns,
    maxBudgetUsd: options.maxBudgetUsd,
    systemPrompt,
    userSpecifiedModel: effectiveModel,
    // ... 更多选项
  });
  return;
}

交互模式路径

typescript
// Source: src/main.tsx:2862-3800+
const initialState: AppState = { /* ... */ };
const store = createStore(initialState);
await showSetupScreens(/* ... */);
await launchRepl(root, { /* options */ });

并行初始化

Action handler 中使用了大量并行执行来减少启动时间:

typescript
// Source: src/main.tsx:1903-1935
const [setupResult, commands, agentDefs] = await Promise.all([
  setup(),                              // UI 设置屏幕
  getCommands(),                        // 加载命令注册表
  getAgentDefinitionsWithOverrides()    // 加载 Agent 定义
]);

MCP 配置也与 setup 并行加载:

typescript
// MCP 配置加载(与 setup 并行)
const mcpConfigsPromise = getClaudeCodeMcpConfigs(dynamicMcpConfig);
// ... 同时运行 setup()
const mcpConfigs = await mcpConfigsPromise;

早期参数处理

在 Commander.js 解析之前,main() 函数还处理了一些需要早期拦截的参数:

深度链接 URI

typescript
// Source: src/main.tsx:609-677 (受 LODESTONE 特性标志门控)
// 解析 cc:// 和 cc+unix:// URL
// 重写为内部 'open' 子命令

SSH 远程模式

typescript
// Source: src/main.tsx:706-795 (受 SSH_REMOTE 特性标志门控)
// 解析 'claude ssh <host> [dir]'
// 提取权限标志,转发到远程 CLI

助手模式

typescript
// Source: src/main.tsx:685-700 (受 KAIROS 特性标志门控)
// 检测 'claude assistant [sessionId]'
// 暂存到 _pendingAssistantChat

注意

以上三个早期参数处理都受特性标志门控,在反编译版本中不会执行。

信号处理

typescript
// Source: src/main.tsx:593-606
// 退出处理器
process.on('exit', () => { /* cleanup */ });

// SIGINT 处理
process.on('SIGINT', () => {
  if (isPrintMode) {
    // -p 模式:直接退出
    process.exit(0);
  }
  // 交互模式:交给 REPL 处理
});

调试模式

通过 -d--debug 启用调试日志:

bash
# 全部调试日志
claude -d

# 按分类过滤
claude -d "api,tools"

# 输出到 stderr
claude --debug-to-stderr

# 输出到文件
claude --debug-file /tmp/claude-debug.log

下一步