启动流程

这一页把启动相关模块串成真正的动态时序。你会先看到总流程,再逐层看启动入口、初始化、共享状态和 REPL 是如何接力工作的。

适合刚接触仓库、想先搞清程序如何被拉起的人。

先看启动总览和主线,再进入各模块透视,不要一上来就钻细节。

理解哪些模块是主干,哪些模块只是按条件接入的能力。

启动总览

从运行时视角看,Claude Code 的启动并不是“加载完模块再开始跑”,而是把预热、初始化、全局状态注入、模式选择和交互入口编排成一条尽量短的关键路径。也正因为如此,启动流程既包含明确的主干模块,也包含很多按环境和 feature gate 条件接入的能力。

启动主线

  1. 进程进入 src/main.tsx
  2. 顶层 side effect 先触发关键预热
  3. 加载核心依赖与 feature flag
  4. 进入 src/entrypoints/init.ts 完成环境准备
  5. 组装命令、工具、插件、技能和状态容器
  6. 根据运行模式进入 REPL、非交互执行、bridge 或远程路径

为什么会有很多前置预热

从源码可以看到,启动期有明显的性能优化设计,例如:
  • MDM 配置读取提前并行启动
  • Keychain 读取提前预取
  • 某些远程配置与网络能力在早期就发起准备
这些动作的目标不是“立刻使用”,而是尽可能把 I/O 等待与模块加载重叠。

主干模块与条件接入模块

启动阶段并不是所有出现过的模块都会无条件参与。更准确的理解方式是把它分成两类:

src/main.tsxsrc/entrypoints/init.tssrc/bootstrap/state.tssrc/replLauncher.tsx

bridge、remote、assistant、部分 analytics、部分 coordinator 能力,以及通过 feature() 或环境变量控制的延迟加载模块。

这种分层的意义在于:主干模块保证“任何一次 CLI 会话都能被正确拉起”,条件接入模块则保证“在对应能力启用时,额外能力能无缝接入,而不会拖慢所有启动路径”。

关键节点

运行时入口模块透视

模块定位

src/main.tsx 是启动编排器,不是所有业务逻辑的最终归宿。它的核心价值是把启动次序排好:哪些东西必须先准备,哪些东西可以延后,哪些能力应该按条件加载。

关键文件

上游 / 下游

  • 上游:进程入口、CLI 参数、环境变量
  • 下游:初始化模块、命令系统、工具系统、状态系统、REPL 与其它运行模式

运行时行为

  • 在文件最顶部触发 side effect 预热,例如 MDM 读取与 Keychain 预取
  • 汇总命令、工具、插件、技能、模型、权限等启动期依赖
  • 根据参数和环境决定进入交互式、非交互式、bridge 或远程路径

常见误区

最容易误解的是把 main.tsx 看成“所有业务都在里面”。实际上它更像总调度台,真正的执行主循环和具体能力大多在后续模块中。

建议阅读顺序

  1. 顶层 side effect 和 import 区
  2. 命令 / 工具注入相关逻辑
  3. 模式选择与交互入口逻辑

初始化模块透视

模块定位

src/entrypoints/init.ts 负责把运行环境变成“可以安全发请求、可以读配置、可以正确回收资源”的状态。它更像底层准备层,而不是用户直接触达的功能层。

关键文件

上游 / 下游

  • 上游:main.tsx 发起的初始化调用
  • 下游:网络代理、遥测、LSP 管理器、清理器、远程配置、scratchpad 等基础设施

运行时行为

  • 启用配置系统并应用安全环境变量
  • 配置 CA、mTLS、代理、预连接和遥测
  • 注册优雅退出清理逻辑
  • 按条件初始化远程配置、政策限制、JetBrains 检测、仓库识别等背景任务

常见误区

它看起来杂,是因为初始化天然就是横切逻辑的汇合点;但它并不应该承载后续交互期的业务判断。

建议阅读顺序

  1. enableConfigs 与安全环境变量应用
  2. 网络和遥测初始化
  3. 清理器与后台预热逻辑

启动状态模块透视

模块定位

src/bootstrap/state.ts 是启动期和会话级共享状态的容器。它负责记住“这次会话是谁、从哪里来、当前运行在什么模式下”,让后续模块都能读取同一份运行期事实。

关键文件

上游 / 下游

  • 上游:main.tsx 和初始化逻辑设置的启动参数
  • 下游:QueryEngine、命令层、工具层、UI、远程与 bridge 能力

运行时行为

  • 保存 cwd、projectRoot、sessionId、模型设置、交互模式、远程模式等会话级状态
  • 为 token budget、telemetry、tool result pairing、plan mode 等运行时能力提供共享读写点
  • 充当大量“会话范围开关”的事实来源

常见误区

它不是 React 的 UI store,而是会话级运行时状态容器;和 AppStateStore.ts 互补,但职责不同。

建议阅读顺序

  1. 顶层 State 类型
  2. 关键 getter / setter
  3. 与 token、model、mode 相关的状态字段

REPL 与运行模式模块透视

模块定位

src/replLauncher.tsx 及其相邻入口负责把“已启动完毕的 CLI”真正变成“可交互的 CLI”。到这一步,前面的准备才开始向用户可见体验转化。

关键文件

上游 / 下游

  • 上游:main.tsx 的模式选择结果、初始化完成后的共享状态
  • 下游:REPL、Ink UI、输入处理链、QueryEngine

运行时行为

  • 建立交互式输入循环
  • 接上终端渲染与应用状态
  • 把前面准备好的命令、工具、权限上下文、模型配置带入实际会话

常见误区

很多人会把 REPL 看成“只是一个输入框”,但它其实是启动阶段到交互阶段的桥梁,承担了状态接线和事件流接入的职责。

建议阅读顺序

  1. replLauncher.tsx
  2. interactiveHelpers.tsx
  3. 再回头看 AppStateStore.ts

为什么 side effect、预热和 lazy import 会并存

这三种看起来互相冲突,实际上是在服务同一个目标:把冷启动路径压短。
  • 顶层 side effect 负责最早发起必须尽快开始的 I/O
  • 初始化模块负责把“必须成功的基础环境”准备完整
  • lazy import 负责把重模块推迟到真正需要时再加载
因此,启动流程并不是“越纯越好”,而是“越能缩短关键路径越好”。这也是 Claude Code 这种高交互、重集成 CLI 常见的工程取舍。

读完这一页之后建议去哪里