01.1 启动时序

关注源码

  • src/main.tsx
  • src/entrypoints/init.ts
  • src/interactiveHelpers.tsx
  • src/replLauncher.tsx

启动链路

1. 模块求值阶段先启动预取

main.tsx 在正式进入业务逻辑前就做了三类事:

  • 通过 startupProfiler 标记冷启动阶段。
  • 触发 startMdmRawRead(),把 MDM 配置读取并行化。
  • 触发 startKeychainPrefetch(),把 OAuth/API Key 读取提前。

这说明入口层不是“等 import 完再开始工作”,而是刻意把高延迟 I/O 塞进模块加载窗口,直接优化 CLI 首屏时间。

2. init() 建立安全的启动底座

entrypoints/init.ts 负责在“信任确认之前”完成最小但必要的基础设施:

  • 启用配置系统并解析本地配置。
  • 只应用安全子集环境变量。
  • 提前设置 CA 证书、mTLS、HTTP agent、proxy。
  • 注册 graceful shutdown、LSP manager cleanup、scratchpad 初始化。
  • 异步启动 OAuth 信息补齐、JetBrains 检测、仓库检测、远程 settings/policy loading promise。

这一层的边界很清楚:先让进程变得“可运行、可联网、可清理”,但还不执行需要工作区信任的危险路径。

3. main.tsx 进入会话装配

完成 init() 后,main.tsx 开始真正装配会话:

  • 解析 CLI flags、环境变量、session/source/model/permission mode。
  • 读取 settings、managed settings、policy limits、bootstrap data。
  • 装配 commands、tools、skills、plugins、MCP 配置、agent definitions。
  • 计算初始 AppState 和 REPL/SDK 所需上下文。

这一步不是单一函数调用,而是把多个子系统的配置结果折叠成同一份会话快照。

4. 交互式模式进入 setup + REPL

交互式路径会经过:

  1. interactiveHelpers.showSetupScreens()
  2. replLauncher.launchRepl()
  3. components/App.tsx
  4. screens/REPL.tsx

其中 showSetupScreens() 负责信任边界和首次交互前的对话框,launchRepl() 负责懒加载真正的 App/REPL 组件。

启动阶段的几个关键约束

信任边界先于完整环境变量

interactiveHelpers.tsx 里会先完成 TrustDialog 和相关审批,再调用 applyConfigEnvironmentVariables()。这意味着:

  • 危险环境变量不会在不受信任的工作区中提前生效。
  • 遥测初始化也被放在 trust 之后,以便读取完整环境与远程设置。

初始化尽量 fail-open,但配置错误单独 fail-fast

init.ts 对 upstream proxy、遥测等子系统倾向于“失败记录后继续”,但对配置解析错误则直接走专门错误对话或非交互 stderr 退出。说明它区分:

  • 平台增强能力失败
  • 运行前置条件失败

大模块按需懒加载

入口层广泛使用:

  • feature() 条件编译
  • require() 打断循环依赖
  • import() 延迟加载 UI 或重量级模块

这使同一代码库能承载不同 build 形态,同时压低主路径启动成本。

读代码时建议关注

  • main.tsx 顶部的预取 side-effect。
  • init.ts 里“safe env”和“full env”的分界。
  • showSetupScreens() 里 trust、Grove、API key、dangerous mode 的顺序。
  • launchRepl() 如何让启动逻辑与 REPL UI 解耦。