Files
claude-code/.trae/documents/ARCHITECTURE.md
T
Serendipity ed91e47107 feat: 初始化项目结构与核心文件
- 添加项目配置文件(tsconfig.json、bunfig.toml、.gitignore、.env.example)
- 创建文档架构图(00runtime.png 至 08-state-data-flow.png)
- 添加核心工具常量定义(FileEditTool、AgentTool、BashTool 等)
- 实现基础命令框架(help、exit、config、model 等)
- 添加 Ink TUI 组件库和布局引擎
- 包含内存管理、沙箱、shell 工具等基础工具类
- 设置预加载脚本和版本信息
2026-04-02 17:13:04 +08:00

25 KiB
Raw Blame History

Claude Code Haha 架构文档

本文档详细分析 Claude Code Haha 项目的架构设计、核心模块以及数据流动方式。

目录

  1. 概述
  2. 整体架构
  3. 入口与启动
  4. 交互层(TUI
  5. Ink 渲染引擎
  6. 工具系统
  7. 命令系统
  8. Skill 系统
  9. 状态管理
  10. 桥接与远程控制
  11. 服务层
  12. 数据流
  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(代码消除):

// 启用特性
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 的跨平台布局引擎)进行布局计算:

// 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 基类:

// Tool.ts
export type Tool = {
  name: string
  description: string
  allowedTools?: string[]
  isEnabled?: () => boolean
  prompt?: ToolPrompt
  UI?: ToolUIComponent
  execute?: (context: ToolUseContext) => Promise<ToolResult>
}

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 工具注册与过滤

// 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 工具权限

工具调用需要权限确认:

// 权限类型
type ToolPermission = {
  tool: string
  args: Record<string, unknown>
  reason?: string
  autoApprove?: boolean
}

// 权限检查
function checkToolPermission(tool: string): boolean
function requestToolPermission(tool: string): Promise<boolean>

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 命令注册

// 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 命令类型

type Command = {
  name: string
  description: string
  aliases?: string[]
  type: 'prompt' | 'action' | 'navigation'
  execute: (args: string, context: CommandContext) => Promise<CommandResult>
}

8. Skill 系统

8.1 概述

Skill 是封装好的任务模板,可以被 AI Agent 调用。

8.2 内置 Skills

Skill 说明 用途
verify 验证代码修改 自动化验证
batch 批量处理 批量任务执行
loop 循环执行 重复任务
debug 调试助手 问题诊断
simplify 代码简化 重构辅助
stuck 困境解脱 遇到问题时提供帮助
updateConfig 配置更新 配置文件修改
remember 记忆管理 知识库操作
scheduleRemoteAgents 远程调度 分布式任务

8.3 Skill 注册

// 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 需要将文件提取到磁盘:

// 首次调用时提取
const files = await extractBundledSkillFiles(skillName, filesDefinition)
// 模型可以 Read/Grep 这些文件

9. 状态管理

9.1 AppStateStore

使用 React 的 useSyncExternalStore 实现全局状态管理:

// 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 结构

// 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 状态选择器

使用选择器模式避免不必要的重渲染:

// 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

// state/AppState.tsx
export function useAppState<T>(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 会话管理

// 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<void>
}

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() 函数和条件导入实现构建时代码消除:

// Feature Flag 定义
if (feature('FEATURE')) {
  require('./feature.js')
}

// 环境变量检查
if (process.env.USER_TYPE === 'ant') {
  // Ant 专用代码
}

13.2 流式响应处理

// 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 权限模型

// 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 协议

// services/mcp/client.ts
export class MCPClient {
  private connection: JSONRPCConnection
  
  async initialize(): Promise<void> {
    await this.connection.sendRequest('initialize', {
      protocolVersion: '2024-11-05',
      capabilities: { ... }
    })
  }
  
  async listTools(): Promise<Tool[]> {
    const response = await this.connection.sendRequest(
      'tools/list',
      {}
    )
    return response.tools
  }
  
  async callTool(name: string, args: object): Promise<ToolResult> {
    return this.connection.sendRequest('tools/call', {
      name,
      arguments: args
    })
  }
}

13.5 终端渲染优化

// 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 CLI 入口
main.tsx 主程序入口
REPL.tsx REPL 界面
tools.ts 工具系统
commands.ts 命令系统
AppState.tsx 状态管理
bridgeMain.ts 桥接主入口
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