Skip to content

启动流程详解

Claude Code 的启动过程涉及 3 个关键文件和多个初始化步骤,从 CLI 解析到 REPL 界面完全就绪。

启动链概览

用户执行 `claude` 命令

entrypoints/cli.tsx  (~303 行)
  ├── main()  — 命令行路由入口
  │     ├── args 路由判断 (16+ 个 feature-gated 快速路径)
  │     ├── 特殊模式检测: --version, --mcp, -p, server, bridge, daemon 等
  │     └── 动态 import 目标模块

main.tsx  (~4684 行)
  ├── Commander.js 选项解析 (~50 个选项)
  ├── CURRENT_MIGRATION_VERSION = 11 — 运行迁移
  ├── runMigrations() — 9 个同步 + 2 个条件 + 1 个异步迁移
  └── 启动 REPL 或执行一次性查询

entrypoints/init.ts  (~309 行)
  ├── enableConfigs() — 验证并启用配置系统
  ├── applySafeConfigEnvironmentVariables() + applyExtraCACertsFromConfig()
  ├── setupGracefulShutdown() — 注册清理钩子
  ├── 初始化 1P 事件日志 + GrowthBook
  ├── populateOAuthAccountInfoIfNeeded()
  ├── initJetBrainsDetection()
  ├── detectCurrentRepository()
  ├── initializeRemoteManagedSettingsLoadingPromise()
  ├── configureGlobalMTLS() + configureGlobalAgents()
  ├── preconnectAnthropicApi()
  └── (延迟) initTelemetryAfterTrust → OTEL 加载 (~400KB)

screens/REPL.tsx — 交互式循环
  ├── App.tsx → Provider 组合
  ├── StatusLine → 状态栏
  ├── PromptInput → 用户输入
  └── 等待用户交互...

第一站:cli.tsx — 命令行路由

entrypoints/cli.tsx 是整个应用的入口点,main() 函数实现了一个巨型路由器,所有依赖都使用动态 import() 以最小化模块加载。

关键路由表

条件目标说明
--version / -v / -V直接输出版本零模块加载快速路径
--dump-system-prompt导出系统提示词feature gate DUMP_SYSTEM_PROMPT
--claude-in-chrome-mcpChrome MCPChrome MCP 服务器
--computer-use-mcpComputer Use MCPfeature gate CHICAGO_MCP
--daemon-worker (DAEMON)Daemon Worker内部 worker 进程
remote-control/rc/remote/sync/bridge (BRIDGE_MODE)Bridge 模块claude.ai 桥接
daemon (DAEMON)守护进程 Supervisor后台运行
ps/logs/attach/kill/--bg (BG_SESSIONS)会话管理后台会话管理
new/list/reply (TEMPLATES)模板系统模板创建/列表/回复
environment-runner (BYOC_ENVIRONMENT_RUNNER)环境运行器BYOC 环境
self-hosted-runner (SELF_HOSTED_RUNNER)自托管运行器自托管模式
--tmux + --worktreetmux worktreetmux worktree 快速路径
--update/--upgrade更新子命令重定向到 update
默认main.tsxcliMain()交互式终端界面

第二站:main.tsx — Commander.js 配置

main.tsx (~4684 行) 是最核心的启动文件,使用 Commander.js 定义 ~50 个 CLI 选项:

关键选项

typescript
program
  .option('-p, --pipe', '管道模式(一次性查询)')
  .option('--model <model>', '模型选择')
  .option('--max-turns <n>', 'Agent 最大轮次')
  .option('--permission-mode <mode>', '权限模式')
  .option('--allowedTools <tools...>', '允许的工具')
  .option('--resume <session>', '恢复会话')
  .option('--add-dir <dir>', '添加工作目录')
  .option('--output-format <fmt>', '输出格式 (text|json|stream-json)')
  .option('--verbose', '详细日志')
  .option('--dangerously-skip-permissions', '跳过权限(危险)')
  // ...更多选项

迁移系统

typescript
// src/main.tsx L325
const CURRENT_MIGRATION_VERSION = 11

// runMigrations() 中的实际迁移(按执行顺序):
// 同步迁移:
//   migrateAutoUpdatesToSettings()
//   migrateBypassPermissionsAcceptedToSettings()
//   migrateEnableAllProjectMcpServersToSettings()
//   resetProToOpusDefault()
//   migrateSonnet1mToSonnet45()
//   migrateLegacyOpusToCurrent()
//   migrateSonnet45ToSonnet46()
//   migrateOpusToOpus1m()
//   migrateReplBridgeEnabledToRemoteControlAtStartup()
// 条件迁移:
//   resetAutoModeOptInForDefaultOffer()  — 仅 feature('TRANSCRIPT_CLASSIFIER') 时
//   migrateFennecToOpus()                — 仅内部构建 (ant) 时
// 异步迁移 (fire-and-forget):
//   migrateChangelogFromConfig()

第三站:init.ts — 多步骤初始化

entrypoints/init.ts 导出一个被 memoize 包裹的 init() 异步函数,确保只执行一次。

注意: 与文档旧版不同,init 并非简单的 5 个命名阶段,而是一系列顺序步骤,通过 profileCheckpoint 标记进度。

初始化步骤(按实际执行顺序)

typescript
async function init() {
  // 1. enableConfigs() — 验证并启用配置系统
  // 2. applySafeConfigEnvironmentVariables() + applyExtraCACertsFromConfig()
  // 3. setupGracefulShutdown() — 注册 SIGINT/SIGTERM/exit 清理
  // 4. 异步初始化 1P 事件日志 + GrowthBook 特性门控
  // 5. populateOAuthAccountInfoIfNeeded() — OAuth 账户信息
  // 6. initJetBrainsDetection() — JetBrains IDE 检测
  // 7. detectCurrentRepository() — 当前仓库检测
  // 8. initializeRemoteManagedSettingsLoadingPromise() — 远程托管设置
  //    + initializePolicyLimitsLoadingPromise() — 策略限制
  // 9. recordFirstStartTime() — 记录首次启动时间
  // 10. configureGlobalMTLS() — mTLS 客户端证书
  // 11. configureGlobalAgents() — 代理配置
  // 12. preconnectAnthropicApi() — API 预连接
  // 13. initUpstreamProxy() — 仅 CLAUDE_CODE_REMOTE 时
  // 14. setShellIfWindows() — Windows Shell 设置
  // 15. registerCleanup(shutdownLspServerManager) — LSP 清理
  //     + registerCleanup(cleanupSessionTeams) — 会话团队清理
  // 16. ensureScratchpadDir() — 仅 scratchpad 启用时
}

延迟初始化: initTelemetryAfterTrust

typescript
async function initializeTelemetryAfterTrust() {
  // 仅在用户接受信任对话框后执行
  // 延迟加载 OpenTelemetry (~400KB OTEL SDK)
  // 初始化 2 个 sink:
  //   - Datadog (允许事件白名单)
  //   - 1P (BatchLogRecordProcessor)
  // 配置采样率(按事件名称)
  // 配置 GrowthBook killswitch
}

第四站:REPL.tsx — 交互式界面

screens/REPL.tsx 是主界面组件,负责将所有系统组合成用户可交互的终端 UI:

组件树

<REPL>
  <App>
    <FpsMetricsProvider>
      <StatsProvider>
        <AppStateProvider initialState={...}>
          <FullscreenLayout>
            <ScrollBox>
              <LogoHeader />
              <VirtualMessageList messages={...} />
            </ScrollBox>
            <StatusLine />
            <PromptInput />
          </FullscreenLayout>
        </AppStateProvider>
      </StatsProvider>
    </FpsMetricsProvider>
  </App>
</REPL>

REPL Props

typescript
// 实际类型名为 Props(非 REPLProps)
export type Props = {
  commands: Command[]
  initialTools: Tool[]
  mcpClients?: MCPServerConnection[]  // 可选,类型为 MCPServerConnection[]
  remoteSessionConfig?: RemoteSessionConfig
  systemPrompt?: string
  initialMessages?: Message[]
  debug?: boolean
  thinkingConfig: ThinkingConfig      // 必选
  pendingHookMessages?: Message[]
  // ... 还有 initialContentReplacements, dynamicMcpConfig,
  //     strictMcpConfig, sshSession, directConnectConfig, taskListId 等
}

初始化时序图

t=0ms    cli.tsx main() 开始
t=5ms    ├── args 路由判断
t=10ms   ├── dynamic import main.tsx
t=20ms   main.tsx 开始
t=25ms   ├── Commander.js 解析选项
t=30ms   ├── runMigrations() (11 个迁移)
t=50ms   ├── init() 开始 (5 阶段)
t=55ms   │   ├── enableConfigs()
t=80ms   │   ├── applySafeConfigEnvironmentVariables()
t=120ms  │   ├── setupGracefulShutdown()
t=150ms  │   ├── initializeRemoteManagedSettingsLoadingPromise()
t=200ms  │   └── preconnectAnthropicApi()
t=220ms  REPL.tsx 挂载
t=250ms  ├── AppState 初始化 (80+ 字段)
t=280ms  ├── 工具池构建 (assembleToolPool)
t=300ms  ├── Ink 渲染引擎启动
t=350ms  ├── 首帧渲染
t=400ms  └── 等待用户输入
         -------- 延迟初始化 --------
t=500ms  initTelemetryAfterTrust (如信任已建立)
t=600ms  MCP 服务器连接 (并行)
t=800ms  GrowthBook 配置刷新

启动优化技术

  1. 延迟 import: 除入口外的模块全部 await import() 按需加载
  2. 记忆化初始化: init.ts 中每个阶段只执行一次(memoize
  3. 并行加载: MCP 客户端连接并行启动
  4. 延迟遥测: OTEL ~400KB 在信任建立后才加载
  5. 渐进渲染: 首帧先显示 Logo + 输入框,数据后续填充