Skip to content

Latest commit

 

History

History
162 lines (123 loc) · 4.04 KB

File metadata and controls

162 lines (123 loc) · 4.04 KB

03 - 启动流程

概述

当用户在终端输入 claude 时,经历以下阶段:

cli.tsx (入口) → init.ts (初始化) → main.tsx (主循环) → React UI 渲染

阶段一:CLI 入口 (entrypoints/cli.tsx)

async function main(): Promise<void> {
  const args = process.argv.slice(2)

  // 快速路径:--version 零模块加载
  if (args[0] === '--version') {
    console.log(`${MACRO.VERSION} (Claude Code)`)
    return
  }

  // 快速路径:Chrome MCP 模式(直接进入 MCP 服务器)
  if (args.includes('--claude-in-chrome-mcp')) { ... }

  // 快速路径:Chrome Native Host(直接进入原生消息循环)
  if (args.includes('--chrome-native-host')) { ... }

  // 其他路径:加载启动分析器
  const { profileCheckpoint } = await import('../utils/startupProfiler.js')
  profileCheckpoint('cli_entry')

  // 各种快速路径检查...
  // 最终进入完整 CLI
}

快速路径设计:对 --version--dump-system-prompt--claude-in-chrome-mcp--chrome-native-host 等简单操作跳过完整初始化,实现零延迟响应。所有 import 都是动态的 (await import()),按需加载。


阶段二:初始化 (entrypoints/init.ts)

init() 函数用 memoize 包装,保证只执行一次:

export const init = memoize(async (): Promise<void> => {
  // 1. 启用配置系统
  enableConfigs()

  // 2. 应用安全环境变量(信任对话前只应用安全的)
  applySafeConfigEnvironmentVariables()

  // 3. 应用额外 CA 证书(必须在首次 TLS 握手前)
  applyExtraCACertsFromConfig()

  // 4. 设置优雅关闭
  setupGracefulShutdown()

  // 5. 初始化 1P 事件日志(异步,不阻塞)
  void Promise.all([...]).then(...)

  // 6. 填充 OAuth 账户信息
  void populateOAuthAccountInfoIfNeeded()

  // 7. JetBrains IDE 检测(异步)
  void initJetBrainsDetection()

  // 8. 检测 Git 仓库
  void detectCurrentRepository()

  // 9. 远程设置加载
  initializeRemoteManagedSettingsLoadingPromise()

  // 10. 配置 mTLS 和代理
  configureGlobalMTLS()
  configureGlobalAgents()

  // 11. 预连接 Anthropic API(TCP+TLS 握手重叠)
  preconnectAnthropicApi()

  // 12. 注册清理回调
  registerCleanup(shutdownLspServerManager)
  registerCleanup(shutdownTeamIfNeeded)   // 清理 Agent 团队资源
})

关键设计决策

  • 安全优先:信任对话之前只应用"安全"的环境变量
  • 异步不阻塞:OAuth、IDE 检测、仓库检测都用 void 异步执行
  • 预连接:在 init 阶段就开始 TCP+TLS 握手,与后续 100ms 工作重叠
  • 延迟加载:OpenTelemetry (~400KB) 等重模块延迟到实际需要时才加载

阶段三:主循环 (main.tsx)

main.tsx 是最大的单文件(803KB),使用 Commander.js 定义 CLI 参数后进入主逻辑:

Commander.js 解析参数
  │
  ├─ 信任对话(首次使用时)
  │
  ├─ 应用完整环境变量
  │
  ├─ 初始化 Tool 列表
  │
  ├─ 加载 MCP 服务器
  │
  ├─ 初始化 QueryEngine
  │
  └─ 渲染 React UI
      │
      ├─ REPL 模式:交互式终端 UI
      ├─ Print 模式:单次查询
      └─ Server 模式:HTTP/stdin 服务

阶段四:React 渲染启动

UI 通过自定义 Ink 渲染器挂载到终端:

React 组件树
  │
  ▼
Ink Reconciler (自定义 React Reconciler)
  │
  ▼
Virtual DOM Nodes
  │
  ▼
Yoga WASM (Flexbox 布局引擎)
  │
  ▼
Cell Grid (字符单元格矩阵)
  │
  ▼
ANSI 转义序列
  │
  ▼
终端显示

启动优化策略总结

策略 实现
快速路径 --version 零 import
动态导入 所有 import 都是 await import()
API 预连接 preconnectAnthropicApi() 重叠握手
异步初始化 OAuth/IDE 检测不阻塞主流程
延迟加载 重模块(OpenTelemetry、React)按需加载
Feature Flags 编译时移除未启用的功能代码
Memoize init() 只执行一次