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

961 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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<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 工具注册与过滤
```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<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 命令注册
```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<CommandResult>
}
```
---
## 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<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 会话管理
```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<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()` 函数和条件导入实现构建时代码消除:
```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<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 终端渲染优化
```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*