来源:Claude Code 技术文档 - v2.1.88 源码分析
开发者入门指南
14.1 环境准备
14.1.1 前置依赖
工具
版本要求
说明
Bun
>= 1.x
主运行时与构建工具
Node.js
>= 18.x
兼容性与部分工具链
Git
>= 2.x
版本控制
TypeScript
>= 5.x
类型检查
14.1.2 获取源码
# 项目已在本地目录
cd claude-code-2.1.8814.1.3 安装依赖
bun install14.1.4 主要技术栈
- 语言: TypeScript (严格模式)
- 运行时: Bun
- UI 框架: React + Ink (终端 UI)
- Schema 验证: Zod v4
- 状态管理: 自实现 Store (类 Zustand)
- 协议: MCP (Model Context Protocol)
- 编译优化: React Compiler Runtime (自动 memo)
14.2 项目运行
14.2.1 开发模式
# 直接运行入口
bun run src/entrypoints/cli.tsx
# 或使用项目脚本(如果 package.json 有配置)
bun run dev14.2.2 MCP Server 模式
bun run src/entrypoints/mcp.ts14.2.3 环境变量
变量
说明
ANTHROPIC_API_KEY
Anthropic API 密钥
CLAUDE_CODE_MAX_OUTPUT_TOKENS
最大输出 Token 数
MCP_TIMEOUT
MCP 超时时间
CLAUDE_CODE_DEBUG
启用调试日志
14.3 架构快速理解
14.3.1 数据流概览
用户输入
→ REPL.tsx 捕获
→ useTextInput Hook 处理按键
→ processUserInput() 解析
→ 以 / 开头? → 命令系统 (commands.ts)
→ 否则 → QueryEngine.submitMessage()
→ claude.ts 调用 API
→ 模型响应 tool_use?
→ 是 → Tool.call() 执行
→ 否 → 渲染到 VirtualMessageList14.3.2 核心入口文件
src/entrypoints/cli.tsx— 启动入口,解析参数并路由到正确模式src/entrypoints/init.ts— 7 步初始化链src/QueryEngine.ts— AI 查询的中枢src/tools.ts— 工具池组装src/commands.ts— 命令注册表src/state/store.ts— 状态管理核心
14.3.3 分层架构
┌──────────────────────────────────┐
│ UI 层: React + Ink 组件 │ ← components/, screens/, hooks/
├──────────────────────────────────┤
│ 交互层: REPL + 命令引擎 │ ← commands/, keybindings/
├──────────────────────────────────┤
│ 核心层: QueryEngine + 工具 │ ← QueryEngine.ts, tools/, Tool.ts
├──────────────────────────────────┤
│ 服务层: API + MCP + 状态 │ ← services/, state/, plugins/
├──────────────────────────────────┤
│ 基础层: CLI + 启动 + 工具函数 │ ← cli/, bootstrap/, utils/
├──────────────────────────────────┤
│ 通信层: Bridge + Remote │ ← bridge/, remote/
└──────────────────────────────────┘14.4 如何添加新工具
工具是 Claude Code 中最常扩展的部分。每个工具让 AI 模型能调用一个特定能力。
14.4.1 步骤
1. 创建工具目录
src/tools/MyNewTool/
├── index.ts # 工具定义
└── prompt.ts # (可选)提示词2. 实现工具
// src/tools/MyNewTool/index.ts
import { buildTool } from "../../Tool"
import { z } from "zod"
const MyNewTool = buildTool({
// ---- 基本信息 ----
name: "my_new_tool",
displayTitle: "My New Tool",
description: "工具功能描述,AI 通过此了解何时调用此工具",
// ---- 输入 Schema ----
inputSchema: z.object({
input_param: z.string().describe("参数描述"),
optional_param: z.number().optional().describe("可选参数"),
}),
// ---- 权限 ----
isReadOnly: () => true, // 只读工具不需权限确认
// 若不是只读,需声明:
// needsPermissions: (input) => true,
// userFacingName: (input) => `my_new_tool: ${input.input_param}`,
// ---- 执行 ----
async *call(input, context) {
// context 包含: abortController, readFile, options 等
// 1. 使用 yield 发送中间状态(可选)
yield {
type: "progress",
content: "正在处理...",
}
// 2. 执行核心逻辑
const result = doSomething(input.input_param)
// 3. 返回最终结果(最后一个 yield 会被当作结果)
yield {
type: "result",
data: result,
resultForAssistant: `处理结果: ${result}`,
}
},
})
export default MyNewTool3. 注册工具
在 src/tools.ts 中的 getTools() 函数里添加工具:
import MyNewTool from "./tools/MyNewTool"
// 在工具数组中添加
tools.push(MyNewTool)14.4.2 工具关键概念
概念
说明
isReadOnly()
返回 true 表示只读操作,跳过权限检查
needsPermissions()
返回 true 时需要用户确认
isEnabled()
返回 false 可动态禁用工具
isConditional
标记为条件工具,仅在特定场景加载
renderResultForAssistant()
自定义返回给模型的结果格式
renderToolUseMessage()
自定义 UI 中显示的工具调用信息
AsyncGenerator
call() 使用 yield 可发送流式中间状态
14.4.3 工具权限级别
// 权限分类
isReadOnly: () => true // 完全跳过权限检查
needsPermissions: () => false // 需要权限系统处理但自动允许
needsPermissions: () => true // 需要用户确认14.5 如何添加新命令
命令是用户通过 /command_name 输入触发的交互方式。
14.5.1 命令类型
类型
接口
用途
PromptCommand
返回字符串发给模型
将用户输入转为 AI 提示
LocalCommand
直接执行逻辑
配置修改、状态切换
LocalJSXCommand
返回 JSX 组件
需要 UI 渲染的命令
14.5.2 步骤
1. 创建命令文件
// src/commands/my-command/index.ts
import type { Command } from "../../types/command"
const myCommand: Command = {
// 类型: "prompt" | "local" | "local-jsx"
type: "local",
name: "my-command",
description: "命令描述",
isEnabled: true,
isHidden: false,
progressMessage: "执行中...",
// 参数自动补全
argNames: ["target"],
getCompletions: async (args) => {
return ["option1", "option2"]
},
// 参数描述
argDescriptions: {
target: "目标描述",
},
// 执行
call: async (args, context) => {
// context 包含: readFile, setMessages, abortController 等
return {
type: "local-result",
message: "命令执行完成",
}
},
}
export default myCommand2. 注册命令
在 src/commands.ts 中导入并添加:
import myCommand from "./commands/my-command"
// 添加到命令列表
commands.push(myCommand)14.5.3 命令返回类型
// PromptCommand 返回
{ type: "prompt-result", message: "发送给 AI 的内容" }
// LocalCommand 返回
{ type: "local-result", message: "显示给用户的结果" }
{ type: "local-result", message: "...", shouldResume: true } // 继续之前的查询
// LocalJSXCommand 返回
{ type: "local-jsx-result", component: <MyComponent /> }
// 空结果
{ type: "empty" }14.6 如何添加新 Hook
Hook 是安全钩子,在工具执行前后触发。
14.6.1 Hook 配置
Hook 在 .claude/settings.json 或 CLAUDE.md 中配置:
{
"hooks": {
"PreToolUse": [
{
"matcher": "BashTool",
"hooks": [
{
"type": "command",
"command": "node ./hooks/validate-bash.js"
}
]
}
]
}
}14.6.2 Hook 类型
Hook
触发时机
用途
PreToolUse
工具执行前
验证/阻止工具调用
PostToolUse
工具执行后
审计/日志记录
Notification
通知事件
自定义通知
14.6.3 Hook 返回 Schema
// PreToolUse Hook 可返回
{
"decision": "approve", // 允许执行
// 或
"decision": "block", // 阻止执行
"reason": "不允许该操作"
}14.7 状态管理实践
14.7.1 读取状态
import { useAppState } from "../state/AppState"
// 在组件中使用
function MyComponent() {
const messages = useAppState((s) => s.messages)
const isLoading = useAppState((s) => s.isLoading)
return <Text>{isLoading ? "加载中..." : `${messages.length} 条消息`}</Text>
}14.7.2 更新状态
import { appStateStore } from "../state/AppStateStore"
// 用 set() 更新
appStateStore.set({
isLoading: true,
})
// 用函数式更新
appStateStore.set((prev) => ({
messages: [...prev.messages, newMessage],
}))14.7.3 订阅状态变化
import { onChangeAppState } from "../state/onChangeAppState"
// 监听特定字段变化
const unsubscribe = onChangeAppState(
(state) => state.isLoading,
(isLoading) => {
console.log("isLoading changed to:", isLoading)
}
)14.8 MCP 工具扩展
14.8.1 添加 MCP Server
在 ~/.claude/settings.json 或项目级别配置:
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["./my-mcp-server.js"],
"env": {
"API_KEY": "..."
}
}
}
}14.8.2 MCP 配置层级
优先级从高到低:
enterprise— 企业管理策略project—.claude/settings.jsonproject-local—.claude/settings.local.jsonuser—~/.claude/settings.jsonuser-local—~/.claude/settings.local.jsonglobal— 全局默认
14.8.3 MCP 传输类型
// Stdio (默认)
{ "command": "node", "args": ["server.js"] }
// SSE
{ "url": "http://localhost:3000/sse" }
// HTTP
{ "url": "http://localhost:3000/mcp", "type": "http" }14.9 调试技巧
14.9.1 启用 Debug 日志
CLAUDE_CODE_DEBUG=1 bun run src/entrypoints/cli.tsx14.9.2 Bridge 调试
# 使用 bridge debug 命令
/bridge-debugBridge 系统提供了 bridgeDebug.ts 和 debugUtils.ts 模块用于检查远程通信。
14.9.3 Doctor 屏幕
# 运行环境诊断
/doctor通过 screens/Doctor.tsx 组件检查环境配置问题。
14.9.4 状态检查
# 查看当前上下文
/context
# 查看成本
/cost
# 查看版本
/version14.9.5 日志与历史
- 会话历史位于
~/.claude/sessions/目录 - 每个会话有唯一的
SessionId(品牌类型string & { __brand: "SessionId" }) - 使用
history.ts中的logHistory()追踪消息
14.10 代码规范速查
14.10.1 类型安全
// ✅ 使用品牌类型
const sessionId: SessionId = "abc" as SessionId
// ✅ 使用 DeepImmutable 防止意外修改
type ImmutableState = DeepImmutable<AppState>
// ✅ 使用 Zod 验证外部输入
const schema = z.object({ name: z.string() })
const result = schema.safeParse(input)14.10.2 异步模式
// ✅ 工具使用 AsyncGenerator
async *call(input, context) {
yield { type: "progress", content: "进行中" }
const result = await doWork()
yield { type: "result", data: result }
}
// ✅ API 调用使用 withRetry
import { withRetry } from "./services/withRetry"
const result = await withRetry(() => apiCall(), {
strategy: "foreground",
})14.10.3 组件模式
// ✅ 使用 React Compiler(自动 memo,不需手动 useMemo/useCallback)
function MyComponent({ data }: Props) {
const computed = expensiveCompute(data) // 自动优化
return <Text>{computed}</Text>
}
// ✅ 使用 useSyncExternalStore 读取 Store
function useAppState<T>(selector: (s: AppState) => T): T {
return useSyncExternalStore(store.subscribe, () => selector(store.get()))
}14.10.4 编译时特性门控
import { feature } from "../constants/features"
// ✅ 编译时消除死代码
if (feature("EXPERIMENTAL_FEATURE")) {
// 此代码段在 feature 关闭时会被完全移除
enableExperimentalFeature()
}14.11 常见开发场景
14.11.1 修改系统提示词
系统提示词在 src/constants/prompts.ts 中组装,包含 9 个部分:
- 角色定义
- 环境信息
- 工具说明
- 工作流指南
- 安全指导
- 插件提示
- 用户自定义规则 (CLAUDE.md)
- 项目上下文
- 会话元数据
14.11.2 添加新的 AI Provider
在 src/services/client.ts 的 getAnthropicClient() 工厂函数中添加新的 provider:
function getAnthropicClient(): AnthropicClient {
if (isMyProvider()) {
return new Anthropic({
baseURL: "https://my-provider.example.com/v1",
apiKey: process.env.MY_PROVIDER_KEY,
defaultHeaders: {
"x-attribution": ATTRIBUTION_HEADER,
},
})
}
// ... 其他 provider
}目前支持的 Provider:
- Anthropic Direct — 直连 API
- AWS Bedrock —
@anthropic-ai/bedrock-sdk - Azure Foundry — Azure 集成
- Google Vertex AI — Google Cloud 集成
14.11.3 修改权限行为
权限系统在 src/types/permissions.ts 中定义:
// 修改权限模式
type PermissionMode =
| "default" // 标准模式
| "plan" // 仅规划
| "bypassPermissions"// 自动批准全部
| "acceptEdits" // 自动批准编辑
| "dangerousFullAuto"// 完全无限制
| "trusted" // 受信环境
| "advisor" // 仅建议14.12 项目规模参考
类别
数量
源码文件
500+
工具
45+
命令
120+
组件
200+
Hooks
90+
工具函数
150+
类型定义
60+
服务模块
20+
14.13 进阶路线图
阶段
学习重点
核心文件
入门
CLI 运行、基本命令
cli.tsx, commands.ts
基础
工具系统、状态管理
Tool.ts, tools.ts, store.ts
中级
查询引擎、服务层
QueryEngine.ts, claude.ts, withRetry.ts
高级
Bridge 通信、插件开发
bridge/, plugins/, skills/
专家
性能优化、安全模型
tokenBudget.ts, permissions.ts, Hook 系统