# Claude Code Haha 架构文档 > 本文档详细分析 Claude Code Haha 项目的架构设计、核心模块以及数据流动方式。 ## 目录 1. [概述](#1-概述) 2. [整体架构](#2-整体架构) 3. [入口与启动](#3-入口与启动) 4. [交互层(TUI)](#4-交互层tui) 5. [Ink 渲染引擎](#5-ink-渲染引擎) 6. [工具系统](#6-工具系统) 7. [命令系统](#7-命令系统) 8. [Skill 系统](#8-skill-系统) 9. [状态管理](#9-状态管理) 10. [桥接与远程控制](#10-桥接与远程控制) 11. [服务层](#11-服务层) 12. [数据流](#12-数据流) 13. [关键技术](#13-关键技术) --- ## 1. 概述 Claude Code Haha 是基于 Claude Code 泄露源码修复的本地可运行版本,支持接入任意 Anthropic 兼容 API(如 MiniMax、OpenRouter 等)。 ### 核心特性 - 完整的 Ink TUI 交互界面(与官方 Claude Code 一致) - `--print` 无头模式(脚本/CI 场景) - 支持 MCP 服务器、插件、Skills - 支持自定义 API 端点和模型 - 降级 Recovery CLI 模式 ### 技术栈 | 类别 | 技术 | |------|------| | 运行时 | Bun | | 语言 | TypeScript | | 终端 UI | React 19 + Ink 6 | | CLI 解析 | Commander.js | | API | Anthropic SDK | | 协议 | MCP、LSP | --- ## 2. 整体架构 ### 2.1 分层架构 Claude Code Haha 采用**五层分层架构**,从上到下依次为: ``` ┌─────────────────────────────────────────────────────────────┐ │ 入口层 (Entrypoints) │ │ cli.tsx → main.tsx → REPL.tsx │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 交互层 (Interaction) │ │ screens/ + components/ │ │ TUI 界面、用户输入、消息展示 │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 核心层 (Core) │ │ tools/ + commands/ + skills/ + state/ │ │ 工具系统、命令系统、Skill、状态管理 │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 服务层 (Services) │ │ services/ + bridge/ + context/ │ │ API、MCP、OAuth、分析、桥接 │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 支撑层 (Infrastructure) │ │ utils/ + hooks/ + constants/ │ │ 工具函数、React Hooks、常量定义 │ └─────────────────────────────────────────────────────────────┘ ``` ### 2.2 项目结构 ``` src/ ├── entrypoints/ # CLI 入口点 │ ├── cli.tsx # 主入口(参数解析、快速路径分流) │ ├── mcp.ts # MCP 服务器入口 │ └── init.ts # 初始化入口 ├── screens/ # 交互界面 │ └── REPL.tsx # 主 REPL 界面 ├── components/ # UI 组件库 │ ├── App.tsx │ ├── Message.tsx │ ├── PromptInput/ │ └── ... ├── ink/ # Ink 终端渲染引擎 │ ├── components/ # Ink 基础组件(Box、Text、Button) │ ├── events/ # 事件系统 │ ├── hooks/ # Ink Hooks │ ├── layout/ # Yoga 布局引擎 │ ├── termio/ # 终端协议解析(ANSI、CSI、SGR) │ └── ... ├── tools/ # 工具系统 │ ├── Tool.ts # 工具基类 │ ├── BashTool/ # Bash 执行工具 │ ├── FileEditTool/ # 文件编辑工具 │ ├── GrepTool/ # 搜索工具 │ ├── MCPTool/ # MCP 工具 │ └── ... ├── commands/ # 命令系统 │ ├── commit/ │ ├── review/ │ ├── help/ │ └── ... ├── skills/ # Skill 系统 │ ├── bundled/ # 内置 Skills │ │ ├── verify/ │ │ ├── batch.ts │ │ ├── debug.ts │ │ ├── loop.ts │ │ └── ... │ └── bundledSkills.ts ├── state/ # 状态管理 │ ├── AppState.tsx │ ├── AppStateStore.ts │ └── store.ts ├── bridge/ # 桥接与远程控制 │ ├── bridgeMain.ts │ ├── bridgeApi.ts │ └── ... ├── services/ # 服务层 │ ├── api/ # API 服务 │ ├── mcp/ # MCP 服务 │ ├── oauth/ # OAuth 服务 │ ├── analytics/ # 分析服务 │ └── lsp/ # LSP 服务 ├── context/ # React 上下文 ├── hooks/ # React Hooks ├── constants/ # 常量定义 └── utils/ # 工具函数 ``` --- ## 3. 入口与启动 ### 3.1 启动流程 ``` CLI 启动 (bin/claude-haha) ↓ entrypoints/cli.tsx - 解析命令行参数 - 处理快速路径(--version、--help) - 特殊模式检查(--daemon-worker、bridge、remote-control) ↓ main.tsx (动态导入) - 完整初始化 - 配置加载 - 状态初始化 ↓ screens/REPL.tsx - TUI 渲染 - 用户交互循环 ``` ### 3.2 快速路径优化 `cli.tsx` 实现了多种快速路径,避免不必要的模块加载: | 路径 | 条件 | 优化效果 | |------|------|---------| | `--version` | `args.length === 1` | 零模块加载 | | `--dump-system-prompt` | Feature Flag | 提前退出 | | `--daemon-worker` | Feature Flag | Lean Worker | | `bridge/remote-control` | Feature Flag | 桥接专用初始化 | | `daemon` | Feature Flag | 守护进程模式 | | `ps/logs/attach/kill` | Feature Flag | 会话管理 | ### 3.3 Feature Flags 项目使用 `feature()` 函数实现 Dead Code Elimination(代码消除): ```typescript // 启用特性 if (feature('FEATURE_NAME')) { // 仅在启用的构建中包含 } // 条件导入 const Module = feature('FEATURE') ? require('./feature.js') : null ``` 支持的 Feature Flags: - `VOICE_MODE`:语音模式 - `BRIDGE_MODE`:桥接模式 - `DAEMON`:守护进程 - `BG_SESSIONS`:后台会话 - `COORDINATOR_MODE`:协调模式 - `WORKFLOW_SCRIPTS`:工作流脚本 --- ## 4. 交互层(TUI) ### 4.1 REPL 主界面 `screens/REPL.tsx` 是核心的 TUI 组件,负责: - **消息展示**:渲染用户消息、助手消息、系统消息 - **输入处理**:PromptInput 接收用户输入 - **任务管理**:后台任务的状态展示与切换 - **权限请求**:工具调用的权限确认对话框 - **快捷键绑定**:全局键盘事件处理 ### 4.2 核心组件 ``` components/ ├── App.tsx # 根组件 ├── Message.tsx # 单条消息渲染 ├── Messages.tsx # 消息列表 ├── MessageRow.tsx # 消息行 ├── PromptInput/ # 输入框组件 │ ├── PromptInput.tsx │ └── PromptInputQueuedCommands.tsx ├── Spinner.tsx # 加载动画 ├── SearchBox.tsx # 搜索框 ├── TaskListV2.tsx # 任务列表 └── permissions/ # 权限相关组件 ``` ### 4.3 输入模式 REPL 支持多种输入模式: | 模式 | 说明 | 快捷键 | |------|------|--------| | 标准模式 | 普通文本输入 | Enter 提交 | | Vim 模式 | Vim 风格编辑 | Esc 进入命令模式 | | 命令模式 | 斜杠命令输入 | `/` 触发 | | 选择模式 | 消息选择/复制 | v 进入可视化模式 | --- ## 5. Ink 渲染引擎 ### 5.1 概述 Ink 是基于 React 的终端 UI 渲染库,Claude Code 对其进行了深度定制。 ### 5.2 架构 ``` ink/ ├── components/ # React 组件 │ ├── Box.tsx # 容器组件 │ ├── Text.tsx # 文本组件 │ ├── Button.tsx # 按钮组件 │ └── ... ├── reconciler.ts # React Reconciler ├── renderer.ts # 渲染器 ├── screen.ts # 屏幕管理 ├── dom.ts # DOM 抽象 └── termio/ # 终端协议 ├── ansi.ts # ANSI 转义序列 ├── csi.ts # Control Sequence Introducer ├── sgr.ts # Select Graphic Rendition ├── parser.ts # 协议解析器 └── tokenize.ts # Tokenizer ``` ### 5.3 布局引擎 Ink 使用 **Yoga**(Facebook 的跨平台布局引擎)进行布局计算: ```typescript // ink/layout/yoga.ts import Yoga from 'yoga-wasm' // 支持的布局属性 type LayoutProps = { width?: number | 'auto' | number height?: number | 'auto' | number flexDirection?: 'row' | 'column' justifyContent?: 'flex-start' | 'center' | 'flex-end' | 'space-between' alignItems?: 'flex-start' | 'center' | 'flex-end' | 'stretch' padding?: number | [number, number, number, number] margin?: number | [number, number, number, number] } ``` ### 5.4 终端协议 Ink 实现了完整的终端协议支持: | 协议 | 说明 | 用途 | |------|------|------| | ANSI | 基本转义序列 | 颜色、样式 | | CSI | 控制序列 | 光标移动、清屏 | | SGR | 选择图形渲染 | 颜色属性 | | OSC | 操作系统命令 | 窗口标题 | --- ## 6. 工具系统 ### 6.1 概述 工具系统是 Claude Code 的核心能力,允许 AI Agent 执行各种操作。 ### 6.2 工具基类 所有工具都继承自 `Tool` 基类: ```typescript // Tool.ts export type Tool = { name: string description: string allowedTools?: string[] isEnabled?: () => boolean prompt?: ToolPrompt UI?: ToolUIComponent execute?: (context: ToolUseContext) => Promise } ``` ### 6.3 内置工具 | 工具 | 说明 | 核心文件 | |------|------|---------| | BashTool | 执行 Shell 命令 | tools/BashTool/ | | FileReadTool | 读取文件 | tools/FileReadTool/ | | FileEditTool | 编辑文件 | tools/FileEditTool/ | | FileWriteTool | 写入文件 | tools/FileWriteTool/ | | GlobTool | 文件搜索 | tools/GlobTool/ | | GrepTool | 内容搜索 | tools/GrepTool/ | | WebFetchTool | HTTP 请求 | tools/WebFetchTool/ | | WebSearchTool | 网络搜索 | tools/WebSearchTool/ | | AgentTool | 子 Agent | tools/AgentTool/ | | TaskStopTool | 停止任务 | tools/TaskStopTool/ | | MCPTool | MCP 工具 | tools/MCPTool/ | | LSPTool | LSP 工具 | tools/LSPTool/ | | SkillTool | Skill 调用 | tools/SkillTool/ | ### 6.4 工具注册与过滤 ```typescript // tools.ts export function getAllBaseTools(): Tools { return [ AgentTool, TaskOutputTool, BashTool, GlobTool, GrepTool, ExitPlanModeV2Tool, FileReadTool, FileEditTool, FileWriteTool, // ... 更多工具 ] } export function getTools(permissionContext: ToolPermissionContext): Tools { const tools = getAllBaseTools() // 权限过滤 return filterToolsByDenyRules(tools, permissionContext) } ``` ### 6.5 工具权限 工具调用需要权限确认: ```typescript // 权限类型 type ToolPermission = { tool: string args: Record reason?: string autoApprove?: boolean } // 权限检查 function checkToolPermission(tool: string): boolean function requestToolPermission(tool: string): Promise ``` --- ## 7. 命令系统 ### 7.1 概述 命令系统处理以 `/` 开头的斜杠命令,提供辅助功能。 ### 7.2 内置命令 | 命令 | 说明 | 目录 | |------|------|------| | /commit | Git 提交 | commands/commit/ | | /review | 代码审查 | commands/review.js | | /help | 帮助信息 | commands/help/ | | /diff | 查看变更 | commands/diff/ | | /tasks | 任务管理 | commands/tasks/ | | /model | 模型切换 | commands/model/ | | /config | 配置管理 | commands/config/ | | /clear | 清除缓存 | commands/clear/ | | /doctor | 诊断检查 | commands/doctor/ | | /theme | 主题切换 | commands/theme/ | | /mcp | MCP 管理 | commands/mcp/ | | /skills | Skill 管理 | commands/skills/ | ### 7.3 命令注册 ```typescript // commands.ts import addDir from './commands/add-dir/index.js' import commit from './commands/commit.js' import help from './commands/help/index.js' const commands: Command[] = [ addDir, commit, help, // ... ] export function getCommand(name: string): Command | undefined { return commands.find(cmd => cmd.name === name || cmd.aliases?.includes(name) ) } ``` ### 7.4 命令类型 ```typescript type Command = { name: string description: string aliases?: string[] type: 'prompt' | 'action' | 'navigation' execute: (args: string, context: CommandContext) => Promise } ``` --- ## 8. Skill 系统 ### 8.1 概述 Skill 是封装好的任务模板,可以被 AI Agent 调用。 ### 8.2 内置 Skills | Skill | 说明 | 用途 | |-------|------|------| | verify | 验证代码修改 | 自动化验证 | | batch | 批量处理 | 批量任务执行 | | loop | 循环执行 | 重复任务 | | debug | 调试助手 | 问题诊断 | | simplify | 代码简化 | 重构辅助 | | stuck | 困境解脱 | 遇到问题时提供帮助 | | updateConfig | 配置更新 | 配置文件修改 | | remember | 记忆管理 | 知识库操作 | | scheduleRemoteAgents | 远程调度 | 分布式任务 | ### 8.3 Skill 注册 ```typescript // skills/bundledSkills.ts export function registerBundledSkill(definition: BundledSkillDefinition): void { const command: Command = { type: 'prompt', name: definition.name, description: definition.description, // ... } bundledSkills.push(command) } ``` ### 8.4 Skill 文件提取 某些 Skill 需要将文件提取到磁盘: ```typescript // 首次调用时提取 const files = await extractBundledSkillFiles(skillName, filesDefinition) // 模型可以 Read/Grep 这些文件 ``` --- ## 9. 状态管理 ### 9.1 AppStateStore 使用 React 的 `useSyncExternalStore` 实现全局状态管理: ```typescript // state/store.ts export function createStore( initialState: AppState, onChange?: (newState: AppState, oldState: AppState) => void ): AppStateStore { return { getState: () => state, setState: (update) => { const newState = typeof update === 'function' ? update(state) : update state = newState listeners.forEach(listener => listener()) }, subscribe: (listener) => { listeners.add(listener) return () => listeners.delete(listener) } } } ``` ### 9.2 AppState 结构 ```typescript // state/AppStateStore.ts export interface AppState { // 主循环状态 mainLoopModel: string task: TaskState | null // MCP 状态 mcp: { clients: MCPClient[] tools: Tool[] resources: MCPResource[] } // 权限状态 toolPermissionContext: ToolPermissionContext // UI 状态 messages: Message[] isLoading: boolean // 配置状态 settings: Settings config: Config } ``` ### 9.3 状态选择器 使用选择器模式避免不必要的重渲染: ```typescript // state/selectors.ts export const selectMainLoopModel = (s: AppState) => s.mainLoopModel export const selectMessages = (s: AppState) => s.messages export const selectMcpTools = (s: AppState) => s.mcp.tools ``` ### 9.4 React Hooks ```typescript // state/AppState.tsx export function useAppState(selector: (s: AppState) => T): T { const store = useAppStore() return useSyncExternalStore( store.subscribe, () => selector(store.getState()), () => selector(store.getState()) ) } export function useSetAppState(): SetAppState { return useAppStore().setState } ``` --- ## 10. 桥接与远程控制 ### 10.1 Bridge 模式 Bridge 允许远程控制本地 Claude Code 实例。 ### 10.2 核心组件 ``` bridge/ ├── bridgeMain.ts # 主入口 ├── bridgeApi.ts # API 客户端 ├── bridgeUI.ts # 状态显示 ├── bridgeMessaging.ts # 消息处理 ├── sessionRunner.ts # 会话运行 ├── jwtUtils.ts # JWT 认证 ├── trustedDevice.ts # 设备信任 └── types.ts # 类型定义 ``` ### 10.3 认证流程 ``` Bridge 启动 ↓ 检查认证状态 (getClaudeAIOAuthTokens) ↓ 检查 Bridge 可用性 (getBridgeDisabledReason) ↓ 验证最低版本 (checkBridgeMinVersion) ↓ 检查策略限制 (isPolicyAllowed) ↓ 建立桥接连接 (bridgeMain) ``` ### 10.4 会话管理 ```typescript // bridge/types.ts export type SessionSpawnOpts = { sessionId?: string spawnMode?: 'foreground' | 'background' spawnCount?: number sessionTimeoutMs?: number } export type SessionHandle = { sessionId: string workSecret: string sdkUrl: string cleanup: () => Promise } ``` --- ## 11. 服务层 ### 11.1 API 服务 ``` services/api/ ├── client.ts # Anthropic API 客户端 ├── claude.ts # Claude 特定逻辑 ├── bootstrap.ts # 初始化 ├── errors.ts # 错误处理 ├── filesApi.ts # 文件 API ├── grove.ts # Grove 集成 ├── logging.ts # 日志 ├── usage.ts # 使用统计 └── withRetry.ts # 重试逻辑 ``` ### 11.2 MCP 服务 Model Context Protocol 实现: ``` services/mcp/ ├── client.ts # MCP 客户端 ├── config.ts # 配置 ├── auth.ts # 认证 ├── oauthPort.ts # OAuth 端口 ├── types.ts # 类型定义 ├── utils.ts # 工具函数 ├── xaa.ts # XAA 集成 ├── claudeai.ts # Claude AI 集成 └── utils.ts ``` ### 11.3 OAuth 服务 ``` services/oauth/ ├── client.ts # OAuth 客户端 ├── crypto.ts # 加密工具 └── index.ts # 导出 ``` ### 11.4 Analytics 服务 ``` services/analytics/ ├── sink.ts # 数据汇 ├── datadog.js # DataDog 集成 ├── growthbook.js # GrowthBook 特性开关 ├── firstPartyEventLogger.js # 第一方事件日志 └── index.js ``` ### 11.5 LSP 服务 Language Server Protocol 实现: ``` services/lsp/ ├── LSPClient.ts # LSP 客户端 ├── config.ts # 配置 └── manager.ts # 管理器 ``` --- ## 12. 数据流 ### 12.1 请求生命周期 ``` 用户输入 ↓ PromptInput 接收输入 ↓ 命令解析 (/command 或普通文本) ↓ 创建 UserMessage ↓ 添加消息到状态 (setAppState) ↓ 调用 query() 函数 ↓ 构建 API 请求 ↓ Anthropic API 调用 ↓ 流式响应处理 ↓ 工具调用检测 ↓ 执行工具 (tool use) ↓ 继续响应或完成 ↓ 更新消息状态 ↓ 渲染消息 ``` ### 12.2 工具调用流 ``` API 响应包含 tool_use ↓ 提取工具信息 (name, input) ↓ 检查权限 (toolPermissionContext) ↓ 请求用户确认 (如果需要) ↓ 执行工具 (tool.execute()) ↓ 获取工具结果 ↓ 添加到消息历史 ↓ 发送 tool_result 回到 API ↓ 继续响应流 ``` ### 12.3 消息流 ``` ┌─────────┐ UserMessage ┌─────────┐ │ 用户 │ ───────────────→ │ 状态 │ └─────────┘ └─────────┘ ↓ ┌─────────┐ ┌─────────────┐ │ API │ ←───────────── │ query() │ └─────────┘ 请求 └─────────────┘ ↓ ┌─────────┐ ┌─────────────┐ │ 流式 │ ─────────────→ │ 状态更新 │ │ 响应 │ AssistantMsg │ + 渲染 │ └─────────┘ └─────────────┘ ``` ### 12.4 状态更新流 ``` Action 触发 (用户输入、API 响应) ↓ setAppState(update) ↓ 计算新状态 ↓ 通知所有订阅者 ↓ 相关组件重渲染 ↓ UI 更新 ``` --- ## 13. 关键技术 ### 13.1 Dead Code Elimination (DCE) 通过 `feature()` 函数和条件导入实现构建时代码消除: ```typescript // Feature Flag 定义 if (feature('FEATURE')) { require('./feature.js') } // 环境变量检查 if (process.env.USER_TYPE === 'ant') { // Ant 专用代码 } ``` ### 13.2 流式响应处理 ```typescript // services/api/claude.ts const stream = await client.messages.stream({ model: params.model, max_tokens: params.maxTokens, messages: params.messages, tools: params.tools, }) for await (const event of stream) { if (event.type === 'message_delta') { // 处理 token } else if (event.type === 'content_block_delta') { // 处理增量内容 } } ``` ### 13.3 权限模型 ```typescript // utils/permissions/permissionSetup.ts export function createPermissionContext( settings: PermissionSettings ): ToolPermissionContext { return { isBypassPermissionsModeAvailable: settings.bypassMode, denyRules: settings.denyRules ?? [], allowRules: settings.allowRules ?? [], } } // 工具过滤 export function filterToolsByDenyRules( tools: Tool[], context: ToolPermissionContext ): Tool[] { return tools.filter(tool => !getDenyRuleForTool(context, tool)) } ``` ### 13.4 MCP 协议 ```typescript // services/mcp/client.ts export class MCPClient { private connection: JSONRPCConnection async initialize(): Promise { await this.connection.sendRequest('initialize', { protocolVersion: '2024-11-05', capabilities: { ... } }) } async listTools(): Promise { const response = await this.connection.sendRequest( 'tools/list', {} ) return response.tools } async callTool(name: string, args: object): Promise { return this.connection.sendRequest('tools/call', { name, arguments: args }) } } ``` ### 13.5 终端渲染优化 ```typescript // ink/renderer.ts export class Renderer { private reconciler: FiberRoot render(element: ReactElement): void { updateContainer(element, this.reconciler, null) } private framesPerSecond: number private lastFrame: number frame(): void { const now = performance.now() const delta = now - this.lastFrame if (delta >= 1000 / this.framesPerSecond) { this.flushUpdates() this.lastFrame = now } requestAnimationFrame(() => this.frame()) } } ``` --- ## 附录 ### A. 关键文件索引 | 文件 | 说明 | |------|------| | [cli.tsx](src/entrypoints/cli.tsx) | CLI 入口 | | [main.tsx](src/main.tsx) | 主程序入口 | | [REPL.tsx](src/screens/REPL.tsx) | REPL 界面 | | [tools.ts](src/tools.ts) | 工具系统 | | [commands.ts](src/commands.ts) | 命令系统 | | [AppState.tsx](src/state/AppState.tsx) | 状态管理 | | [bridgeMain.ts](src/bridge/bridgeMain.ts) | 桥接主入口 | | [client.ts](src/services/api/client.ts) | API 客户端 | ### B. 环境变量 | 变量 | 说明 | |------|------| | `ANTHROPIC_API_KEY` | API Key | | `ANTHROPIC_BASE_URL` | API 端点 | | `ANTHROPIC_MODEL` | 默认模型 | | `DISABLE_TELEMETRY` | 禁用遥测 | | `CLAUDE_CODE_SIMPLE` | 简单模式 | | `USER_TYPE` | 用户类型 (ant/external) | --- *文档版本:1.0.0* *最后更新:2026-04-02*