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": "[email protected]","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+[sS]*?froms+['"](..?/[^'"]+)['"]|require(s*['"](..?/[^'"]+)['"]s*)/gfor (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.tsexport 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.tsexport 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.tsexport 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.tsexport 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 的架构设计体现了以下优秀工程实践: