源码泄露事件

2026 年 3 月 31 日,Claude Code 的完整源码在技术社区流出,引发了 AI 开发者圈的广泛讨论。这并非 Anthropic 主动开源,而是一次意外的代码泄露——完整的 TypeScript 源码、构建配置、内部工具实现,甚至包含部分内部注释和调试代码,全部暴露在公众视野中。

这套源码的泄露,对于 AI Agent 开发者而言,是一次难得的学习机会:

代码规模惊人src/ 目录下 60+ 个模块,涵盖工具系统、权限管理、Agent 调度、MCP 协议实现等完整功能。这不是一个 MVP 或玩具项目,而是经过大规模用户验证的商业级产品。

架构设计精良:从工具系统的 buildTool 模式,到权限系统的多层级检查,再到 MCP 协议的适配器设计,每一处都体现了工程团队对 AI Agent 的深刻理解。

工程化程度极高:完善的错误处理、性能优化(并行预取、懒加载、缓存)、测试覆盖、类型安全……这是教科书级别的 TypeScript 项目工程实践。

安全意识强烈:源码中随处可见安全相关的代码——危险命令检测、沙箱隔离、权限剥离、敏感信息过滤。Claude Code 在让 AI 拥有强大能力的同时,也在小心翼翼地控制风险。

泄露源码包含的核心内容

  • 核心引擎:Agent 调度、消息处理、工具调用
  • 40+ 内置工具:Bash、Edit、Glob、Grep、WebSearch、Agent...
  • 权限系统:细粒度的工具权限控制和用户确认机制
  • MCP 协议实现:动态加载外部工具的标准协议
  • 多 Agent 协作:子代理、团队模式、后台任务

源码规模

  • 60+ 模块目录
  • 数千个 TypeScript 文件
  • 完整的构建、测试、部署流程

技术栈

  • TypeScript(严格模式)
  • Bun 运行时 + Node.js 兼容
  • React + Ink(终端 UI)
  • Zod v4(Schema 验证)
  • Anthropic SDK

本文定位声明

本文是一份技术学习文档,目的是:

  • 帮助开发者理解 AI Agent 的架构设计
  • 学习 TypeScript 大型项目的工程实践
  • 探索 MCP 协议的设计思路

声明仅用于学习研究目的。


📋 目录

  • 项目概览
  • 核心架构
  • 根目录核心文件
  • 模块深度分析
  • 工具系统详解
  • 服务模块详解
  • 设计模式与最佳实践
  • 如何基于源码搭建自己的 Claude Code

项目概览

技术栈

层级

技术

版本/说明

语言

TypeScript

严格类型检查

运行时

Bun

主运行时,支持原生模块

兼容

Node.js

>= 18

构建

Bun bundle

支持 dead code elimination

UI 框架

React + Ink

终端 UI

状态管理

自定义 Store

类似 Redux,不可变更新

API

Anthropic SDK

Claude 模型 API

协议

MCP

Model Context Protocol

验证

Zod v4

Schema 验证

核心特性

  1. 多模式运行: 交互式 REPL + 非交互式 Print 模式
  1. 工具扩展: 40+ 内置工具 + MCP 动态加载
  1. Agent 系统: 支持子代理、团队协作、后台任务
  1. 权限管理: 细粒度的工具权限控制
  1. 会话持久化: 支持会话恢复、分支、teleport

核心架构

┌─────────────────────────────────────────────────────────────────┐
│                          CLI Entry (main.tsx)                   │
│  - 命令行参数解析 (Commander)                                     │
│  - 初始化流程 (init, setup)                                      │
│  - 模式选择 (interactive / headless)                             │
└─────────────────────────────────────────────────────────────────┘
                                │
                ┌───────────────┴───────────────┐
                ▼                               ▼
┌───────────────────────────┐   ┌───────────────────────────┐
│   Interactive Mode (REPL)  │   │   Headless Mode (print)   │
│   - Ink UI 渲染            │   │   - 单次查询执行           │
│   - 实时状态更新            │   │   - 流式输出支持           │
│   - 用户交互处理            │   │   - JSON Schema 输出       │
└───────────────────────────┘   └───────────────────────────┘
                │                               │
                └───────────────┬───────────────┘
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│                        Query Engine                             │
│  - 消息处理流程                                                  │
│  - API 调用管理                                                  │
│  - 工具调用调度                                                  │
└─────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│                         Tool System                             │
│  - 40+ 内置工具                                                  │
│  - MCP 动态工具                                                  │
│  - 权限检查                                                      │
│  - 并发控制                                                      │
└─────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│                        State Management                         │
│  - AppState (全局状态)                                           │
│  - ToolPermissionContext                                         │
│  - MCP 连接状态                                                  │
│  - Task/Agent 状态                                               │
└─────────────────────────────────────────────────────────────────┘

根目录核心文件

main.tsx - CLI 入口

职责: 命令行解析、初始化编排、模式选择

// 核心流程
async function main() {
  // 1. 安全设置
  process.env.NoDefaultCurrentDirectoryInExePath = '1'
  
  // 2. 并行预启动(性能优化)
  startMdmRawRead()           // MDM 设置预读
  startKeychainPrefetch()     // Keychain 预取
  
  // 3. 命令行解析(60+ 选项)
  const program = new CommanderCommand()
  program
    .option('-p, --print')
    .option('--model <model>')
    .option('--dangerously-skip-permissions')
    // ... 更多选项
  
  // 4. 初始化钩子
  program.hook('preAction', async () => {
    await init()              // 加载配置、认证
    runMigrations()           // 数据迁移
  })
  
  // 5. 执行模式分支
  if (isNonInteractiveSession) {
    await runHeadless()
  } else {
    await launchRepl()
  }
}

设计亮点:

  • 并行预取减少启动时间
  • Lazy Import 条件导入
  • Dead code elimination(feature() 函数)
  • 迁移系统保证配置兼容性

Tool.ts - 工具接口

职责: 定义工具接口、提供 buildTool 构建器

export type Tool<Input, Output, Progress> = {
  // 基本信息
  readonly name: string
  aliases?: string[]
  readonly inputSchema: ZodSchema<Input>
  outputSchema?: ZodSchema<Output>
  
  // 核心方法
  call(input, context, canUseTool, parentMessage, onProgress): Promise<ToolResult<Output>>
  description(input, options): Promise<string>
  
  // 权限
  checkPermissions(input, context): Promise<PermissionResult>
  validateInput?(input, context): Promise<ValidationResult>
  
  // 行为特性
  isEnabled(): boolean
  isConcurrencySafe(input): boolean
  isReadOnly(input): boolean
  isDestructive?(input): boolean
  interruptBehavior?(): 'cancel' | 'block'
  
  // UI 渲染
  renderToolUseMessage(input, options): ReactNode
  renderToolResultMessage?(content, progress, options): ReactNode
  getToolUseSummary?(input): string | null
  
  // Prompt
  prompt(options): Promise<string>
  userFacingName(input): string
}

// 构建器:填充默认值
export function buildTool<D extends ToolDef>(def: D): BuiltTool<D> {
  return {
    ...TOOL_DEFAULTS,
    userFacingName: () => def.name,
    ...def,
  }
}

const TOOL_DEFAULTS = {
  isEnabled: () => true,
  isConcurrencySafe: () => false,  // 安全默认值
  isReadOnly: () => false,
  isDestructive: () => false,
  checkPermissions: () => Promise.resolve({ behavior: 'allow' }),
}

设计模式:

  • Builder Pattern:buildTool 提供默认值
  • Strategy Pattern:不同权限检查策略
  • Observer Pattern:onProgress 回调

context.ts - 上下文管理

职责: 用户上下文、系统上下文的获取和缓存

// 用户上下文(CLAUDE.md 等)
export const getUserContext = memoize(async () => {
  const claudeMd = shouldDisableClaudeMd
    ? null
    : getClaudeMds(await getMemoryFiles())
  
  return {
    ...(claudeMd && { claudeMd }),
    currentDate: `Today's date is ${getLocalISODate()}.`,
  }
})

// 系统上下文(Git 状态)
export const getSystemContext = memoize(async () => {
  const [branch, mainBranch, status, log] = await Promise.all([
    getBranch(),
    getDefaultBranch(),
    execFileNoThrow(gitExe(), ['status', '--short']),
    execFileNoThrow(gitExe(), ['log', '--oneline', '-n', '5']),
  ])
  
  return {
    gitStatus: [
      `Current branch: ${branch}`,
      `Main branch: ${mainBranch}`,
      `Status:\n${status || '(clean)'}`,
      `Recent commits:\n${log}`,
    ].join('\n\n')
  }
})

Task.ts - 任务系统

职责: 任务类型定义、任务 ID 生成、任务状态管理

export type TaskType =
  | 'local_bash'      // 本地 Shell 任务
  | 'local_agent'     // 本地 Agent 任务
  | 'remote_agent'    // 远程 Agent 任务
  | 'in_process_teammate'  // 进程内队友
  | 'local_workflow'  // 本地工作流
  | 'monitor_mcp'     // MCP 监控
  | 'dream'           // Dream 任务

export type TaskStatus =
  | 'pending' | 'running' | 'completed' | 'failed' | 'killed'

// 任务 ID 生成(安全、唯一)
export function generateTaskId(type: TaskType): string {
  const prefix = TASK_ID_PREFIXES[type]  // 'b', 'a', 'r' 等
  const bytes = randomBytes(8)
  let id = prefix
  for (let i = 0; i < 8; i++) {
    id += TASK_ID_ALPHABET[bytes[i]! % 36]  // 0-9a-z
  }
  return id  // 例如: "b3k9x2m1n7p4"
}

模块深度分析

📁 assistant/ - AI 助手后台服务

职责: KAIROS/Proactive 模式的后台守护进程

文件

功能

深入分析

sessionHistory.ts

会话历史管理

记录会话 ID、时间戳、摘要,支持历史查询和恢复

架构设计:

┌─────────────────────────────────────────┐
│           Assistant Daemon              │
│  ┌─────────────┐  ┌─────────────┐       │
│  │  Scheduler  │  │   Notifier  │       │
│  │  (定时任务)  │  │  (推送通知)  │       │
│  └─────────────┘  └─────────────┘       │
│         │                │              │
│         ▼                ▼              │
│  ┌─────────────────────────────────┐   │
│  │       Session History           │   │
│  │   (会话记录、上下文恢复)          │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘

📁 bootstrap/ - 启动状态管理

职责: 全局启动状态的单例管理

// state.ts 核心状态
let cwd: string                           // 当前工作目录
let sessionId: SessionId                  // 会话 ID
let mainLoopModel: ModelSetting           // 主模型
let permissionMode: PermissionMode        // 权限模式
let agentDefinitions: AgentDefinitionsResult  // Agent 定义
let hasTrustDialogAccepted: boolean       // 信任对话框
let statsStore: StatsStore                // 统计存储
let registeredHooks: RegisteredHooks      // 注册的 Hooks

// 状态访问器(确保单例)
export function getCwd(): string { return cwd }
export function getSessionId(): SessionId { return sessionId }
export function getMainLoopModel(): ModelSetting { return mainLoopModel }

设计要点:

  • 单例模式确保全局一致性
  • 状态变更通过 setter 触发副作用
  • 支持状态快照和恢复

📁 bridge/ - 远程控制桥接

职责: Claude Code 与 claude.ai 的双向通信

核心文件分析:

文件

职责

关键实现

bridgeMain.ts

主逻辑

WebSocket 连接、心跳、重连

bridgeApi.ts

API 接口

RPC 调用封装

bridgeConfig.ts

配置管理

环境 ID、会话 URL

bridgeMessaging.ts

消息处理

序列化、路由

bridgePermissionCallbacks.ts

权限回调

远程权限审批

bridgePointer.ts

指针同步

光标位置共享

capacityWake.ts

容量唤醒

按需激活

架构图:

┌─────────────────┐                    ┌─────────────────┐
│   Claude Code   │                    │   claude.ai     │
│    (本地)       │                    │    (云端)       │
│                 │                    │                 │
│  ┌───────────┐  │   WebSocket (WSS)  │  ┌───────────┐  │
│  │  Bridge   │◄─┼────────────────────┼─►│  Server   │  │
│  │  Client   │  │                    │  │           │  │
│  └───────────┘  │                    │  └───────────┘  │
│        │        │                    │        │        │
│        ▼        │                    │        ▼        │
│  ┌───────────┐  │                    │  ┌───────────┐  │
│  │Permission │  │  权限请求 ────────►│  │  User     │  │
│  │  Manager  │  │  ◄─────── 审批结果  │  │ Approval  │  │
│  └───────────┘  │                    │  └───────────┘  │
└─────────────────┘                    └─────────────────┘

消息流:

// 权限请求流程
async function requestPermission(tool: string, input: unknown) {
  // 1. 本地生成请求
  const request = {
    type: 'permission_request',
    toolName: tool,
    input: sanitize(input),
    timestamp: Date.now(),
  }
  
  // 2. 发送到云端
  bridge.send(request)
  
  // 3. 等待审批
  const response = await bridge.waitFor('permission_response', request.id)
  
  return response.decision  // 'allow' | 'deny' | 'ask'
}

📁 buddy/ - 伴侣精灵系统

职责: 终端右下角的动画伴侣

文件

功能

实现

companion.ts

核心逻辑

状态机、动画触发

CompanionSprite.tsx

React 组件

Ink 渲染、帧动画

sprites.ts

精灵定义

ASCII 艺术、动画帧

prompt.ts

提示词

伴侣行为描述

状态机设计:

┌─────────┐   idle    ┌─────────┐
│  Idle   │ ─────────►│  Think  │
│  (休息)  │           │  (思考)  │
└─────────┘           └────┬────┘
     ▲                     │
     │                working
     │                     ▼
     │               ┌─────────┐
     └───────────────│  Work   │
      done           │  (工作)  │
                     └─────────┘

📁 cli/ - 命令行接口

职责: Headless/Print 模式实现

文件

功能

print.ts

Headless 模式核心,单次查询执行

structuredIO.ts

结构化输入输出(JSON Schema)

remoteIO.ts

远程 I/O 处理

exit.ts

退出码管理

handlers/

各类处理器(auth、mcp、plugins)

transports/

传输层实现

print.ts 核心流程:

export async function runPrintMode(options: PrintOptions) {
  // 1. 解析输入
  const input = await parseInput(options)
  
  // 2. 初始化上下文
  const context = await createQueryContext(options)
  
  // 3. 执行查询(流式)
  const stream = await queryModelWithStreaming({
    messages: [{ role: 'user', content: input }],
    model: options.model,
    stream: true,
  })
  
  // 4. 输出结果
  for await (const chunk of stream) {
    if (chunk.type === 'content_block_delta') {
      process.stdout.write(chunk.delta.text)
    }
  }
  
  // 5. 清理
  await cleanup()
}

📁 commands/ - Slash 命令系统

职责: 实现 /help/login 等 Slash 命令

命令

文件

功能

/init

init.ts

初始化项目配置

/commit

commit.ts

Git 提交

/review

review.ts

代码审查

/status

statusline.tsx

状态显示

/install

install.tsx

安装插件

/config

(内置)

配置管理

命令注册模式:

interface Command {
  name: string
  aliases?: string[]
  description: string
  handler: (args: string[], context: CommandContext) => Promise<void>
  autocomplete?: (input: string) => string[]
}

// 命令注册
const commands: Command[] = [
  {
    name: 'commit',
    description: 'Create a git commit',
    handler: async (args, ctx) => {
      const message = args.join(' ')
      await createCommit(message, ctx)
    },
  },
]

📁 components/ - React UI 组件库

职责: 终端 UI 组件(Ink 框架)

组件

功能

App.tsx

根组件

REPL.tsx

REPL 主界面

Spinner.tsx

加载动画

ApproveApiKey.tsx

API Key 批准

AutoModeOptInDialog.tsx

Auto 模式选择

BridgeDialog.tsx

桥接对话框

BaseTextInput.tsx

文本输入

组件设计原则:

// 函数式组件 + Hooks
const Spinner: React.FC<SpinnerProps> = ({ mode, text }) => {
  const [frame, setFrame] = useState(0)
  
  useEffect(() => {
    const timer = setInterval(() => {
      setFrame(f => (f + 1) % FRAMES.length)
    }, 80)
    return () => clearInterval(timer)
  }, [])
  
  return (
    <Box>
      <Text color="cyan">{FRAMES[frame]}</Text>

      <Text> {text}</Text>

    </Box>

  )
}

📁 constants/ - 常量定义

职责: 全局常量集中管理

文件

内容

product.ts

产品信息(名称、版本、URL)

oauth.ts

OAuth 配置(客户端 ID、端口)

apiLimits.ts

API 限制(Token、速率)

betas.ts

Beta 功能开关

prompts.ts

系统提示词模板

errorIds.ts

错误 ID 枚举


📁 context/ - React Context

职责: 全局状态共享

Context

功能

notifications.tsx

通知管理

modalContext.tsx

模态框

overlayContext.tsx

覆盖层

mailbox.tsx

消息收发

voice.tsx

语音功能

fpsMetrics.tsx

性能指标


📁 coordinator/ - 协调器模式

职责: 多 Agent 协调(Leader-Worker)

// coordinatorMode.ts
export function isCoordinatorMode(): boolean {
  return process.env.CLAUDE_COORDINATOR_MODE === 'true'
}

// Leader 分发任务
export async function dispatchToWorkers(tasks: Task[]) {
  const workers = getAvailableWorkers()
  
  return Promise.all(tasks.map((task, i) => {
    const worker = workers[i % workers.length]
    return worker.execute(task)
  }))
}

📁 hooks/ - React Hooks

职责: 可复用逻辑封装

Hook

功能

useCanUseTool.tsx

工具权限检查

useArrowKeyHistory.tsx

箭头键历史

useBlink.ts

闪烁动画

useCancelRequest.ts

取消请求

useClipboardImageHint.ts

剪贴板提示


📁 ink/ - Ink 终端 UI 框架

职责: 封装 Ink 框架,实现终端 UI

文件

功能

ink.tsx

核心封装

Ansi.tsx

ANSI 处理

bidi.ts

双向文本

dom.ts

虚拟 DOM

focus.ts

焦点管理

frame.ts

帧渲染


📁 keybindings/ - 快捷键系统

职责: 可配置的快捷键绑定

文件

功能

defaultBindings.ts

默认绑定

parser.ts

快捷键解析

resolver.ts

快捷键解析

useKeybinding.ts

Hook


📁 memdir/ - 内存目录管理

职责: CLAUDE.md 智能扫描

文件

功能

memdir.ts

核心逻辑

findRelevantMemories.ts

查找相关记忆

memoryScan.ts

扫描算法

memoryAge.ts

老化机制

扫描策略:

当前目录/CLAUDE.md
    │
    ├── 父目录/CLAUDE.md (向上遍历)
    │
    └── ~/.claude/CLAUDE.md (用户全局)

📁 migrations/ - 数据迁移

职责: 版本升级时的配置迁移

// 迁移脚本模式
export async function migrateSonnet45ToSonnet46() {
  const settings = await loadSettings()
  
  if (settings.model === 'claude-sonnet-4-5') {
    settings.model = 'claude-sonnet-4-6'
    await saveSettings(settings)
    logEvent('migration_sonnet_45_to_46')
  }
}

📁 native-ts/ - 原生模块

职责: 性能关键路径的原生实现

模块

功能

color-diff/

颜色差异计算

file-index/

文件索引

yoga-layout/

布局引擎


📁 plugins/ - 插件系统

职责: 插件发现、加载、管理

interface Plugin {
  name: string
  version: string
  commands?: Command[]
  tools?: Tool[]
  hooks?: HookDefinition[]
  mcpServers?: MCPServerConfig[]
}

// 插件加载
export async function loadPlugin(pluginPath: string): Promise<Plugin> {
  const manifest = await readJson(join(pluginPath, 'manifest.json'))
  const plugin = await import(join(pluginPath, 'index.js'))
  
  return {
    name: manifest.name,
    commands: plugin.commands ?? [],
    tools: plugin.tools ?? [],
  }
}

📁 query/ - 查询引擎

职责: 核心查询处理

文件

功能

config.ts

查询配置

deps.ts

依赖管理

stopHooks.ts

停止钩子

tokenBudget.ts

Token 预算


📁 remote/ - 远程会话管理

职责: CCR 远程会话

文件

功能

RemoteSessionManager.ts

会话生命周期

remotePermissionBridge.ts

权限桥接

SessionsWebSocket.ts

WebSocket 管理


📁 screens/ - 页面组件

职责: 全屏页面

文件

功能

REPL.tsx

主界面

Doctor.tsx

诊断页面

ResumeConversation.tsx

恢复会话


📁 server/ - 服务器模式

职责: 直接连接服务

文件

功能

createDirectConnectSession.ts

创建会话

directConnectManager.ts

管理器


📁 skills/ - Skills 系统

职责: 可扩展技能包

文件

功能

loadSkillsDir.ts

加载技能

mcpSkillBuilders.ts

MCP 构建

bundled/

内置技能


📁 state/ - 状态管理

职责: 全局状态管理

// AppState 完整结构
export type AppState = {
  // 设置
  settings: SettingsJson
  verbose: boolean
  mainLoopModel: ModelSetting
  
  // 权限
  toolPermissionContext: ToolPermissionContext
  
  // MCP
  mcp: {
    clients: MCPServerConnection[]
    tools: Tool[]
    commands: Command[]
    resources: Record<string, ServerResource[]>
  }
  
  // Agent
  agentDefinitions: AgentDefinitionsResult
  agentNameRegistry: Map<string, AgentId>
  
  // 任务
  tasks: { [taskId: string]: TaskState }
  
  // 团队
  teamContext?: TeamContext
  
  // 更多...
}

// Store 实现
export class Store<State> {
  private state: State
  private listeners = new Set<(state: State) => void>()
  
  getState(): State { return this.state }
  
  setState(updater: (prev: State) => State): void {
    const next = updater(this.state)
    if (next !== this.state) {
      this.state = next
      this.listeners.forEach(l => l(this.state))
    }
  }
  
  subscribe(listener: (state: State) => void): () => void {
    this.listeners.add(listener)
    return () => this.listeners.delete(listener)
  }
}

📁 tasks/ - 任务系统

职责: 后台任务管理

目录

任务类型

LocalShellTask/

Shell 命令任务

LocalAgentTask/

Agent 任务

RemoteAgentTask/

远程 Agent

InProcessTeammateTask/

进程内队友

DreamTask/

Dream 任务

任务生命周期:

pending → running → completed/failed/killed
    │         │
    │         ├── 输出持久化
    │         └── 通知入队
    │
    └── 超时/取消 → killed

📁 types/ - 类型定义

职责: TypeScript 类型集中管理

文件

内容

message.ts

消息类型

permissions.ts

权限类型

tools.ts

工具类型

hooks.ts

Hooks 类型

ids.ts

ID 类型


📁 upstreamproxy/ - 上游代理

职责: CCR 上游代理支持

文件

功能

upstreamproxy.ts

代理核心

relay.ts

CONNECT 中继


📁 utils/ - 工具函数

职责: 通用工具函数(100+ 文件)

子目录

功能

permissions/

权限处理

settings/

设置管理

model/

模型相关

bash/

Bash 工具

shell/

Shell 提供者

telemetry/

遥测

git/

Git 操作

sandbox/

沙箱

plugins/

插件工具


📁 vim/ - Vim 模式

职责: Vim 风格键盘导航

文件

功能

motions.ts

移动命令

operators.ts

操作符

textObjects.ts

文本对象


📁 voice/ - 语音模式

职责: 语音输入/输出

文件

功能

voiceModeEnabled.ts

启用判断


工具系统详解

工具分类总览

工具 (40+)
├── 文件操作
│   ├── FileReadTool      # 读取文件
│   ├── FileEditTool      # 编辑文件
│   ├── FileWriteTool     # 写入文件
│   ├── GlobTool          # 文件搜索
│   └── GrepTool          # 内容搜索
│
├── Shell 执行
│   ├── BashTool          # Bash 命令
│   └── PowerShellTool    # PowerShell
│
├── 网络
│   ├── WebFetchTool      # 网页抓取
│   └── WebSearchTool     # 网页搜索
│
├── Agent/Task
│   ├── AgentTool         # 子代理
│   ├── TaskOutputTool    # 任务输出
│   └── TaskStopTool      # 停止任务
│
├── 协作
│   ├── TeamCreateTool    # 创建团队
│   ├── TeamDeleteTool    # 删除团队
│   └── SendMessageTool   # 发送消息
│
├── 计划
│   ├── EnterPlanModeTool
│   └── ExitPlanModeTool
│
├── MCP
│   ├── MCPTool
│   ├── ListMcpResourcesTool
│   └── ReadMcpResourceTool
│
└── 其他
    ├── SkillTool
    ├── TodoWriteTool
    ├── ConfigTool
    └── ...

BashTool 深入分析

// BashTool.tsx 核心实现
export const BashTool = buildTool({
  name: 'Bash',
  inputSchema: z.object({
    command: z.string(),
    timeout: z.number().optional(),
    description: z.string().optional(),
  }),
  
  async call(input, context, canUseTool, parentMessage, onProgress) {
    const { command, timeout } = input
    
    // 1. 安全解析
    const parsed = parseForSecurity(command)
    
    // 2. 只读检查
    const isReadOnly = checkReadOnlyConstraints(command)
    
    // 3. 沙箱判断
    const useSandbox = shouldUseSandbox(command, context)
    
    // 4. 执行
    const result = await exec(command, {
      timeout: timeout ?? getDefaultTimeoutMs(),
      sandbox: useSandbox,
      cwd: getCwd(),
    })
    
    // 5. 大输出持久化
    if (result.stdout.length > PREVIEW_SIZE_BYTES) {
      const outputPath = getTaskOutputPath(taskId)
      await writeTextContent(outputPath, result.stdout)
      return {
        data: {
          output: generatePreview(result.stdout),
          outputPath,
        }
      }
    }
    
    return { data: { output: result.stdout } }
  },
  
  isSearchOrReadCommand(input) {
    return isSearchOrReadBashCommand(input.command)
  },
})

FileEditTool 深入分析

// FileEditTool.ts 核心实现
export const FileEditTool = buildTool({
  name: 'Edit',
  
  async call(input, context) {
    const { file_path, old_string, new_string } = input
    
    // 1. 读取文件
    const content = await readFile(file_path)
    
    // 2. 查找并替换
    const newContent = content.replace(old_string, new_string)
    
    // 3. 写入
    await writeFile(file_path, newContent)
    
    // 4. 返回 diff
    return {
      data: {
        path: file_path,
        diff: generateDiff(content, newContent),
      }
    }
  },
  
  async checkPermissions(input, context) {
    return checkWritePermissionForTool(input.file_path, context)
  },
})

WebSearchTool 深入分析

// WebSearchTool.ts 核心实现
export const WebSearchTool = buildTool({
  name: 'WebSearch',
  
  async call(input, context) {
    const { query, allowed_domains, blocked_domains } = input
    
    // 使用 Claude 内置的 Web Search 工具
    const toolSchema = {
      type: 'web_search_20250305',
      name: 'web_search',
      allowed_domains,
      blocked_domains,
      max_uses: 8,
    }
    
    const result = await queryModelWithStreaming({
      tools: [toolSchema],
      messages: [{ role: 'user', content: query }],
    })
    
    return parseSearchResults(result)
  },
})

服务模块详解

📁 services/mcp/ - MCP 协议实现

职责: MCP 客户端、工具发现、服务器管理

文件

功能

client.ts

MCP 客户端实现

types.ts

类型定义

config.ts

配置管理

auth.ts

认证

headersHelper.ts

Headers 处理

MCP 客户端核心:

// client.ts
export async function connectMCPServer(config: MCPServerConfig): Promise<MCPServerConnection> {
  // 1. 创建传输层
  let transport: Transport
  switch (config.type) {
    case 'stdio':
      transport = new StdioClientTransport({
        command: config.command,
        args: config.args,
        env: { ...process.env, ...config.env },
      })
      break
    case 'sse':
      transport = new SSEClientTransport(new URL(config.url))
      break
    case 'http':
      transport = new StreamableHTTPClientTransport(new URL(config.url))
      break
  }
  
  // 2. 创建客户端
  const client = new Client({ name: 'claude-code', version: VERSION }, {
    capabilities: { tools: {}, resources: {} },
  })
  
  // 3. 连接
  await client.connect(transport)
  
  // 4. 发现工具
  const { tools } = await client.request(ListToolsResultSchema, {})
  
  // 5. 转换为 Tool 对象
  const mcpTools = tools.map(tool => createMCPTool(client, tool))
  
  return { client, tools: mcpTools, config }
}

📁 services/analytics/ - 分析遥测

职责: GrowthBook 集成、事件追踪

文件

功能

growthbook.ts

GrowthBook SDK

index.ts

分析入口

firstPartyEventLogger.ts

1P 事件日志

GrowthBook 集成:

// growthbook.ts
export async function initializeGrowthBook(user: UserAttributes) {
  const client = new GrowthBook({
    apiHost: 'https://cdn.growthbook.io',
    clientKey: getGrowthBookClientKey(),
    attributes: {
      id: user.id,
      sessionId: getSessionId(),
      platform: process.platform,
      userType: user.userType,
    },
    trackingCallback: (experiment, result) => {
      logEvent('experiment_viewed', {
        experimentId: experiment.key,
        variationId: result.variationId,
      })
    },
  })
  
  await client.loadFeatures()
  return client
}

// 功能开关检查
export function isFeatureEnabled(featureKey: string): boolean {
  return client?.isOn(featureKey) ?? false
}

// 动态配置获取
export function getFeatureValue<T>(key: string, defaultValue: T): T {
  return client?.getFeatureValue(key, defaultValue) ?? defaultValue
}

📁 services/api/ - API 客户端

职责: Anthropic API 封装

文件

功能

claude.ts

Claude API 客户端

client.ts

HTTP 客户端

usage.ts

用量追踪

errors.ts

错误处理

logging.ts

日志记录

API 调用核心:

// claude.ts
export async function queryModelWithStreaming(options: QueryOptions) {
  const { messages, model, tools, stream } = options
  
  const client = new Anthropic({
    apiKey: await getApiKey(),
    baseURL: getApiBaseUrl(),
  })
  
  const response = await client.messages.create({
    model: model ?? 'claude-sonnet-4-20250514',
    max_tokens: 8192,
    messages,
    tools,
    stream,
  })
  
  if (stream) {
    return response as AsyncIterable<MessageStreamEvent>
  }
  
  return response as Message
}

📁 services/lsp/ - LSP 集成

职责: 语言服务器协议集成

文件

功能

manager.ts

LSP 管理器

client.ts

LSP 客户端

types.ts

类型定义


📁 services/oauth/ - OAuth 客户端

职责: OAuth 认证流程

文件

功能

client.ts

OAuth 客户端

types.ts

类型定义


📁 services/remoteManagedSettings/ - 远程管理设置

职责: 企业远程配置管理

文件

功能

index.ts

入口

syncCacheState.ts

同步缓存


设计模式与最佳实践

1. 模块化工具系统

模式: Builder + Strategy

// 工具定义
const MyTool = buildTool({
  name: 'MyTool',
  inputSchema: z.object({ input: z.string() }),
  
  async call(input, context) {
    // 实现逻辑
    return { data: 'result' }
  },
  
  checkPermissions(input, context) {
    return { behavior: 'allow' }
  },
})

// buildTool 自动填充默认值
// - isEnabled: true
// - isConcurrencySafe: false
// - isReadOnly: false

2. 状态管理模式

模式: Flux-like 单向数据流

// Store
const store = new Store<AppState>(getDefaultAppState())

// 读取
const state = store.getState()

// 更新(不可变)
store.setState(prev => ({
  ...prev,
  tasks: {
    ...prev.tasks,
    [taskId]: { ...prev.tasks[taskId], status: 'completed' },
  },
}))

// 订阅
const unsubscribe = store.subscribe(state => {
  console.log('State updated:', state)
})

3. 权限系统模式

模式: Chain of Responsibility

// 权限检查链
async function checkPermission(tool: Tool, input: unknown, context: Context) {
  // 1. 工具特定检查
  const toolResult = await tool.checkPermissions(input, context)
  if (toolResult.behavior !== 'allow') return toolResult
  
  // 2. 全局拒绝规则
  if (matchDenyRules(tool.name, context)) {
    return { behavior: 'deny' }
  }
  
  // 3. 全局允许规则
  if (matchAllowRules(tool.name, context)) {
    return { behavior: 'allow' }
  }
  
  // 4. 需要用户确认
  return { behavior: 'ask' }
}

4. 任务系统模式

模式: State Machine

// 任务状态机
type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'killed'

const transitions: Record<TaskStatus, TaskStatus[]> = {
  pending: ['running', 'killed'],
  running: ['completed', 'failed', 'killed'],
  completed: [],  // 终态
  failed: [],     // 终态
  killed: [],     // 终态
}

function canTransition(from: TaskStatus, to: TaskStatus): boolean {
  return transitions[from].includes(to)
}

5. MCP 协议模式

模式: Adapter

// MCP 工具适配器
function createMCPTool(client: MCPClient, toolDef: MCPToolDefinition): Tool {
  return {
    name: `mcp__${toolDef.name}`,
    inputSchema: convertMCPSchemaToZod(toolDef.inputSchema),
    
    async call(input, context) {
      const result = await client.callTool(toolDef.name, input)
      return { data: result.content }
    },
    
    isMcp: true,
    mcpInfo: { toolName: toolDef.name },
  }
}

6. 缓存策略

模式: Memoization + LRU

// 带缓存的函数
export const getGitStatus = memoize(async () => {
  const [branch, status] = await Promise.all([
    getBranch(),
    execFileNoThrow('git', ['status', '--short']),
  ])
  return { branch, status }
})

// LRU 缓存
const cache = new LRUCache<string, FileState>({
  max: 1000,
  maxAge: 1000 * 60 * 5,  // 5 分钟
})

export const getFileState = memoizeWithLRU(
  (path: string) => readFileState(path),
  path => path,
  50,  // 最大缓存数量
)

7. 并发控制

模式: Semaphore + Queue

// 并发限制
const MAX_CONCURRENT_TOOLS = 10
const semaphore = new Semaphore(MAX_CONCURRENT_TOOLS)

async function executeTool(tool: Tool, input: unknown) {
  await semaphore.acquire()
  try {
    return await tool.call(input, context)
  } finally {
    semaphore.release()
  }
}

8. 错误处理

模式: Result Type

// 结果类型
type Result<T, E = Error> =
  | { ok: true; value: T }
  | { ok: false; error: E }

async function safeCall<T>(fn: () => Promise<T>): Promise<Result<T>> {
  try {
    const value = await fn()
    return { ok: true, value }
  } catch (error) {
    return { ok: false, error: toError(error) }
  }
}

如何基于源码搭建自己的 Claude Code

方案一:Fork 修改

步骤:

  1. 获取源码
  1. 安装依赖
bun install
  1. 修改配置
    • src/constants/product.ts - 产品名称
    • src/constants/oauth.ts - OAuth 配置
    • src/utils/auth.ts - 认证逻辑
  1. 添加自定义工具
// src/tools/MyTool/MyTool.ts
import { buildTool } from '../Tool.js'
import { z } from 'zod/v4'

export const MyTool = buildTool({
  name: 'MyTool',
  inputSchema: z.object({
    input: z.string().describe('Input parameter'),
  }),
  
  async call(input, context) {
    // 实现你的逻辑
    return { data: 'result' }
  },
  
  async description(input) {
    return 'My custom tool description'
  },
})
  1. 注册工具
// src/tools.ts
import { MyTool } from './tools/MyTool/MyTool.js'

export function getAllBaseTools(): Tools {
  return [
    ...existingTools,
    MyTool,
  ]
}
  1. 构建运行
bun run build
bun run start

方案二:从零开始构建

核心架构:

your-claude-code/
├── src/
│   ├── index.ts              # 入口
│   ├── cli.ts                # CLI 解析
│   ├── agent/
│   │   ├── engine.ts         # 核心引擎
│   │   ├── context.ts        # 上下文
│   │   └── message.ts        # 消息处理
│   ├── tools/
│   │   ├── base.ts           # 工具基类
│   │   ├── registry.ts       # 工具注册
│   │   └── implementations/
│   ├── mcp/
│   │   ├── client.ts
│   │   └── server.ts
│   ├── permissions/
│   │   ├── manager.ts
│   │   └── rules.ts
│   └── state/
│       ├── store.ts
│       └── types.ts
├── package.json
└── tsconfig.json

核心实现代码:

// 1. 工具系统 (tools/base.ts)
export interface Tool<Input, Output> {
  name: string
  inputSchema: z.ZodType<Input>
  call(input: Input, context: Context): Promise<Output>
  checkPermissions?(input: Input): Promise<PermissionResult>
}

// 2. 工具注册 (tools/registry.ts)
export class ToolRegistry {
  private tools = new Map<string, Tool>()
  
  register(tool: Tool) {
    this.tools.set(tool.name, tool)
  }
  
  get(name: string) {
    return this.tools.get(name)
  }
  
  list() {
    return Array.from(this.tools.values())
  }
}

// 3. Agent 引擎 (agent/engine.ts)
export class AgentEngine {
  constructor(
    private client: Anthropic,
    private tools: ToolRegistry,
    private permissions: PermissionManager,
  ) {}
  
  async query(messages: Message[]): Promise<Response> {
    while (true) {
      const response = await this.client.messages.create({
        model: 'claude-sonnet-4',
        messages,
        tools: this.getToolDefinitions(),
      })
      
      if (response.stop_reason === 'tool_use') {
        const results = await Promise.all(
          response.content
            .filter(block => block.type === 'tool_use')
            .map(block => this.executeTool(block))
        )
        
        messages.push(
          { role: 'assistant', content: response.content },
          { role: 'user', content: results }
        )
        continue
      }
      
      return response
    }
  }
  
  private async executeTool(block: ToolUseBlock) {
    const tool = this.tools.get(block.name)
    const permission = await this.permissions.check(tool, block.input)
    
    if (permission.denied) {
      return { type: 'tool_result', tool_use_id: block.id, content: 'Denied' }
    }
    
    const result = await tool.call(block.input, this.context)
    return { type: 'tool_result', tool_use_id: block.id, content: result }
  }
}

// 4. 权限管理 (permissions/manager.ts)
export class PermissionManager {
  private rules: PermissionRule[] = []
  
  addRule(rule: PermissionRule) {
    this.rules.push(rule)
  }
  
  async check(tool: Tool, input: unknown): Promise<PermissionResult> {
    for (const rule of this.rules) {
      if (rule.matches(tool.name, input)) {
        return { denied: rule.behavior === 'deny', reason: rule.reason }
      }
    }
    return { denied: false, askUser: true }
  }
}

// 5. MCP 客户端 (mcp/client.ts)
export class MCPClient {
  async connect(config: MCPServerConfig) {
    const transport = this.createTransport(config)
    const client = new MCPClientSDK({ name: 'my-claude-code', version: '1.0' })
    await client.connect(transport)
    
    const { tools } = await client.listTools()
    return this.convertToTools(tools)
  }
  
  private createTransport(config: MCPServerConfig): Transport {
    switch (config.type) {
      case 'stdio':
        return new StdioClientTransport({
          command: config.command,
          args: config.args,
        })
      case 'http':
        return new StreamableHTTPClientTransport(new URL(config.url))
      default:
        throw new Error(`Unknown transport: ${config.type}`)
    }
  }
}

关键决策点

决策点

选项

建议

模型

Anthropic API / 兼容 API

Anthropic API 质量最高

UI

终端 (Ink) / Web / Desktop

终端最轻量,Web 最通用

认证

API Key / OAuth / 自定义

API Key 最简单,OAuth 最安全

存储

本地文件 / 云端同步

本地文件最简单

MCP

支持 / 不支持

支持可无限扩展


总结

Claude Code 是一个设计精良的 AI 编程助手,其核心设计亮点包括:

  1. 模块化架构: 清晰的职责划分,易于扩展
  1. 工具系统: buildTool 模式,默认值 + 覆盖
  1. 权限系统: 多层级检查,安全可控
  1. Agent 系统: 支持子代理、团队协作
  1. MCP 协议: 动态加载外部工具
  1. 性能优化: 并行预取、懒加载、死代码消除

通过深入分析源码,可以学习到:

  • 大型 TypeScript 项目的组织方式
  • CLI 工具的设计模式
  • 终端 UI 的实现技巧
  • AI Agent 的架构设计
  • 权限系统的实现方案

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐