1. 项目概述
本项目是 Anthropic 官方 AI 编程命令行工具Claude Code 的完整源码(package.json 中"name": "claude-code",版本1.0.0)。
src/ 目录下共约996 个源文件(930 个.ts + 66 个.tsx),是一个完整的生产级 Agentic(智能体)CLI 应用。
源码保留了大量 Anthropic 内部标识:
feature('XXX')构建宏(bun:bundle)用于编译期死代码消除// Ant-only标注的内部功能tengu_前缀的分析埋点事件对 Statsig/GrowthBook 实验平台的引用
这说明这是从官方发布包还原出来的源码,具有极高的参考价值。
2. 技术栈
| 语言 | strict: true,ESNext 模块,moduleResolution: bundler) |
| 运行时 | Bunbun:bundle 的feature() 编译期宏 |
| UI 框架 | React 19jsx: react-jsx) |
| 终端渲染 | 自研 Inksrc/ink/)—— 把 React 组件树渲染到终端 TTY |
| CLI 解析 | @commander-js/extra-typings |
| AI SDK | @anthropic-ai/sdk |
| AI 协议 | @modelcontextprotocol/sdk |
| Schema 校验 | zod |
| A/B 实验 | @growthbook/growthbook |
| 工具库 | lodash-eschalk(着色)、execa(子进程)、lru-cache、ignore(gitignore 解析)、proper-lockfile、jsonc-parser、env-paths |
3. 目录结构
src/├── entrypoints/ # 入口点(cli.tsx、mcp.ts、sdk/)├── main.tsx # 主控制器,全局初始化├── query.ts # ⭐ Agentic 主循环(项目心脏)├── Tool.ts # 工具统一接口定义├── tools.ts # 工具注册与组装│├── tools/ # 40+ 内置工具实现(约 184 文件)│ ├── AgentTool/ # 子智能体(递归调用 query)│ ├── BashTool/ # Shell 命令执行│ ├── FileReadTool/ # 文件读取│ ├── FileEditTool/ # 文件编辑│ ├── FileWriteTool/ # 文件写入│ ├── GrepTool/ # 内容搜索│ ├── GlobTool/ # 文件模式匹配│ ├── WebFetchTool/ # 网页抓取│ ├── WebSearchTool/ # 网络搜索│ ├── TodoWriteTool/ # 任务管理│ ├── TeamCreateTool/ # 多智能体团队│ ├── TaskCreate/ # 异步任务│ ├── PowerShellTool/ # PowerShell(Windows)│ ├── REPLTool/ # 安全沙箱执行│ └── ...│├── services/ # 服务层(约 130 文件)│ ├── api/ # Claude API 封装、重试、错误处理│ ├── mcp/ # MCP 客户端与官方注册表│ ├── compact/ # 多层上下文压缩策略│ ├── analytics/ # 埋点 + GrowthBook 实验│ ├── policyLimits/ # 企业策略控制│ └── SessionMemory/ # 会话记忆│├── components/ # React UI 组件(约 389 文件)├── hooks/ # React Hooks(约 104 文件)├── ink/ # 自研终端渲染引擎(约 96 文件)│ ├── reconciler.ts # React Fiber → 终端 DOM│ ├── renderer.ts # 节点渲染│ ├── dom.ts # 自定义 DOM 结构│ ├── styles.ts # 样式系统│ └── termio/ # 终端 IO 层│├── commands/ # 斜杠命令(约 207 文件)├── utils/ # 工具库(约 564 文件)├── constants/ # 常量(prompts.ts 53KB)├── context/ # React Context├── state/ # 应用状态├── types/ # TypeScript 类型定义├── bridge/ # 远程控制桥接(31 文件)├── coordinator/ # 多智能体协调器├── bootstrap/ # 启动状态管理└── skills/ # 技能系统4. 核心架构
cli.tsx(引导) ↓main.tsx(全局初始化:配置、鉴权、GrowthBook、MCP、插件) ↓replLauncher.tsx(启动交互式 REPL) ↓┌──────────── query.ts(Agentic 主循环)─────────────┐│ ││ 上下文压缩 → 调用模型 API → 解析 tool_use ││ ↑ ↓ ↓ ││ 工具结果回灌 ← 执行工具 ← 工具调度编排 ││ ↓ ││ AgentTool(子智能体,递归 query) │└──────────────────────────────────────────────────────┘ ↓ink/(React 组件树 → 终端 TTY 实时渲染)5. 核心模块详解
5.1 引导入口 —cli.tsx
职责:极致优化的快速路径引导器,所有 import 均为动态加载,最小化冷启动开销。
快速路径分发表:
--version-v | 零依赖 | |
--dump-system-prompt | ||
--claude-in-chrome-mcp | ||
--computer-use-mcp | ||
--daemon-worker | ||
remote-controlbridge | ||
daemon | ||
ps/logs/attach/kill--bg | ||
new/list/reply | ||
environment-runner | ||
self-hosted-runner | ||
| main.tsx |
// 示例:--version 零依赖快速路径if (args.length === 1 && (args[0] === '--version' || args[0] === '-v')) {console.log(`${VERSION} (Claude Code)`)return}5.2 主控制器 —main.tsx
职责:完成所有全局初始化,最终启动 REPL 交互界面。
初始化流程(启动时序):
1. profileCheckpoint('main_tsx_entry') ← 性能打点2. startMdmRawRead() ← 并行拉取 MDM 配置3. startKeychainPrefetch() ← 并行预取 Keychain4. enableConfigs() ← 加载本地配置文件5. initializeGrowthBook() ← 初始化 A/B 实验6. loadPolicyLimits() ← 加载企业策略7. getMcpToolsCommandsAndResources() ← 连接 MCP 服务器8. initBundledSkills() + initBuiltinPlugins() ← 技能和插件9. getTools(permissionContext) ← 组装工具列表10. launchRepl() / launchAssistant() ← 启动 REPL预取并行化是 main.tsx 的重要优化手段——MDM、Keychain、GrowthBook、AWS 凭证、fast mode 状态等全部在初始化阶段并行触发,利用启动期间的等待时间。
5.3 Agentic 主循环 —query.ts ⭐
这是整个项目的"心脏",一个async function* query() 异步生成器,驱动整个对话→工具→回灌的递归循环。
状态机设计
type State = { messages: Message[] toolUseContext: ToolUseContext autoCompactTracking: AutoCompactTrackingState | undefined maxOutputTokensRecoveryCount: number hasAttemptedReactiveCompact: boolean maxOutputTokensOverride: number | undefined pendingToolUseSummary: Promise<ToolUseSummaryMessage | null> | undefined stopHookActive: boolean | undefined turnCount: number transition: Continue | undefined// 记录上次 continue 的原因}每次循环迭代用不可变state = {...} 替换,transition.reason 追踪循环延续原因:
transition.reason | |
|---|---|
next_turn | |
reactive_compact_retry | |
collapse_drain_retry | |
max_output_tokens_escalate | |
max_output_tokens_recovery | |
stop_hook_blocking | |
token_budget_continuation |
单次迭代管线
┌─────────────────────── while(true) ────────────────────────────┐│ ││ 1. 工具结果体积预算控制 applyToolResultBudget() ││ 2. 历史裁剪 snipCompactIfNeeded() [feature gate] ││ 3. 微压缩 microcompact() ││ 4. 上下文折叠 contextCollapse() [feature gate] ││ 5. 自动压缩 autocompact() ││ ↓ ││ 6. 构造完整系统提示 appendSystemContext() ││ 7. 流式调用模型 deps.callModel() ││ ↓ 边收流边处理 ││ 8. 错误恢复: ││ • FallbackTriggeredError → 切换模型重试 ││ • prompt-too-long 413 → collapse drain → reactive compact ││ • max_output_tokens → 升级 64k → 多轮恢复(≤3次) ││ • media-size 错误 → reactive compact 剥离图片 ││ ↓ ││ 9. 工具执行 runTools() / StreamingToolExecutor ││ 10. Hooks Stop hooks / PostSampling hooks ││ 11. Token 预算检查 checkTokenBudget() ││ 12. 拼装消息 messages + assistantMessages + toolResults ││ ↓ ││ 无 tool_use → return { reason: 'completed' } │└─────────────────────────────────────────────────────────────────┘关键设计细节
Prompt 缓存优化:工具 input 的backfillObservableInput 只在需要新增字段时克隆消息,原始 API 绑定消息不变,保证 prompt cache 命中。
task_budget 计费:压缩后taskBudgetRemaining 减去finalContextTokensFromLastResponse,跨 compact 边界累计扣除,向服务端同步剩余预算。
记忆预取:startRelevantMemoryPrefetch 在每个 user turn 开始时异步触发,在后续工具执行期间静默完成,consume 时零等待。
5.4 工具系统 —Tool.ts /tools.ts
Tool<Input, Output, Progress> 接口
工具接口按职责分三层:
执行层:
call(args, context, canUseTool, parentMessage, onProgress?): Promise<ToolResult<Output>>validateInput(input, context): Promise<ValidationResult>checkPermissions(input, context): Promise<PermissionResult>行为声明层(影响调度策略):
isConcurrencySafe(input): boolean// 能否与其他工具并发isReadOnly(input): boolean// 只读不写isDestructive(input): boolean// 不可逆操作isEnabled(): boolean// 当前是否可用interruptBehavior(): 'cancel' | 'block'// 用户提交新消息时的行为渲染层(React 节点,直接渲染到终端):
renderToolUseMessage(input, options): React.ReactNoderenderToolResultMessage(content, progressMessages, options): React.ReactNoderenderToolUseRejectedMessage(input, options): React.ReactNoderenderGroupedToolUse(toolUses, options): React.ReactNode | nullbuildTool() 工厂
// 所有默认值 fail-closed:保守安全const TOOL_DEFAULTS = { isEnabled: () =>true, isConcurrencySafe: () =>false, // 默认不并发 isReadOnly: () =>false, // 默认有写入 isDestructive: () =>false, checkPermissions: (input) =>// 默认放行,交给通用权限系统Promise.resolve({ behavior: 'allow', updatedInput: input }), toAutoClassifierInput: () =>'', // 默认跳过安全分类 userFacingName: () => name,}工具组装assembleToolPool()
缓存稳定性优化(注释明确标注):
// 内置工具与 MCP 工具分区独立排序,保证内置工具连续前缀// 服务端在最后一个内置工具后插入 cache breakpoint// 若 MCP 工具插入内置工具之间,会使下游所有缓存 key 失效const byName = (a: Tool, b: Tool) => a.name.localeCompare(b.name)return uniqBy( [...builtInTools].sort(byName).concat(allowedMcpTools.sort(byName)),'name',)5.5 工具执行编排 —services/tools/
toolOrchestration.ts:批次分区调度
核心算法partitionToolCalls():
工具调用序列: [Read, Grep, Glob, Bash, Read, Grep] ↓ partitionToolCalls批次 1 (并发): [Read, Grep, Glob] ← isConcurrencySafe = true批次 2 (串行): [Bash] ← isConcurrencySafe = false批次 3 (并发): [Read, Grep] ← isConcurrencySafe = true并发批用all() 生成器合并,默认并发度10(CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY)。
串行批的contextModifier 在批间累积传递(用于 MCP server 连接等副作用)。
StreamingToolExecutor:流式并发执行器
更先进的执行模式——工具一边从模型流式到达,就一边开始执行:
模型流式输出: [tool_1_start...tool_1_end] [tool_2_start...tool_2_end]执行时序: tool_1 开始执行 ──────────────→ 完成 tool_2 开始执行 ──→ 完成结果输出: 按 tool 到达顺序缓冲后按序输出(保序)关键特性:
TrackedTool状态机:queued → executing → completed → yieldedsiblingAbortController:Bash 出错时立即终止同批兄弟子进程,但不中断父级 AbortController(不结束 turn)流式 fallback 时调用 discard(),丢弃所有在途结果,防止 orphan tool_result
5.6 子智能体系统 —AgentTool
实现"智能体调用智能体"的递归多智能体能力:
主 Agent(query.ts) ↓ AgentTool.call() ↓ runAgent.ts ├── createSubagentContext() 隔离上下文(独立 agentId、FileStateCache) ├── initializeAgentMcpServers() 加载 agent 私有 MCP 服务器(frontmatter 声明) ├── resolveAgentTools() 过滤 agent 允许的工具集 └── query() ← 递归调用主循环!子智能体上下文隔离(createSubagentContext):
独立 agentId(UUID)独立 FileStateCache(LRU,防止跨 agent 状态污染)setAppState为 no-op(子 agent 不能修改主线程 UI 状态)localDenialTracking(本地拒绝计数,不依赖 AppState)
Prompt 缓存复用(forkSubagent.ts):
Fork 模式下共享父级的 renderedSystemPrompt字节避免 fork 时重新调用 getSystemPrompt()导致内容漂移,破坏缓存命中
多智能体协作框架:
TeamCreateTool | |
TeamDeleteTool | |
TaskCreateTool | |
TaskGet/List/Stop/Update | |
SendMessageTool |
5.7 上下文压缩 —services/compact/
为应对长会话 token 溢出,实现了五层压缩策略(按开销从小到大):
microCompact.ts | tool_use_id 删除旧工具结果,保留最新 N 条 | ||
apiMicrocompact.ts | cache_deleted_input_tokens) | ||
snipCompact.ts | |||
autoCompact.ts | |||
reactiveCompact.ts |
完整压缩流程(compact.ts):
1. executePreCompactHooks() ← 压缩前钩子2. analyzeContext() ← 分析 token 分布(工具结果/思考块/对话文本)3. runForkedAgent() ← 派生子 agent 对历史生成摘要 └── 摘要长度上限 COMPACT_MAX_OUTPUT_TOKENS4. buildPostCompactMessages() ← 摘要 + 附件 + hook 结果拼装新消息列表5. createCompactBoundaryMessage() ← 插入边界标记(后续查询只取边界后内容)6. executePostCompactHooks() ← 压缩后钩子压缩后 token 追踪(在query.ts 中):
// task_budget 跨 compact 边界累计扣除taskBudgetRemaining = Math.max(0, (taskBudgetRemaining ?? params.taskBudget.total) - preCompactContext)5.8 终端渲染引擎 —ink/
把 React 组件树渲染到终端 TTY 的自研引擎(约 96 文件,深度定制自 ink)。
核心层次
React 组件树 (TSX) ↓reconciler.ts ← react-reconciler host config(React Fiber 接入点) ↓dom.ts ← 自定义 DOM 节点(DOMElement / TextNode) ↓native-ts/yoga-layout ← Yoga 弹性布局引擎(C++ → TS 绑定) ↓render-node-to-output.ts ← 节点 → 字符 OutputBuffer ↓render-to-screen.ts + log-update.ts ← 差量更新终端输出 ↓termio/ ← 终端底层 IO(VT100 转义、光标控制)关键子模块
reconciler.ts | createReconciler() host config,将 React Fiber 操作(createInstance/appendChild/commitUpdate 等)映射到自定义 DOM |
renderer.ts | |
styles.ts | |
wrap-text.ts | |
stringWidth.ts | |
bidi.ts | |
searchHighlight.ts | |
optimizer.ts | |
parse-keypress.ts | |
focus.ts | |
selection.ts | |
terminal-querier.ts |
5.9 API 与 MCP 层
services/api/(Claude API 封装)
claude.ts | taskBudget、thinking、toolChoice、effortValue 等参数 |
withRetry.ts | FallbackTriggeredError(触发模型 fallback) |
errors.ts | isPromptTooLongMessage、PROMPT_TOO_LONG_ERROR_MESSAGE 等) |
bootstrap.ts | |
filesApi.ts | FilesApi) |
dumpPrompts.ts | |
promptCacheBreakDetection.ts |
services/mcp/(Model Context Protocol)
MCP 是 Anthropic 开放的工具扩展协议,允许外部服务向 Claude 暴露工具:
外部 MCP 服务器(本地进程 / 远程 HTTP) ↓ JSON-RPC over stdio / SSEclient.ts connectToServer() + fetchToolsForClient() ↓MCPTool(包装为标准 Tool 接口) ↓assembleToolPool()(与内置工具合并,保缓存稳定性排序)officialRegistry.ts 维护官方 MCP 服务器 URL 列表,支持一键安装。
5.10 系统提示 —constants/prompts.ts
getSystemPrompt() 构建发给模型的完整系统提示(文件约 53KB),包含:
核心角色定义与行为规范 工具使用指南(按工具列表动态注入) enhanceSystemPromptWithEnvDetails():注入环境信息操作系统与 shell 类型 当前工作目录 Git 仓库信息(分支、状态) 已安装工具版本 内存文件( CLAUDE.md)内容MCP 服务器指令差量( getMcpInstructionsDeltaAttachment)
重要:注释明确要求提示内容须与 Statsig
claude_code_global_system_cachingdynamic config 保持同步,以确保跨用户共享 prompt 缓存 breakpoint,大幅降低 API 成本。
6. 模块协作时序
以用户输入一条编码请求为例:
用户按回车 │ ▼REPL(components/REPL.tsx)捕获输入 │ createUserMessage() ▼query() 启动新一轮 Agentic 循环 │ ├─ 上下文预处理(microcompact / autocompact 按需触发) │ ├─ getSystemPrompt() 构造系统提示 │ ├─ deps.callModel() 流式调用 Claude API │ │ │ ├─ StreamingToolExecutor.addTool() ← 边流边加入执行队列 │ │ │ └─ yield AssistantMessage → ink/ 实时渲染到终端 │ ├─ 工具执行(以 FileEditTool 为例) │ ├─ validateInput() 校验参数 │ ├─ checkPermissions() 权限检查(deny 规则 / 用户确认) │ ├─ call() 执行编辑 │ └─ renderToolResultMessage() → React 节点 → ink/ 渲染 │ ├─ 工具结果作为 UserMessage 回灌消息列表 │ ├─ 有更多 tool_use? → continue(下一轮) │ └─ 无 tool_use → Stop hooks → return { reason: 'completed' }7. 设计亮点
1. 动态导入 + 编译期死代码消除
feature('XXX') 宏在 Bun 构建时通过 tree-shaking 剔除内部功能,外部发布包不含ant-only 代码。快速路径全部使用await import() 动态加载,冷启动仅需--version 的零依赖路径。
2. Generator 驱动的流式架构
query.ts 用async generator 统一了"模型流式输出 + 工具执行 + 消息回灌",天然支持中断(AbortController)、恢复、以及 React 的流式渲染。
3. 多层上下文工程
五种压缩策略按开销从小到大排列,优先保留细粒度历史(microcompact/snip),仅在必要时才召唤子 agent 生成摘要(autocompact),极端情况下才响应 413 紧急处理(reactiveCompact)。
4. Prompt 缓存优化
工具列表保缓存稳定性排序、系统提示同步 Statsig 配置、子 agent fork 共享父级 prompt 字节——多处精心设计最大化服务端 prompt 缓存命中率,直接降低 API 成本。
5. 完善的权限与安全体系
每个工具有validateInput +checkPermissions 双重校验,配合 PreToolUse/PostToolUse/Stop/PostSampling 四类 Hooks,以及自动安全分类器(toAutoClassifierInput),构成纵深防御。
6. 多智能体能力
内置 AgentTool(递归 query)、Team(多 agent 协作)、Task(异步后台任务)体系,支持并行子智能体、agent 间消息传递、上下文隔离与 transcript 持久化。
夜雨聆风