Claude Code 是一个基于 TypeScript 开发的 AI 编程助手 CLI 工具,由 Anthropic 开发。它提供了与 Claude AI 模型的交互界面,支持代码编辑、文件操作、命令执行、Web 搜索等功能。
- 语言: TypeScript
- 运行时: Bun (通过
bun:bundle特性) - 架构模式: 模块化架构 + React Ink 终端 UI
- 核心功能: AI 对话、代码编辑、工具调用、权限管理
┌─────────────────────────────────────────────────────────────┐
│ 用户界面层 (UI Layer) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ REPL.tsx │ │ Commands │ │ Ink Components │ │
│ │ (主界面) │ │ (命令处理) │ │ (Box, Text, etc) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 应用逻辑层 (Application Layer) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ QueryEngine │ │ Tools │ │ Commands │ │
│ │ (查询引擎) │ │ (工具系统) │ │ (命令注册中心) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 服务层 (Service Layer) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ API Client │ │ MCP │ │ Analytics │ │
│ │ (API客户端) │ │ (模型控制协议)│ │ (分析统计) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 数据层 (Data Layer) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ AppState │ │ Messages │ │ Session Storage │ │
│ │ (应用状态) │ │ (消息模型) │ │ (会话存储) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
- 模块化设计: 每个功能模块职责单一,通过清晰的接口进行通信
- 类型安全: 大量使用 TypeScript 类型系统,核心类型定义在
src/types/目录 - 插件化架构: 支持 Skills、Plugins、MCP 服务器的动态扩展
- 权限控制: 细粒度的工具权限管理系统
- 状态管理: 集中式状态管理,支持持久化和恢复
文件位置: src/QueryEngine.ts
QueryEngine 是对话查询生命周期和会话状态的管理中心。它负责:
- 管理对话消息流
- 处理用户输入和 AI 响应
- 工具调用协调
- 会话状态持久化
export class QueryEngine {
private config: QueryEngineConfig
private mutableMessages: Message[]
private abortController: AbortController
private permissionDenials: SDKPermissionDenial[]
private totalUsage: NonNullableUsage
private discoveredSkillNames = new Set<string>()
private loadedNestedMemoryPaths = new Set<string>()
async *submitMessage(
prompt: string | ContentBlockParam[],
options?: { uuid?: string; isMeta?: boolean }
): AsyncGenerator<SDKMessage, void, unknown>
interrupt(): void
getMessages(): readonly Message[]
getReadFileState(): FileStateCache
}- 异步生成器模式: 使用
AsyncGenerator实现流式响应 - 状态隔离: 每个 QueryEngine 实例管理独立的对话状态
- 工具包装器:
wrappedCanUseTool拦截权限检查 - 消息生命周期管理: 支持消息压缩、转录、恢复
文件位置: src/Tool.ts, src/tools.ts
export type Tool = {
name: string // 工具名称
description: string // 工具描述
inputJSONSchema: ToolInputJSONSchema // 输入参数 JSON Schema
isEnabled: () => boolean // 是否启用
isReadOnly: boolean // 是否只读
needsPermissions: boolean // 是否需要权限
// 核心执行方法
call(
input: Record<string, unknown>,
context: ToolUseContext,
toolUseID: string,
assistantMessage: AssistantMessage
): AsyncGenerator<ToolYield, void, unknown>
}| 工具名称 | 功能描述 | 文件位置 |
|---|---|---|
| BashTool | 执行 Bash 命令 | tools/BashTool/BashTool.ts |
| FileReadTool | 读取文件内容 | tools/FileReadTool/FileReadTool.ts |
| FileEditTool | 编辑文件 | tools/FileEditTool/FileEditTool.ts |
| FileWriteTool | 写入文件 | tools/FileWriteTool/FileWriteTool.ts |
| GlobTool | 文件模式匹配 | tools/GlobTool/GlobTool.ts |
| GrepTool | 文本搜索 | tools/GrepTool/GrepTool.ts |
| WebSearchTool | Web 搜索 | tools/WebSearchTool/WebSearchTool.ts |
| WebFetchTool | 网页获取 | tools/WebFetchTool/WebFetchTool.ts |
| AgentTool | AI Agent 调用 | tools/AgentTool/AgentTool.ts |
| TaskCreateTool | 任务创建 | tools/TaskCreateTool/TaskCreateTool.ts |
| TodoWriteTool | 待办事项 | tools/TodoWriteTool/TodoWriteTool.ts |
| LSPTool | LSP 服务 | tools/LSPTool/LSPTool.ts |
用户输入 → QueryEngine → 解析工具调用 → 权限检查 → 工具执行 → 结果返回
↓
canUseTool (权限系统)
↓
Tool.call (异步生成器)
↓
产出 ToolYield 事件
文件位置: src/bridge/
Bridge 模块实现与外部系统的桥接通信,支持远程会话、WebSocket 连接、多会话管理。
| 文件 | 职责 |
|---|---|
bridgeMain.ts |
桥接主循环,会话生命周期管理 |
bridgeApi.ts |
桥接 API 客户端 |
bridgeMessaging.ts |
消息传递机制 |
bridgeUI.ts |
桥接 UI 状态管理 |
sessionRunner.ts |
会话运行器 |
jwtUtils.ts |
JWT 令牌管理 |
types.ts |
桥接类型定义 |
// 桥接配置
export type BridgeConfig = {
environmentId: string
environmentSecret: string
apiUrl: string
pollIntervalMs: number
}
// 会话句柄
export type SessionHandle = {
sessionId: string
process: ChildProcess
dir: string
abort: () => void
}
// 主循环
export async function runBridgeLoop(
config: BridgeConfig,
environmentId: string,
environmentSecret: string,
api: BridgeApiClient,
spawner: SessionSpawner,
logger: BridgeLogger,
signal: AbortSignal
): Promise<void>文件位置: src/commands.ts, src/commands/
export type Command = CommandBase &
(PromptCommand | LocalCommand | LocalJSXCommand)
type CommandBase = {
name: string
description: string
aliases?: string[]
isEnabled?: () => boolean
isHidden?: boolean
availability?: CommandAvailability[]
// ...
}
export type PromptCommand = {
type: 'prompt'
progressMessage: string
getPromptForCommand(
args: string,
context: ToolUseContext
): Promise<ContentBlockParam[]>
}
export type LocalJSXCommand = {
type: 'local-jsx'
load: () => Promise<LocalJSXCommandModule>
}- PromptCommand: 生成提示词,发送给 AI 处理
- LocalCommand: 本地执行,不经过 AI
- LocalJSXCommand: 本地执行,返回 React 组件渲染
| 命令 | 类型 | 功能 |
|---|---|---|
/commit |
prompt | 提交代码 |
/doctor |
local-jsx | 诊断检查 |
/help |
local-jsx | 帮助信息 |
/memory |
local-jsx | 内存管理 |
/model |
local-jsx | 模型切换 |
/cost |
local-jsx | 成本统计 |
/exit |
local-jsx | 退出程序 |
文件位置: src/services/
// API 客户端创建
export async function getAnthropicClient({
apiKey,
maxRetries,
model,
fetchOverride,
source,
}: {
apiKey?: string
maxRetries: number
model?: string
fetchOverride?: ClientOptions['fetch']
source?: string
}): Promise<Anthropic>支持多种 API 提供商:
- Direct API (api.anthropic.com)
- AWS Bedrock
- Google Vertex AI
- Azure Foundry
MCP (Model Control Protocol) 服务实现与外部 MCP 服务器的通信:
export type MCPServerConnection = {
name: string
client: Client
tools: Tool[]
resources: ServerResource[]
config: McpServerConfig
}- GrowthBook 特性开关
- Datadog 指标上报
- 事件日志记录
文件位置: src/ink/
Ink 是一个基于 React 的终端 UI 渲染引擎,实现了:
- 虚拟 DOM: React 组件在终端的渲染
- 布局引擎: 基于 Yoga 的 Flexbox 布局
- 事件系统: 键盘输入、焦点管理
- 样式系统: ANSI 颜色、文本样式
// 布局节点
export class InkNode {
id: number
type: 'root' | 'text' | 'box'
props: Props
children: InkNode[]
yogaNode: YogaNode
}
// 渲染器
export function renderToScreen(
output: Output,
screen: Screen
): void
// 输入处理
export function useInput(
handler: (input: string, key: Key) => void
): voidApp (应用根组件)
├── Box (容器)
│ ├── Text (文本)
│ ├── Messages (消息列表)
│ │ └── Message (单个消息)
│ ├── PromptInput (输入框)
│ └── StatusLine (状态栏)
└── Modal (模态框)
文件位置: src/state/
export type AppState = DeepImmutable<{
settings: SettingsJson // 用户设置
verbose: boolean // 详细模式
mainLoopModel: ModelSetting // 主循环模型
toolPermissionContext: ToolPermissionContext // 权限上下文
// UI 状态
expandedView: 'none' | 'tasks' | 'teammates'
footerSelection: FooterItem | null
// 桥接状态
replBridgeEnabled: boolean
replBridgeConnected: boolean
replBridgeSessionActive: boolean
// 任务状态
tasks: TaskState[]
// 文件历史
fileHistory: FileHistoryState
// 归因状态
attribution: AttributionState
}>export type Store<T> = {
getState: () => T
setState: (updater: (prev: T) => T) => void
subscribe: (callback: (state: T) => void) => () => void
}
export function createStore<T>(initialState: T): Store<T>文件位置: src/utils/permissions/, src/types/permissions.ts
export type PermissionMode =
| 'acceptEdits' // 自动接受编辑
| 'bypassPermissions' // 绕过权限
| 'default' // 默认模式
| 'dontAsk' // 不询问
| 'plan' // 计划模式
| 'auto' // 自动模式 (特性开关控制)
| 'bubble' // 气泡模式工具调用请求
↓
检查 PermissionMode
↓
检查 PermissionRules (alwaysAllow/alwaysDeny/alwaysAsk)
↓
检查 Classifier (自动模式)
↓
显示权限对话框 (如果需要)
↓
返回 PermissionResult
export type PermissionRule = {
source: PermissionRuleSource
ruleBehavior: PermissionBehavior // 'allow' | 'deny' | 'ask'
ruleValue: PermissionRuleValue // { toolName: string, ruleContent?: string }
}┌──────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────┐
│ 用户输入 │ → │ processUserInput │ → │ QueryEngine │ → │ API调用 │
└──────────┘ └─────────────┘ └──────────────┘ └──────────┘
↓
┌──────────────┐
│ 工具调用决策 │
└──────────────┘
↓
┌──────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────┐
│ 用户展示 │ ← │ Ink渲染 │ ← │ 消息格式化 │ ← │ 工具执行 │
└──────────┘ └─────────────┘ └──────────────┘ └──────────┘
AI 响应包含 tool_use
↓
解析 tool_use 块
↓
canUseTool 权限检查
↓
┌─────┴─────┐
↓ ↓
允许 拒绝
↓ ↓
执行工具 返回拒绝结果
↓
产出 ToolYield
↓
格式化为 tool_result
↓
发送回 AI
Skills 是用户可定义的提示词模板:
// Skill 定义
export type Skill = {
name: string
description: string
prompt: string
paths?: string[] // 适用的文件路径模式
}Plugins 提供更复杂的扩展能力:
export type PluginManifest = {
name: string
version: string
hooks?: HookDefinition[]
commands?: CommandDefinition[]
}MCP (Model Control Protocol) 允许连接外部工具服务器:
export type McpServerConfig = {
name: string
command: string
args?: string[]
env?: Record<string, string>
}- 性能: 比 Node.js 更快的启动和执行速度
- 内置功能: 原生支持 TypeScript、SQLite、WebSocket
- 打包:
bun:bundle特性支持条件编译 - 兼容性: 支持大部分 Node.js API
- 声明式 UI: 使用 React 组件描述终端界面
- 状态管理: 利用 React 的状态管理功能
- 生态系统: 复用 React 生态的工具和模式
- 可测试性: 组件化便于单元测试
QueryEngine 和工具调用都使用 AsyncGenerator:
async *submitMessage(): AsyncGenerator<SDKMessage, void, unknown>优点:
- 流式处理:可以逐步产出结果
- 可中断:通过 AbortSignal 随时取消
- 内存友好:不需要等待所有结果
src/
├── bridge/ # 桥接系统(远程会话、WebSocket)
├── buddy/ # 伙伴精灵(Companion)
├── cli/ # CLI 传输层(SSE、WebSocket)
├── commands/ # 命令实现(50+ 个命令)
├── components/ # React 组件
├── constants/ # 常量定义
├── context/ # React Context
├── coordinator/ # 协调器模式
├── entrypoints/ # 入口点(CLI、MCP、SDK)
├── hooks/ # React Hooks
├── ink/ # Ink 终端渲染引擎
├── keybindings/ # 键盘绑定
├── memdir/ # 内存目录管理
├── plugins/ # 插件系统
├── query/ # 查询配置
├── schemas/ # Zod 模式定义
├── screens/ # 屏幕组件
├── server/ # 服务器类型
├── services/ # 服务层
│ ├── analytics/ # 分析统计
│ ├── api/ # API 客户端
│ ├── compact/ # 消息压缩
│ ├── lsp/ # LSP 服务
│ └── mcp/ # MCP 服务
├── skills/ # 技能系统
├── state/ # 状态管理
├── tasks/ # 任务系统
├── tools/ # 工具实现(30+ 个工具)
├── types/ # 类型定义
├── utils/ # 工具函数
└── vim/ # Vim 模式
Claude Code 是一个架构清晰、设计精良的 AI 编程助手。其核心设计亮点包括:
- 模块化架构: 清晰的职责划分,易于维护和扩展
- 类型安全: 全面的 TypeScript 类型覆盖
- 流式处理: 异步生成器模式实现流式响应
- 权限控制: 细粒度的权限管理系统
- 可扩展性: Skills、Plugins、MCP 三层扩展机制
- 终端 UI: React Ink 提供现代化的终端交互体验
该项目展示了如何构建一个生产级的 AI 助手 CLI 工具,值得深入学习其架构设计和技术实现。