image.png

一次 npm 发布事故,让 Anthropic 的内核代码意外开源。我们从头拆解这个工业级 AI 编程助手的架构和最核心的那个循环。

0. 写在前面:这不是官方开源

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/        快捷键系统                          │
└─────────────────────────────────────────────────────────────┘

三、启动流程深度解析

3.1 开发入口:完整性检查

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*\)/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.jsindex.ts 等多种后缀
  • 排序输出:按文件路径排序,便于定位问题

3.2 主入口:性能优化策略

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();
}

设计意图: 将非关键路径的初始化延迟到首屏渲染后,避免阻塞启动流程。

3.3 安全性设计

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 和配置执行任意代码,因此只在信任建立后才执行。

3.4 入口点路由

系统支持多种启动模式,通过 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/脚本调用
mcpmcp serve 命令MCP 服务器模式
claude-code-github-actionGITHUB_ACTIONS 环境变量GitHub Action
sdk-tsSDK TypeScript 调用程序化调用
sdk-pySDK Python 调用程序化调用

四、核心模块剖析

4.1 命令系统

命令定义采用模块化设计,每个命令独立目录:

// 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' },
],
// ...
};

4.2 工具系统

工具是 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'],
},
// ...
};

4.3 状态管理

状态管理采用 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(),
// ...
});

4.4 终端渲染引擎

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. 等待用户输入                            │
└──────────────────────────────────────────────┘

六、架构设计亮点

6.1 条件编译

使用 Bun 的 feature() 进行条件编译:

const coordinatorModeModule = feature('COORDINATOR_MODE') 
? require('./coordinator/coordinatorMode.js') 
: null;

const kairosGate = feature('KAIROS') 
? require('./assistant/gate.js') 
: null;

优势: 未启用的功能不会被打包,减小体积,优化启动速度。

6.2 异步非阻塞设计

// 后台执行,不阻塞主流程
void loadRemoteManagedSettings();
void loadPolicyLimits();
void import('./utils/eventLoopStallDetector.js').then(m => m.startEventLoopStallDetector());

6.3 防御性编程

// 防止 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 的架构设计体现了以下优秀工程实践:

  1. 模块化架构:清晰的职责划分,便于维护和扩展
  2. 性能优化:并行初始化、延迟加载、条件编译
  3. 安全性优先:路径劫持防护、Git 命令安全检查、调试器检测
  4. 可扩展性:支持多种入口类型、功能开关机制
  5. 工程化程度高:完善的错误处理、日志体系、监控指标