Claude Code源码分析
Claude Code 完整流程详细分析
一、应用启动流程 (main.tsx)
阶段 1: 初始化阶段 (模块加载级别)
// 0. 启动性能检查点
profileCheckpoint(‘main_tsx_entry’)
// 1. 并行启动后台进程 (优化启动时间)
startMdmRawRead() // macOS MDM 读取
startKeychainPrefetch() // OAuth + API key 预取
阶段 2: 参数解析阶段
function main() {
// 1. 深度链接处理 (macOS URL scheme)
if (feature(‘LODESTONE’)) {
handleDeepLinkUri()
}
// 2. 直连 URL 重写 (cc:// URL)
if (feature(‘DIRECT_CONNECT’) && ccUrlMatch) {
rewriteProcessArgs()
}
// 3. 助理模式参数解析
if (feature(‘KAIROS’) && assistantArgMatch) {
_pendingAssistantChat.sessionId = sessionId
}
// 4. SSH 会话参数解析
if (feature(‘SSH_REMOTE’) && sshArgMatch) {
_pendingSSH.host = host
_pendingSSH.cwd = dir
}
// 5. 交互式 vs 非交互式模式检测
const isNonInteractive = hasPrintFlag ||
hasInitOnlyFlag ||
hasSdkUrl ||
!process.stdout.isTTY
}
阶段 3: Client Type 确定阶段
const clientType = determineClientType()
// 可能的值:
// – ‘cli’ (交互式命令行)
// – ‘sdk-cli’ (headless/print 模式)
// – ‘claude-desktop’ (桌面应用)
// – ‘claude-vscode’ (VS Code 扩展)
// – ‘local-agent’ (本地 Agent 模式)
// – ‘remote’ (远程会话)
阶段 4: Runner 准备阶段
async function run() {
const program = new CommanderCommand()
// preAction hook: 在命令执行前运行初始化
program.hook(‘preAction’, async () => {
// 等待并行进程完成
await Promise.all([
ensureMdmSettingsLoaded(),
ensureKeychainPrefetchCompleted()
])
// 核心初始化
await init()
// 加载日志接收器
initSinks()
// 迁移数据
runMigrations()
// 加载远程管理设置
void loadRemoteManagedSettings()
})
}
阶段 5: 分支选择阶段
// ================= 交互式模式 =================
if (!isNonInteractive) {
// 1. 运行 setup() 屏幕交互
await showSetupScreens()
// 2. 构建 AppState
const initialState: AppState = {
settings: getInitialSettings(),
mainLoopModel: initialMainLoopModel,
toolPermissionContext: effectiveToolPermissionContext,
mcp: { clients: [], tools: [], commands: [] },
plugins: { enabled: [], disabled: [] },
// … 更多状态
}
// 3. 构建 sessionConfig
const sessionConfig = {
debug: debug,
commands: […commands, …mcpCommands],
initialTools,
mcpClients,
systemPrompt,
thinkingConfig,
onTurnComplete: (messages) => uploadSessionData(messages)
}
// 4. 启动 REPL (交互式终端)
await launchRepl(root, appProps, replProps, renderAndRun)
// launchRepl 内部:
// 1. 动态导入 App 和 REPL 组件
const { App } = await import(‘./components/App.js’)
const { REPL } = await import(‘./screens/REPL.js’)
// 2. 使用 Ink 渲染
await renderAndRun(root, <App><REPL {…replProps} /></App>)
}
// ================= Headless/SDK 模式 =================
else {
// 1. 等待 MCP 连接
await connectMcpBatch(claudeaiConfigs, ‘claudeai’)
// 2. 启动后台任务
if (!isBareMode()) {
startDeferredPrefetches()
void startBackgroundHousekeeping()
}
// 3. 运行 headless 逻辑
const { runHeadless } = await import(‘src/cli/print.js’)
await runHeadless(inputPrompt, getState, setState,
commands, tools, mcpConfigs, agents, options)
}
二、REPL 组件流程 (screens/REPL.tsx)
REPL 组件结构
export function REPL(props: REPLProps) {
// ===== 状态管理 =====
const appState = useAppState()
const setAppState = useSetAppState()
const [messages, setMessages] = useState<Message[]>(props.initialMessages)
const [isLoading, setIsLoading] = useState(false)
const [toolJSX, setToolJSX] = useState<ToolJSXState>(null)
// ===== 核心钩子 =====
// 1. 命令合并 (内置 + MCP 技能)
const commands = useMergedCommands()
// 2. 工具合并 (内置 + MCP 工具)
const tools = useMergedTools()
// 3. MCP 客户端管理
const mcpClients = useMergedClients()
// 4. 队列处理器 (处理排队的命令)
useQueueProcessor({
queryGuard,
commands,
messages,
mainLoopModel,
getToolUseContext,
setUserInputOnProcessing,
setAbortController,
onQuery,
setAppState,
onBeforeQuery,
canUseTool,
onInputChange,
resetHistory,
setToolJSX,
})
// ===== 主查询函数 =====
const onQuery = async (
newMessages: Message[],
abortController: AbortController,
shouldQuery: boolean,
allowedTools: string[],
model: string,
) => {
// 1. 状态转换
setIsLoading(true)
queryGuard.start()
// 2. 运行查询循环
for await (const message of query({
messages: newMessages,
systemPrompt: buildSystemPrompt(),
userContext: getUserContext(),
canUseTool,
toolUseContext,
querySource: getQuerySourceForREPL(),
})) {
// 3. 处理不同类型的消息
switch (message.type) {
case ‘assistant’:
await handleAssistantMessage(message)
break
case ‘progress’:
await handleProgressMessage(message)
break
case ‘user’:
await handleUserMessage(message)
break
case ‘tombstone’:
await handleTombstoneMessage(message)
break
}
}
// 4. 完成清理
setIsLoading(false)
queryGuard.end()
夜雨聆风