ARTICLE · 1351417
Claude Code 源码解析:初始化流程与 REPL 启动
你好,我是江小湖。
前两篇讲了入口分发和启动优化。这一篇讲最后一个阶段:模块加载完成后,main.tsx 如何初始化各种系统,最终渲染出 REPL 界面。

Claude Code 源码解析系列配图

Claude Code 源码解析 02-startup-flow 配图
main.tsx 用 Commander 定义了 50 多个命令行选项:
// main.tsx(简化)constprogram=newCommanderCommand() .name('claude') .description('Claude Code - starts an interactive session') .option('-p, --print', 'Print response and exit') .option('--model <model>', 'Model for the current session') .option('--permission-mode <mode>', 'Permission mode') .option('--bare', 'Run in bare mode')// ... 50+ 个选项 .action(async (prompt, options) => {// 启动逻辑 });
这些选项覆盖运行模式、模型选择、权限模式、输出控制等。参数解析完成后,进入 action handler,这是真正开始初始化的位置。
action handler 首先调用 init(),这是一个被 memoize 包装过的初始化函数:
// entrypoints/init.ts(简化)exportconstinit=memoize(async (): Promise<void> => {enableConfigs();applySafeConfigEnvironmentVariables();applyExtraCACertsFromConfig();configureGlobalMTLS();configureGlobalAgents();preconnectAnthropicApi();setShellIfWindows();});
memoize 确保 init() 在整个进程生命周期内只执行一次。即使多个子系统调用它,也不会重复初始化。
初始化链的顺序很重要:
在初始化完成后,main.tsx 会检查用户是否已经接受过信任对话:
if (!checkHasTrustDialogAccepted()) {awaitshowTrustDialog();}initializeTelemetryAfterTrust();
信任对话是一个用户授权步骤,告知用户 Claude Code 会访问文件系统和网络。只有在用户同意后,遥测系统才会初始化。这个顺序是合规设计:不获取未授权的数据。
全局状态 bootstrap/state.ts 中有一组 Sticky-on Latch 字段,专门用来保护提示缓存:
// bootstrap/state.ts(简化)typeState= {afkModeHeaderLatched:boolean|null; // auto mode beta headerfastModeHeaderLatched:boolean|null; // fast mode beta headercacheEditingHeaderLatched:boolean|null; // cached microcompact headerthinkingClearLatched:boolean|null; // thinking clear header};
这些字段初始为 null,一旦启用就保持为 true。即使用户中途按 Shift+Tab 切换 auto mode,header 仍然保持发送。
为什么这样做?
Claude Code 的系统提示词有约 50-70K token,缓存在服务器端。如果请求中的 header 变化,缓存就会失效,下次请求需要重新计算,输入成本增加约 12 倍。Sticky-on Latch 通过"一旦开启就保持"的策略,避免缓存失效。
最后一步是 launchRepl():
awaitlaunchRepl(prompt, options);startDeferredPrefetches();
launchRepl() 负责:
startDeferredPrefetches() 在 REPL 渲染后启动,利用用户思考的时间完成非关键预取。
main.tsx 用 Commander 解析 50 多个命令行选项。init.ts 按严格顺序初始化配置、证书、代理和 API 连接。launchRepl() 最终渲染 REPL 界面,把控制权交给用户。下一章进入 Agent 循环,看 Claude Code 最核心的 88 行 while 循环是怎么运行的。
以上就是本文的全部内容。如果觉得有收获,欢迎点赞、在看、转发,这是对 江小湖 最大的鼓励。
如有疑问或建议,欢迎在评论区留言交流。
📖 近期文章
•Claude Code 的代码为什么好读?拆成五层看:入口、循环、工具、权限、提示词各管各的
•扒完 Claude Code 51 万行源码:AI 决策逻辑只占 1.6%,剩下 98% 才是 Agent 的真壁垒
•系统上线就万事大吉?Agent 运维实战:日常巡检、故障响应、灾难恢复一篇讲透
•代码写好了,怎么稳稳上生产?Docker、K8s、CI/CD 部署全流程:多环境 + 发布策略一篇讲透
•Agent 搭好了,用户怎么用?REST/SSE/WebSocket 三种 API 设计:认证、限流、SDK 一篇讲透















































































