Code Reader
首页
帮助
设计文档
首页
帮助
设计文档
  • Claude Code 核心架构分析

Claude Code 核心架构分析

基于源码快照分析,位于 /home/sujie/dev/github/claude-code-source-snap/claude-code/src/ 约 1900 个文件,512K LOC,使用 Bun 运行时 + React/Ink 终端 UI


1. 架构总览

1.1 分层架构

Claude Code 采用经典的分层架构,但层与层之间的边界通过 feature flag(编译时死代码消除)和 动态 import(运行时延迟加载)来管理,而非严格的模块隔离。

┌──────────────────────────────────────────────────────────────────┐
│                        入口层 (Entry Points)                      │
│  src/entrypoints/cli.tsx  ──>  src/main.tsx  ──>  src/setup.ts   │
├──────────────────────────────────────────────────────────────────┤
│                    表现层 (Presentation Layer)                     │
│  src/components/ (144 个组件)    src/screens/ (REPL, Doctor)      │
│  src/ink/ (Ink 渲染引擎)         src/hooks/ (85 个 hooks)         │
│  src/context/ (React Context)    src/keybindings/                 │
├──────────────────────────────────────────────────────────────────┤
│                    业务逻辑层 (Business Logic)                     │
│  src/QueryEngine.ts    src/query.ts    src/query/                 │
│  src/commands.ts + src/commands/ (101 个命令)                     │
│  src/tools.ts + src/tools/ (43 个工具)                            │
│  src/services/ (36 个服务模块)                                    │
│  src/skills/ + src/plugins/ (技能与插件系统)                      │
├──────────────────────────────────────────────────────────────────┤
│                    状态与数据层 (State & Data)                     │
│  src/state/ (AppStateStore, Store)   src/bootstrap/state.ts       │
│  src/cost-tracker.ts    src/history.ts    src/tasks.ts            │
├──────────────────────────────────────────────────────────────────┤
│                    基础设施层 (Infrastructure)                     │
│  src/utils/ (329 个工具模块)     src/constants/ (21 个常量)       │
│  src/types/ (类型定义)           src/schemas/ (Schema)            │
│  src/migrations/ (数据迁移)      src/native-ts/                   │
├──────────────────────────────────────────────────────────────────┤
│                    远程与桥接层 (Remote & Bridge)                  │
│  src/bridge/ (31 个文件)    src/remote/    src/server/            │
│  src/coordinator/    src/upstreamproxy/                           │
└──────────────────────────────────────────────────────────────────┘

1.2 顶层模块清单

目录/文件职责文件数
main.tsxCLI 入口、Commander.js 配置、React root 渲染、会话启动流程1 (4684 行)
commands.ts + commands/斜杠命令注册与实现~102
tools.ts + tools/AI 工具定义(Bash、Edit、Read 等)~44
components/React/Ink 终端 UI 组件144
screens/顶层屏幕组件 (REPL, Doctor, ResumeConversation)3
hooks/React 自定义 hooks85
services/后端服务抽象 (API, MCP, Analytics, Policy 等)36
utils/通用工具函数329
ink/Ink 渲染引擎(React 到终端的桥接)48
state/全局状态管理 (AppStateStore, Store)6
bootstrap/启动时全局状态初始化1 (state.ts, 1758 行)
context/React Context providers9
bridge/Remote Control / Bridge 功能31
skills/技能系统4
plugins/插件系统2
constants/常量定义 (API limits, prompts, tools 等)21
types/TypeScript 类型定义8
migrations/配置数据迁移脚本~10
entrypoints/多入口点(CLI, init, MCP, SDK types)5

2. 入口点与初始化流程

2.1 启动序列

进程启动
  │
  ▼
src/entrypoints/cli.tsx ──────────────────────────────────┐
  │                                                        │
  ├─ ① 快速路径: --version (零模块加载)                    │
  ├─ ② 快速路径: --dump-system-prompt                     │
  ├─ ③ 快速路径: --claude-in-chrome-mcp                   │
  ├─ ④ 快速路径: --daemon-worker                          │
  ├─ ⑤ 快速路径: remote-control / bridge                  │
  ├─ ⑥ 快速路径: daemon                                   │
  ├─ ⑦ 快速路径: bg sessions (ps/logs/attach/kill)        │
  ├─ ⑧ 快速路径: templates (new/list/reply)               │
  ├─ ⑨ 快速路径: environment-runner / self-hosted-runner  │
  │                                                        │
  └─ ⑩ 标准路径: 动态 import('../main.js')                 │
       │                                                   │
       ▼                                                   │
  src/main.tsx ────────────────────────────────────┐       │
    │                                              │       │
    ├─ profileCheckpoint('main_tsx_entry')         │       │
    ├─ startMdmRawRead()  ← 并行启动 MDM 读取      │       │
    ├─ startKeychainPrefetch() ← 并行启动钥匙串预取│       │
    ├─ [~135ms 的模块导入评估]                      │       │
    │                                              │       │
    ├─ main() 函数入口                              │       │
    │  ├─ initializeWarningHandler()               │       │
    │  ├─ 处理 cc:// URL, ssh, assistant 等特殊参数 │       │
    │  ├─ eagerLoadSettings() ← 早期解析 --settings │       │
    │  └─ run()                                    │       │
    │     │                                        │       │
    │     ├─ new CommanderCommand()                │       │
    │     ├─ program.hook('preAction', ...)        │       │
    │     │  ├─ ensureMdmSettingsLoaded()          │       │
    │     │  ├─ ensureKeychainPrefetchCompleted()  │       │
    │     │  ├─ init()  ← src/entrypoints/init.ts  │       │
    │     │  │  ├─ enableConfigs()                 │       │
    │     │  │  ├─ applySafeConfigEnvVars()        │       │
    │     │  │  ├─ setupGracefulShutdown()         │       │
    │     │  │  ├─ initialize1PEventLogging()      │       │
    │     │  │  ├─ configureGlobalMTLS()           │       │
    │     │  │  ├─ configureGlobalAgents() (proxy) │       │
    │     │  │  └─ preconnectAnthropicApi()        │       │
    │     │  ├─ initSinks()                        │       │
    │     │  ├─ runMigrations()                    │       │
    │     │  └─ loadRemoteManagedSettings() (异步) │       │
    │     │                                         │       │
    │     ├─ program.option(...)  ← 定义 ~50 个选项│       │
    │     ├─ program.command('mcp')                 │       │
    │     ├─ program.command('auth')                │       │
    │     ├─ program.command('plugin')              │       │
    │     ├─ program.command('server')              │       │
    │     └─ program.action(async (prompt, opts) => │       │
    │        │                                     │       │
    │        ├─ setup() ← src/setup.ts             │       │
    │        │  ├─ startUdsMessaging()              │       │
    │        │  ├─ setup worktree/tmux              │       │
    │        │  ├─ processSetupHooks()              │       │
    │        │  └─ initSessionMemory()              │       │
    │        │                                     │       │
    │        ├─ createRoot() ← src/ink.ts          │       │
    │        ├─ showSetupScreens() (trust, onboarding, login)
    │        ├─ initializeLspServerManager()       │       │
    │        ├─ fetchBootstrapData()               │       │
    │        ├─ getMcpToolsCommandsAndResources()   │       │
    │        ├─ [构建 initialState]                 │       │
    │        │                                     │       │
    │        └─ launchRepl(root, appProps, replProps, renderAndRun)
    │           ├─ import App from components/App   │       │
    │           ├─ import REPL from screens/REPL    │       │
    │           └─ renderAndRun(root, <App><REPL>)  │       │
    │                                               │       │
    ├─ startDeferredPrefetches() ← 首次渲染后调用   │       │
    │  ├─ initUser()                                │       │
    │  ├─ getUserContext()                          │       │
    │  ├─ getSystemContext()                        │       │
    │  ├─ getRelevantTips()                         │       │
    │  ├─ countFilesRoundedRg()                     │       │
    │  ├─ initializeAnalyticsGates()                │       │
    │  └─ settingsChangeDetector.initialize()       │       │

代码引用:

  • 入口分流: src/entrypoints/cli.tsx:33-298
  • 快速路径零加载: src/entrypoints/cli.tsx:37 (--version 不加载任何模块)
  • MDM/Keychain 并行预取: src/main.tsx:13-20
  • init() 函数: src/entrypoints/init.ts:57-238 (memoized, 只执行一次)
  • preAction hook: src/main.tsx:907-966
  • createRoot/launchRepl: src/main.tsx:2226-2229, src/replLauncher.tsx:12-22
  • 延迟预取: src/main.tsx:388-431

2.2 启动性能优化策略

  1. 并行子进程预取: startMdmRawRead() 和 startKeychainPrefetch() 在模块评估前启动,与 ~135ms 的 import 阶段并行执行 (src/main.tsx:13-20)
  2. 分阶段初始化: init() 使用 memoize 确保只执行一次 (src/entrypoints/init.ts:57)
  3. 首屏后延迟加载: startDeferredPrefetches() 在首次渲染后才执行用户初始化、tips 预取等非关键工作 (src/main.tsx:388-431)
  4. 快速路径分流: cli.tsx 对 --version、daemon、bridge 等场景使用独立路径,避免加载主 CLI 模块 (src/entrypoints/cli.tsx:33-298)
  5. Startup Profiler: src/utils/startupProfiler.ts 使用 performance.mark() 精确追踪各阶段耗时,支持采样上报和详细分析两种模式

3. 模块依赖图

3.1 核心依赖关系(文本表示)

entrypoints/cli.tsx
  └──> main.tsx (动态 import)
         ├──> bootstrap/state.ts  (全局可变状态,1758 行)
         ├──> entrypoints/init.ts (初始化,memoized)
         │     ├──> utils/config.ts
         │     ├──> utils/managedEnv.ts
         │     ├──> utils/gracefulShutdown.ts
         │     ├──> services/analytics/*
         │     ├──> utils/proxy.ts
         │     └──> utils/telemetry/instrumentation.ts (lazy)
         ├──> commands.ts  -->  commands/*
         ├──> tools.ts     -->  tools/*
         ├──> context.ts   -->  utils/git.ts, utils/claudemd.ts
         ├──> setup.ts     -->  utils/worktree.ts, services/SessionMemory
         ├──> ink.ts       -->  ink/root.ts (Ink 渲染引擎)
         │                      └──> components/design-system/ThemeProvider
         ├──> state/store.ts  (轻量级 Store<T> 实现)
         ├──> state/AppStateStore.ts  (AppState 类型定义)
         ├──> state/AppState.tsx  (AppStateProvider, React Context)
         │     └──> context/mailbox.tsx, context/voice.tsx
         ├──> services/mcp/client.ts  (MCP 客户端)
         ├──> services/api/bootstrap.ts (引导数据)
         ├──> services/analytics/growthbook.ts (Feature Flags)
         ├──> replLauncher.tsx
         │     └──> components/App.tsx
         │           └──> screens/REPL.tsx
         │                 ├──> QueryEngine.ts
         │                 │     └──> query.ts
         │                 │           └──> services/tools/toolOrchestration.ts
         │                 ├──> hooks/* (85 个自定义 hooks)
         │                 └──> components/* (144 个 UI 组件)
         └──> QueryEngine.ts (headless 模式)

tools.ts
  ├──> Tool.ts  (Tool 类型定义, 792 行)
  ├──> tools/AgentTool/AgentTool.ts
  ├──> tools/BashTool/BashTool.ts
  ├──> tools/FileEditTool/FileEditTool.ts
  ├──> tools/FileReadTool/FileReadTool.ts
  ├──> tools/FileWriteTool/FileWriteTool.ts
  ├──> tools/GlobTool/GlobTool.ts
  ├──> tools/WebFetchTool/WebFetchTool.ts
  ├──> tools/WebSearchTool/WebSearchTool.ts
  ├──> ... (共 43 个工具)
  └──> [懒加载] tools/TeamCreateTool, tools/SendMessageTool

query.ts
  ├──> services/api/claude.ts (API 调用)
  ├──> services/compact/compact.ts (上下文压缩)
  ├──> services/tools/toolOrchestration.ts (工具执行)
  ├──> utils/messages.ts (消息处理)
  ├──> utils/attachments.ts (附件处理)
  └──> query/config.ts, query/deps.ts, query/stopHooks.ts

3.2 循环依赖处理

代码中多处使用 懒加载 (require()) 来打破循环依赖:

  • main.tsx:70-73: teammate.ts 通过 require() 避免与 AppState.tsx 的循环
  • tools.ts:63-72: TeamCreateTool/TeamDeleteTool/SendMessageTool 通过 require() 避免循环
  • commands.ts:62-123: 带 feature gate 的命令通过 require() 延迟加载
  • context.ts:1-34: 通过 memoize + cache clear 模式管理缓存

代码引用:

  • 懒加载 teammate: src/main.tsx:70
  • 懒加载 Team tools: src/tools.ts:63-72
  • 条件导入命令: src/commands.ts:62-122

4. Feature Flags 机制

4.1 核心机制

Feature flags 通过 Bun 构建时宏 实现,使用 import { feature } from 'bun:bundle' 导入。这是一个 编译时常量,在构建外部版本时被设置为 false,Bun 的 bundler 会将 if (feature('XXX')) { ... } 形式的代码块识别为不可达并执行 死代码消除 (DCE)。

代码引用: 全代码库 138 个文件使用 import { feature } from 'bun:bundle'

4.2 Feature Flags 使用频率 Top 20

Feature Flag使用次数职责
KAIROS154助手模式(Agent SDK daemon 使用)
TRANSCRIPT_CLASSIFIER107自动模式分类器(Auto Mode 权限)
TEAMMEM51团队记忆文件系统
VOICE_MODE46语音交互模式
BASH_CLASSIFIER45Bash 命令安全分类器
KAIROS_BRIEF39Brief 工具(agent-to-user 消息)
PROACTIVE37主动自治模式
COORDINATOR_MODE32协调器模式(多 agent 协调)
BRIDGE_MODE28Remote Control / Bridge 功能
EXPERIMENTAL_SKILL_SEARCH21实验性技能搜索
CONTEXT_COLLAPSE20上下文折叠/压缩
KAIROS_CHANNELS19通道通知(push 入站)
UDS_INBOX17Unix Domain Socket 消息收件箱
CHICAGO_MCP16Computer Use MCP 服务器
BUDDY16Buddy 功能
HISTORY_SNIP15历史记录裁剪
MONITOR_TOOL13监控工具
COMMIT_ATTRIBUTION12Git commit 归因
CACHED_MICROCOMPACT12缓存微压缩
BG_SESSIONS11后台会话管理

4.3 Feature Flag 使用模式

模式 1: 条件导入 (DCE)

// src/commands.ts:62-65
const proactive =
  feature('PROACTIVE') || feature('KAIROS')
    ? require('./commands/proactive.js').default
    : null

外部构建时 feature('PROACTIVE') 返回 false,整个 require 不会被打包。

模式 2: 条件逻辑运行时门控

// src/utils/permissions/permissions.ts:488
if (feature('TRANSCRIPT_CLASSIFIER')) {
  // 运行时路径
}

模式 3: 组合 feature flags

// src/commands.ts:77-79
const remoteControlServerCommand =
  feature('DAEMON') && feature('BRIDGE_MODE')
    ? require('./commands/remoteControlServer/index.js').default
    : null

模式 4: 环境变量 + feature flag 双重门控

// src/tools.ts:17-19
const REPLTool =
  process.env.USER_TYPE === 'ant'
    ? require('./tools/REPLTool/REPLTool.js').REPLTool
    : null

5. 关键设计模式

5.1 轻量级状态管理 (Store Pattern)

src/state/store.ts 实现了一个极简的响应式 Store:

  • 34 行代码,无外部依赖
  • getState(), setState(updater), subscribe(listener) 三个方法
  • 使用 Object.is() 进行引用相等性检查,避免不必要的更新
  • 与 React 通过 useSyncExternalStore 桥接

代码引用: src/state/store.ts:1-34

5.2 全局可变状态 (Bootstrap State)

src/bootstrap/state.ts 是一个 1758 行的全局状态模块,包含:

  • 会话 ID、CWD、模型设置、计费统计
  • OpenTelemetry meter/counter 引用
  • Hook 注册表
  • 通过 createSignal() 创建的响应式信号

文件顶部注释警告: // DO NOT ADD MORE STATE HERE - BE JUDICIOUS WITH GLOBAL STATE

代码引用: src/bootstrap/state.ts:31-1758

5.3 React Context 层级

App.tsx
  ├── FpsMetricsProvider    (FPS 指标)
  ├── StatsProvider         (统计数据)
  └── AppStateProvider      (应用状态)
        ├── MailboxProvider  (消息邮箱)
        ├── VoiceProvider    (语音, feature-gated)
        └── [子组件树]

代码引用: src/components/App.tsx:19-55, src/state/AppState.tsx:37-50

5.4 Tool 系统架构

每个 Tool 遵循统一的接口 (src/Tool.ts):

  • name, description, inputJSONSchema (Zod schema)
  • isEnabled(): 运行时检查是否启用
  • run(): 执行工具逻辑
  • userFacingName(): 用户可见名称

工具通过 getAllBaseTools() 汇总,根据 feature flags 和环境变量动态过滤:

  • 43 个工具目录
  • 条件包含: WebBrowserTool, REPLTool, WorkflowTool, SleepTool 等
  • CLAUDE_CODE_SIMPLE 模式只保留 Bash/Read/Edit

代码引用: src/tools.ts:193-251 (getAllBaseTools)

5.5 Query 循环 (Agent Loop)

核心代理循环在 src/query.ts (1729 行) 中实现:

  1. 构建系统提示 + 用户消息
  2. 发送 API 请求到 Anthropic
  3. 解析工具使用块
  4. 执行工具 (runTools())
  5. 收集工具结果
  6. 循环回到步骤 1

src/QueryEngine.ts (1295 行) 是 headless 模式的包装器,管理对话生命周期。

代码引用:

  • 查询循环: src/query.ts
  • 引擎包装: src/QueryEngine.ts
  • 工具编排: src/services/tools/toolOrchestration.ts

5.6 MCP 集成

Model Context Protocol 集成贯穿整个系统:

  • src/services/mcp/client.ts: MCP 客户端管理
  • src/services/mcp/config.ts: 配置解析与策略过滤
  • src/services/mcp/types.ts: 类型定义
  • src/tools/ListMcpResourcesTool/, src/tools/ReadMcpResourceTool/: MCP 资源工具
  • src/commands/mcp/: MCP 子命令 (add, list, get, serve)

5.7 命令系统

命令通过 src/commands.ts 注册,每个命令是一个 Command 类型:

  • type: 'prompt' | 'local-jsx': 命令类型
  • name: 命令名(斜杠命令)
  • description: 描述
  • getPromptForCommand(): 执行逻辑

101 个命令目录 + 动态命令(来自 skills 和 plugins)。命令列表通过 memoize() 懒加载 (src/commands.ts:258)。


6. 重要架构决策

6.1 Bun 运行时选择

  • 使用 bun:bundle 宏实现编译时 feature flag DCE
  • 使用 Bun 的打包器而非 webpack/esbuild
  • 利用 Bun 的快速启动时间

6.2 Ink 而非 blessed/terminal-kit

选择 React/Ink 作为终端 UI 框架:

  • 组件化 UI 开发(144 个组件)
  • 声明式渲染模型
  • 自定义 src/ink/ 目录包含 forked Ink 实现(48 个文件),包括自定义 reconciler (src/ink/reconciler.ts)、DOM 操作 (src/ink/dom.ts)、布局引擎 (src/ink/layout/)
  • 主题系统: src/components/design-system/ThemeProvider.tsx

6.3 Commander.js CLI 框架

  • 使用 @commander-js/extra-typings 获得类型安全
  • preAction hook 统一处理初始化(init, migrations, settings)
  • 50+ 个 CLI 选项
  • 多级子命令 (mcp, auth, plugin, server, ssh, etc.)

6.4 并行预取架构

启动时的 激进并行化 是核心性能策略:

  1. MDM + Keychain 在 import 阶段并行启动 (main.tsx:13-20)
  2. API preconnect 在 init() 最后阶段 fire-and-forget (init.ts:159)
  3. Bootstrap data、passes eligibility、fast mode status 在 setup 后并行拉取 (main.tsx:2350-2375)
  4. 首次渲染后的延迟预取: initUser, getUserContext, tips, file count (main.tsx:388-431)

6.5 会话生命周期管理

会话通过 src/bootstrap/state.ts 中的 switchSession() 管理:

  • 每个会话有唯一 SessionId (UUID)
  • 会话状态持久化到 ~/.claude/projects/ 目录
  • 支持 resume (--continue, --resume <id>)
  • 支持 fork session (--fork-session)
  • Teleport 功能: 跨机器会话迁移

6.6 安全模型

多层安全机制:

  • 信任对话框: 首次在目录运行需用户确认 (showSetupScreens)
  • 权限模式: default, auto, bypass 三种模式 (PERMISSION_MODES)
  • Bash 分类器: BASH_CLASSIFIER feature flag 控制 Bash 命令安全检查
  • 自动模式: TRANSCRIPT_CLASSIFIER feature flag 实现 AI 驱动的权限决策
  • 沙箱: SandboxManager 提供命令沙箱化
  • 调试检测: main.tsx:266-271 检测调试器并退出

6.7 Headless (SDK) 模式

通过 -p/--print 标志触发非交互模式:

  • 跳过 Ink 渲染、信任对话框、预取等
  • 直接通过 QueryEngine.ts 执行查询
  • 支持 stream-json 输出格式
  • 入口点标记为 sdk-cli 而非 cli

代码引用: src/main.tsx:800-803 (isNonInteractive 检测)


7. 代码规模与组织统计

类别数量
总文件数~1900
总代码行~512K
React 组件144 (components/)
自定义 Hooks85 (hooks/)
工具实现43 (tools/)
CLI 命令101 (commands/)
服务模块36 (services/)
工具函数329 (utils/)
Feature flags (使用中)40+
状态迁移脚本~10 (migrations/)
main.tsx 行数4684
bootstrap/state.ts 行数1758
query.ts 行数1729
QueryEngine.ts 行数1295
REPL.tsx 行数5006
screens/ 文件数3 (REPL, Doctor, ResumeConversation)

8. 附录: 关键文件路径索引

文件路径职责
CLI 入口src/entrypoints/cli.tsx快速路径分流
主入口src/main.tsxCommander 配置、会话启动
初始化src/entrypoints/init.ts系统初始化 (memoized)
全局状态src/bootstrap/state.ts会话级全局可变状态
设置src/setup.ts会话设置 (worktree, hooks, MCP)
命令注册src/commands.ts斜杠命令汇总
工具注册src/tools.tsAI 工具汇总
上下文src/context.ts系统/用户上下文生成
Ink 封装src/ink.tsInk 渲染引擎封装
REPL 启动src/replLauncher.tsxREPL 组件挂载
App 组件src/components/App.tsx顶层 React 包装器
REPL 屏幕src/screens/REPL.tsx主交互界面 (5006 行)
查询引擎src/QueryEngine.tsHeadless 查询管理
查询循环src/query.tsAgent 循环核心
Storesrc/state/store.ts轻量级状态管理
AppStatesrc/state/AppStateStore.ts应用状态类型定义
Tool 类型src/Tool.tsTool 接口定义
Startup Profilersrc/utils/startupProfiler.ts启动性能追踪