Anthropic的ClaudeCode源码因sourcemap泄露,包含约1900个源文件、51.2万行TypeScript代码。该项目采用模块化架构,终端优先,基于Bun运行时与React+Ink渲染,启动流程包含并行初始化与延迟预取等优化策略,对AIAgent工程实现具有参考价值。
2026年3月31日,Anthropic 向 npm 推送 @anthropic-ai/claude-code v2.1.88 版本时,发生了一个在当时看来不起眼的小失误——他们忘记排除 source map 文件(cli.js.map,约60MB)。这个 source map 本质上是一个 JSON 映射表,能把压缩后的代码还原成原始 TypeScript。
结果就是,约1900个源文件、51.2万行代码就这么毫无遮掩地躺在了每一个安装者的 node_modules 里。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
本次分析基于这批泄露源码(镜像仓库:gitee.com/thomaslwq/C…)。我们不讨论法律和道德层面的问题——只关注工程本身。坦白说,这套代码的设计思路,对任何想做 AI Agent 的人来说,都很有参考价值。
Claude Code 是 Anthropic 推出的 AI 编程助手,核心价值在于为开发者提供智能代码补全、调试和自动化能力。从项目结构来看,这是一个典型的终端优先应用,采用现代 TypeScript 技术栈:
{
"name": "@anthropic-ai/claude-code",
"type": "module",
"packageManager": "bun@1.3.5",
"engines": {
"bun": ">=1.3.5",
"node": ">=24.0.0"
}
}
核心技术选型:
| 维度 | 技术 | 选型理由 |
|---|---|---|
| 语言 | TypeScript | 类型安全、现代特性支持 |
| 运行时 | Bun | 高性能、快速启动、完整工具链 |
| UI框架 | React + Ink | 终端渲染,类Web开发体验 |
| 状态管理 | React Context + 自定义store | 轻量、灵活 |
| 命令行解析 | Commander | 成熟、功能完善 |
项目采用模块化架构,代码组织得相当清晰:
src/
├── commands/ # CLI 命令定义(add-dir、agents、bridge、btw...)
├── components/ # React 组件(UI层)
├── bridge/ # 远程控制桥接模块
├── services/ # 核心服务(API、MCP、LSP)
├── tools/ # 工具定义(BashTool、FileEditTool、MCPTool...)
├── utils/ # 工具函数库
├── state/ # 全局状态管理
├── ink/ # 终端渲染引擎(fork自Ink)
├── hooks/ # React Hooks
├── keybindings/ # 键盘快捷键系统
├── main.tsx # 主入口
└── dev-entry.ts # 开发环境入口
架构层次图:
┌─────────────────────────────────────────────────────────────┐
│ CLI 层 │
│ commands/ CLI 命令定义与处理 │
├─────────────────────────────────────────────────────────────┤
│ UI 层 │
│ components/ React 组件 │
│ ink/ 终端渲染引擎 │
├─────────────────────────────────────────────────────────────┤
│ 业务层 │
│ tools/ AI 工具定义 │
│ services/ 核心服务(API、MCP、LSP) │
│ bridge/ 远程控制桥接 │
├─────────────────────────────────────────────────────────────┤
│ 状态层 │
│ state/ 全局状态管理 │
│ hooks/ React Hooks │
├─────────────────────────────────────────────────────────────┤
│ 基础设施层 │
│ utils/ 工具函数 │
│ keybindings/ 快捷键系统 │
└─────────────────────────────────────────────────────────────┘
dev-entry.ts 是开发环境的第一道防线,确保项目状态完整:
function collectMissingRelativeImports(): MissingImport[] {
const files: string[] = []
scanFiles(resolve('src'), files)
scanFiles(resolve('vendor'), files)
const missing: MissingImport[] = []
const pattern = /(?:import|export)\s+[\s\S]*?from\s+['"](\.\.?\/[^'"]+)['"]|require\s*\(\s*['"](\.\.?\/[^'"]+)['"]\s*\)/g
for (const file of files) {
const text = readFileSync(file, 'utf8')
for (const match of text.matchAll(pattern)) {
const specifier = match[1] ?? match[2]
const target = resolve(dirname(file), specifier)
if (!hasResolvableTarget(target)) {
missing.push({ importer: file, specifier })
}
}
}
return missing.sort((a, b) => `${a.importer}:${a.specifier}`.localeCompare(`${b.importer}:${b.specifier}`))
}
设计亮点在哪里?几个值得关注的点:正则匹配精确识别相对路径导入语句;候选路径检查支持多种后缀(.ts、.tsx、.js、index.ts 等);排序输出按文件路径排序,便于定位问题。
main.tsx 的启动流程体现了多处性能优化设计:
并行初始化模式:
// 模块加载时立即启动,与后续 import 并行执行
profileCheckpoint('main_tsx_entry');
startMdmRawRead(); // MDM 读取(约65ms)
startKeychainPrefetch(); // Keychain 预取(约65ms)
设计原理其实不复杂:这两个操作都是异步 subprocess 调用,启动后立即返回,与后续的模块导入并行执行,可以节省约130ms的启动时间。
再看看延迟预取策略:
export function startDeferredPrefetches(): void {
if (isEnvTruthy(process.env.CLAUDE_CODE_EXIT_AFTER_FIRST_RENDER) || isBareMode()) {
return // 性能测试模式或裸模式跳过
}
// 进程级预取(在用户输入时后台执行)
void initUser();
void getUserContext();
prefetchSystemContextIfSafe();
void getRelevantTips();
void countFilesRoundedRg(getCwd(), AbortSignal.timeout(3000), []);
// 分析和特性标志初始化
void initializeAnalyticsGates();
void prefetchOfficialMcpUrls();
void refreshModelCapabilities();
// 文件变更检测器
void settingsChangeDetector.initialize();
void skillChangeDetector.initialize();
}
设计意图很清晰:将非关键路径的初始化延迟到首屏渲染后,避免阻塞启动流程。
Windows路径劫持防护:
// SECURITY: 防止 Windows 从当前目录执行命令
process.env.NoDefaultCurrentDirectoryInExePath = '1';
Git命令安全检查:
function prefetchSystemContextIfSafe(): void {
const isNonInteractiveSession = getIsNonInteractiveSession();
// 非交互模式(--print)视为可信
if (isNonInteractiveSession) {
void getSystemContext();
return;
}
// 交互模式需要先建立信任
const hasTrust = checkHasTrustDialogAccepted();
if (hasTrust) {
void getSystemContext();
}
// 否则跳过,等待信任建立
}
安全原理其实很好理解:Git命令可能通过hooks和配置执行任意代码,所以只在信任建立后才执行。
系统支持多种启动模式,通过 initializeEntrypoint 进行路由:
function initializeEntrypoint(isNonInteractive: boolean): void {
if (process.env.CLAUDE_CODE_ENTRYPOINT) return;
const cliArgs = process.argv.slice(2);
// MCP 服务模式
const mcpIndex = cliArgs.indexOf('mcp');
if (mcpIndex !== -1 && cliArgs[mcpIndex + 1] === 'serve') {
process.env.CLAUDE_CODE_ENTRYPOINT = 'mcp';
return;
}
// GitHub Action 模式
if (isEnvTruthy(process.env.CLAUDE_CODE_ACTION)) {
process.env.CLAUDE_CODE_ENTRYPOINT = 'claude-code-github-action';
return;
}
// 根据交互状态设置
process.env.CLAUDE_CODE_ENTRYPOINT = isNonInteractive 'sdk-cli' : 'cli';
}
支持的入口类型:
| 入口类型 | 触发条件 | 用途 |
|---|---|---|
cli | 交互式终端 | 常规使用 |
sdk-cli | -p/--print 标志 | SDK/脚本调用 |
mcp | mcp serve 命令 | MCP 服务器模式 |
claude-code-github-action | GITHUB_ACTIONS 环境变量 | GitHub Action |
sdk-ts | SDK TypeScript 调用 | 程序化调用 |
sdk-py | SDK Python 调用 | 程序化调用 |
命令定义采用模块化设计,每个命令独立目录:
// commands/btw/index.ts
export const btwCommand: Command = {
name: 'btw',
description: 'Quick note-taking and context switching',
examples: [
{ usage: 'btw "Remember to fix the login flow"', description: 'Add a quick note' },
{ usage: 'btw --list', description: 'List all notes' },
],
// ...
};
工具是 Claude Code 的核心能力,定义在 tools/ 目录:
// tools/BashTool/prompt.ts
export const bashTool: Tool = {
name: 'bash',
description: 'Execute bash commands',
inputSchema: {
type: 'object',
properties: {
command: { type: 'string', description: 'Command to execute' },
cwd: { type: 'string', description: 'Working directory' },
},
required: ['command'],
},
// ...
};
状态管理采用 React Context + 自定义 store:
// state/AppStateStore.ts
export interface AppState {
toolPermissionContext: ToolPermissionContext;
fastMode: FastModeState;
fileHistory: FileHistoryState;
attribution: AttributionState;
mcp: McpState;
// ...
}
export const getDefaultAppState = (): AppState => ({
toolPermissionContext: getDefaultToolPermissionContext(),
fastMode: { enabled: false, model: null },
fileHistory: getDefaultFileHistoryState(),
attribution: createEmptyAttributionState(),
mcp: getDefaultMcpState(),
// ...
});
ink/ 目录是对 Ink 框架的定制化 fork,提供终端 UI 渲染能力:
// ink/renderer.ts
export class Renderer {
private root: Root;
private nodeCache: NodeCache;
private optimizer: Optimizer;
render(tree: React.ReactNode): void {
// 将 React 组件转换为终端输出
const nodes = this.reconciler.reconcile(tree);
const output = this.renderToScreen(nodes);
this.output.write(output);
}
}
用户启动 claude 命令
│
▼
┌──────────────────────────────────────────────┐
│ dev-entry.ts │
│ 1. 检查缺失的相对导入 │
│ 2. 输出版本/帮助信息(如果有参数) │
│ 3. 导入 entrypoints/cli.tsx │
└──────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ main.tsx │
│ 1. 性能监控初始化 │
│ 2. 并行启动 MDM/Keychain 读取 │
│ 3. 解析命令行参数 │
│ 4. 确定入口类型(cli/sdk/mcp) │
│ 5. 加载设置 │
│ 6. 执行 run() │
└──────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ run() │
│ 1. 初始化 Commander │
│ 2. 注册 preAction 钩子 │
│ 3. 注册命令 │
│ 4. 解析并执行命令 │
└──────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ REPL 启动 │
│ 1. 初始化状态存储 │
│ 2. 渲染终端 UI │
│ 3. 启动事件循环 │
│ 4. 等待用户输入 │
└──────────────────────────────────────────────┘
使用 Bun 的 feature() 进行条件编译:
const coordinatorModeModule = feature('COORDINATOR_MODE') require('./coordinator/coordinatorMode.js') : null;
const kairosGate = feature('KAIROS') require('./assistant/gate.js') : null;
优势很明显:未启用的功能不会被打包,减小体积,优化启动速度。
// 后台执行,不阻塞主流程
void loadRemoteManagedSettings();
void loadPolicyLimits();
void import('./utils/eventLoopStallDetector.js').then(m => m.startEventLoopStallDetector());
// 防止 inspector 注入
if (isBeingDebugged()) {
process.exit(1);
}
function isBeingDebugged() {
const hasInspectArg = process.execArgv.some(arg => /--inspect(-brk)/.test(arg));
const hasInspectEnv = process.env.NODE_OPTIONS && /--inspect(-brk)/.test(process.env.NODE_OPTIONS);
// ...
return hasInspectorUrl || hasInspectArg || hasInspectEnv;
}
Claude Code 的架构设计体现了以下几个方面的优秀工程实践:模块化架构,清晰的职责划分便于维护和扩展;性能优化方面,并行初始化、延迟加载、条件编译都用得很到位;安全优先也不是一句空话,路径劫持防护、Git命令安全检查、调试器检测都考虑到了;可扩展性方面,支持多种入口类型和功能开关机制;整体工程化程度相当高,完善的错误处理、日志体系和监控指标一个不少。