架构主线 · 01

启动与运行时

从真实启动入口到模型主循环:main.tsx 的总调度、init 的安全与遥测边界、setup 的会话准备、context 的上下文装配、query 的可恢复状态机。

1. 启动入口:src/main.tsx#

src/main.tsx 是启动入口。文件开头特意安排了一组必须最先执行的 side effect:

这些操作说明启动路径已经被认真优化:慢 I/O 被尽量提前、并行化,并从真正渲染路径里挪走。

main.tsx 后面承担的是“总调度器”职责,而不是单纯渲染 UI。它要处理:

argv 先分流再动态 import:daemon、bg-spare、bridge、Chrome/Computer Use MCP 这些路径不进默认图。

2. 早期初始化:src/entrypoints/init.ts#

init() 是 memoized 的全局一次性初始化。它的核心顺序是:

  1. enableConfigs():启用配置系统。
  2. applySafeConfigEnvironmentVariables():trust 之前只应用安全环境变量。
  3. assertScrubSandboxAvailable()
  4. applyExtraCACertsFromConfig():在首次 TLS 前注入额外 CA,因为 Bun/BoringSSL 会缓存证书状态。
  5. setupGracefulShutdown():安装退出清理。
  6. 动态导入 1P event logging 和 GrowthBook,避免启动时同步吞下 OpenTelemetry 依赖。
  7. populateOAuthAccountInfoIfNeeded()、JetBrains detection、repository detection。
  8. 初始化 remote managed settings / policy limits 的加载 promise,避免后续系统等待时死锁。
  9. configureGlobalMTLS()configureGlobalAgents():mTLS 与 proxy 全局配置。
  10. preconnectAnthropicApi():在合适条件下预连 Anthropic API。
  11. remote 环境下可初始化 agent proxy。
  12. Windows:既没 Git Bash、PowerShell 工具又关着,直接退出;需要 Git for Windows 或 PowerShell 7(或设 CLAUDE_CODE_GIT_BASH_PATH)。
  13. LSP cleanup、team cleanup、scratchpad 目录。

这个文件有一个很清楚的安全边界:trust 之前只做“安全配置”,trust 之后再调用 initializeTelemetryAfterTrust()。对 remote-settings-eligible 用户,它会等待远程设置加载并重新应用环境变量,再初始化遥测。也就是说,trust dialog 在这里是真正的运行时门槛,不只是 UI 提示。

3. 会话准备:src/setup.ts#

setup() 把“进程已经启动”变成“当前会话可运行”。它做的事比名字重很多:

这里有两个细节很有代表性:

  1. hook snapshot 必须在 setCwd() 之后,因为 hooks 来自当前项目目录;worktree 切换后还要重新 snapshot。
  2. --bare 跳过 UDS、部分后台任务和 prefetch,但危险权限校验和 tengu_started 仍会执行。

4. 上下文装配:src/context.ts#

context.ts 负责把会话环境变成模型可消费的上下文,主要有两块。

system context

getSystemContext() 会按需加入 git 快照:当前分支、main/default、git status --short(最多 2000 字符)、git log --oneline -n 5git config user.name。remote 或关掉 git instructions 时跳过。CLAUDE_CODE_PERFORCE_MODE 会改成 Perforce 工作区说明。

user context

getUserContext() 主要负责 CLAUDE.md

5. 交互 UI 启动路径#

交互模式大致是:

main.tsx
  → interactiveHelpers.tsx
  → replLauncher.tsx
  → components/App.tsx
  → REPL

interactiveHelpers.tsx 维护进入 UI 前的“仪式”:trust dialog、setup screens、MCP approval、外部 CLAUDE.md include 审批、环境变量应用、telemetry-after-trust、GrowthBook 重置等。

replLauncher.tsx 职责更纯:动态导入 <App><REPL>,再用 renderAndRun() 挂载。动态导入可以避免 main.tsx 过早拉入 React/Ink 组件树。

dialogLaunchers.tsx 则把 resume chooser、snapshot update、teleport mismatch、invalid settings 等一次性 UI 从主入口拆出去,让 main.tsx 不至于更膨胀。

6. Headless / SDK 路径:src/QueryEngine.ts#

交互 REPL 会走 React 组件和 hooks;--print、SDK、remote session 子进程等非交互场景则主要依赖 QueryEngine

QueryEngine 是对 query() 的会话化包装:

可以把 QueryEngine 理解为“非交互模式的 REPL store + query loop adapter”。

7. 主查询循环:src/query.ts#

query.ts 是整个系统的运行时核心。它不是“发一次请求”,而是一个可恢复、可压缩、可执行工具、可继续多轮的状态机。

每次循环大致做这些事:

  1. 建立 query chain tracking,用于嵌套查询/子代理的 analytics。
  2. 截取 compact boundary 之后的消息。
  3. 对 tool results 应用总预算,必要时把大结果替换为持久化文件引用。
  4. 可选 microcompact;中间轮可 fold 排队命令。history snip / context collapse drain 在 2.1.233 字面量里看不到,不当默认步骤。
  5. 自动 compact:可先吃预计算的 compact(tengu_sepia_moth + precomputeCompactionEnabled),再跑阈值 compact。窗口解析见 压缩专题
  6. 拼接完整 system prompt 与 user context。
  7. 计算当前模型;plan 模式下可根据 200k token 情况切模型。
  8. 调用 deps.callModel() 流式请求模型。
  9. 流式过程中发现 tool_use 时,可用 StreamingToolExecutor 提前开始执行工具。
  10. 对可恢复错误做 withheld:prompt-too-long、media-size、max-output-tokens 等先不立刻暴露给 SDK/UI。
  11. 流结束后处理 fallback、reactive compact、max output tokens recovery。
  12. 若没有 tool_use,执行 stop hooks、token budget continuation、返回完成。
  13. 若有 tool_use,执行剩余工具,收集 tool results、attachments、memory prefetch、skill discovery、queued commands。
  14. 刷新工具集合,使新连接的 MCP server 可在下一轮暴露给模型。
  15. 检查 maxTurns,否则组装下一轮 messages 继续循环。

query.ts 里几个重要恢复策略:

8. 工具执行在 query 中的位置#

query.ts 自身不直接执行工具细节,而是委托:

这层拆分使主循环可以专注“轮次状态机”,而工具层专注“执行一个 tool use 是否安全、如何展示、如何转换结果”。

9. API 客户端:src/services/api/client.ts#

API client 把不同模型提供方统一到 Anthropic SDK 风格接口下。可以直接看到几条分支:

它还统一加默认 headers:x-app、User-Agent、session id、container/session metadata、SDK client app 等。对 first-party API,会通过 fetch wrapper 注入 x-client-request-id,方便 timeout 这类无 server request id 的问题排查。

10. 这一层的阅读建议#

如果目标是理解“一次输入后发生什么”,推荐顺序:

  1. main.tsx:看模式分流和启动顺序。
  2. entrypoints/init.ts:看全局安全与遥测边界。
  3. setup.ts:看会话准备、hooks、worktree、permission 安全校验。
  4. context.ts:看系统上下文和用户上下文来源。
  5. QueryEngine.ts:看 headless/SDK 怎么包 query()
  6. query.ts:看模型循环、compact、工具执行和恢复策略。
  7. services/api/client.ts:看 provider 和认证分支。