背景
🚨 刚刚,Claude Code 源码被全网公开了。
不是黑客攻击,是一次典型的发布失误------source map 没剥离干净。
Anthropic 发布的 @anthropic-ai/claude-code 2.1.88 版本里,带了一个 60MB 的 source map 文件,直接指向内部 R2 存储的完整源码。装个包,顺手就能拉下来。
1900+ 个文件,51 万+ 行 TypeScript 代码,就这样摊在了所有人面前------CLI 核心、工具系统、多 Agent 协调、IDE Bridge、权限控制、插件系统,一个不落。
更值得注意的:一些尚未发布的功能也跟着曝光了------Agent 新特性、语音模式、远程协作、持久记忆......
官方目前暂无公告,但 npm 上的 map 文件已被紧急移除。
但是对开发者来说,这是一次绝佳的学习机会。这次我们先关注整体流程,后续我也会继续出专栏来逐步拆解每个细节,关注我不迷路 💗
基于 @anthropic-ai/claude-code@2.1.88 版本的源代码分析
Claude Code 源码分析
基于 @anthropic-ai/claude-code@2.1.88 源码
项目结构
perl
restored-src/
├── src/
│ ├── main.tsx # 入口文件
│ ├── replLauncher.tsx # REPL 启动
│ ├── components/ # React 组件
│ ├── screens/ # 界面(主要是REPL)
│ ├── coordinator/ # 协调器模式
│ ├── state/ # 状态管理
│ ├── tasks/ # 任务系统
│ ├── tools/ # 工具集
│ ├── services/ # API/MCP/Analytics等
│ ├── bridge/ # 远程桥接
│ ├── commands/ # 命令系统
│ ├── skills/ # 技能
│ ├── plugins/ # 插件
│ └── ...
启动流程
main.tsx 是入口。先跑一堆预检:
enableConfigs()启用配置系统applySafeConfigEnvironmentVariables()应用安全的环境变量- 并行启动 MDM 读取、Keychain 预取等耗时操作
- 初始化遥测、检测 Git 仓库
- 等待策略限制加载完成
launchRepl()启动 REPL,渲染 React 组件树
启动阶段的设计思路是把能并行的都并行化,减少等待时间。
REPL 主循环
用户输入后分两路:
- Slash 命令:直接执行对应的命令模块
- 普通文本 :进
handlePromptSubmit→query()处理
query 是核心。它构建消息上下文、调用 Claude API、处理流式响应。API 返回的事件类型主要有三种:tool_use(需要执行工具)、content_block(文本内容)、message_delta(完成标记)。
工具执行走 runTools,内部会根据工具类型决定并发还是串行:读文件、glob、grep 这些可以并行;写文件、agent 调用得串行来。
工具结果返回给 API,继续下一轮对话,直到 API 返回完成。
状态管理
AppStateStore 是核心状态仓库,用 React Context 的方式提供。AppState 里装的东西挺杂的:
settings:用户配置tasks:正在跑的所有任务mcp:MCP 客户端、工具、资源plugins:插件状态toolPermissionContext:权限上下文mainLoopModel:当前用的模型
任务有六种类型:local_bash、local_agent、remote_agent、in_process_teammate、local_workflow、monitor_mcp。
工具系统
tools.ts 是入口,定义了所有内置工具。分类挺清晰的:
- 文件操作:Read、Edit、Write、Glob、Grep、NotebookEdit
- 终端操作:Bash、LSP
- 网络操作:WebFetch、WebSearch
- 任务管理:Create、Stop、List、Get、Update
- Agent 系统:Agent(启动子agent)、SendMessage(给 agent 发消息)、TeamCreate、TeamDelete
- 其他:AskUserQuestion、Config、ExitPlanMode、SkillTool 等
工具编排的核心在 services/tools/toolOrchestration.ts 的 runTools 函数。它先把工具调用分区,然后并发执行只读工具,串行执行可能产生副作用的工具。
查询引擎
query.ts 是查询引擎的入口。主要步骤:
- 消息预处理,包括上下文拼装
microcompact压缩历史消息- 调用
queryModelWithStreaming - 处理流事件:工具调用、文本内容,完成标记
- 工具执行完后把结果发回 API
- 自动 compact 检查,决定是否压缩上下文
- 增量保存会话状态
API 调用在 services/api/claude.ts,用的是 Anthropic 的流式 API。
MCP 系统
MCP (Model Context Protocol) 在 services/mcp/ 下实现了一套完整的东西:
- 传输层:SDK Control Transport(连接外部 MCP 服务器)、InProcess Transport(进程内通信)
- 认证:OAuth 支持
- 功能:工具发现、资源管理、提示词模板、授权处理
MCP 客户端负责管理多个服务器连接,发现工具和资源供模型使用。
命令系统
commands.ts 注册了所有命令,类型分四种:
prompt:提示词类型,展开后发给模型local:本地执行,返回文本结果local-jsx:渲染 React 组件info:信息展示
命令来源有多个:内置命令、skills 目录下的技能、插件提供的命令,工作流脚本、bundle 技能。加载顺序是:先聚合所有来源,再按可用性过滤,最后去重。
协调器模式
启用 COORDINATOR_MODE 后,Claude Code 变成协调者,指挥 worker agent 干活。Coordinator 接收用户任务,分派给多个 worker 并行研究/实现,最后汇总结果。
Worker 有两种模式:
- 简单模式:只有 Bash、Read、Edit
- 完整模式:所有工具 + MCP + Skills
Coordinator 的 prompt 里写了很清楚的工作模式,不抢功、只汇总。
桥接系统
Bridge 实现了两件事:远程控制(手机/网页操控桌面 Claude)和远程会话(桌面 Claude 在网页上跑)。
连接状态有四种:connecting、connected、reconnecting、disconnected。断线会自动重连,有指数退避。
权限系统
权限模式有四种:default、auto、manual、bypass。
检查流程:先 canUseTool,再 permissionCheck,然后查 alwaysAllow/alwaysDeny 规则。auto 模式下低风险操作自动放行,高风险操作弹窗确认。
会话管理
会话以 sessionId 标识,消息增量保存到磁盘。会话成本(token 消耗)独立统计。
恢复会话时从磁盘读取历史消息,重建对话上下文。
插件系统
插件分三类:Marketplace 下载的、本地目录的、内置的。
加载流程:扫描目录 → 读取清单 → 注册命令 → 聚合到命令列表。插件卸载或更新后需要 /reload-plugins 生效。
技能系统
技能放在 skills/ 目录下,每个技能是一个独立模块。模型通过 SkillTool 调用技能。
技能来源:技能目录、bundle 技能(内置)、插件技能。动态技能会在命令执行过程中被发现并加载。
组件层次
React 组件树:
特性开关
用 bun:bundle 的 feature() 函数控制功能编译。开启哪些特性由环境变量决定,比如 COORDINATOR_MODE、KAIROS、VOICE_MODE 等。
好处是发行版可以裁剪掉不需要的代码,减少体积。
关键文件
| 文件 | 作用 |
|---|---|
main.tsx |
入口 |
replLauncher.tsx |
启动 REPL |
components/App.tsx |
根组件 |
screens/REPL.tsx |
REPL 界面 |
state/AppStateStore.ts |
状态定义 |
query.ts |
查询引擎 |
services/api/claude.ts |
API 调用 |
services/tools/toolOrchestration.ts |
工具执行 |
tools.ts |
工具注册 |
commands.ts |
命令注册 |
bridge/bridgeMain.ts |
远程桥接 |
coordinator/coordinatorMode.ts |
协调器 |
总结
整体是个分层架构:入口 → 状态 → REPL → 查询引擎 → 工具/API。状态管理用 React Context,工具系统可扩展,命令来自多个源(内置/技能/插件/工作流)。
设计上比较务实,该并行并行、该串行串行,会话状态持久化到磁盘而不是全放内存。特性开关的实现也值得参考,可以有效控制不同发行版的功能差异。