ed91e47107
- 添加项目配置文件(tsconfig.json、bunfig.toml、.gitignore、.env.example) - 创建文档架构图(00runtime.png 至 08-state-data-flow.png) - 添加核心工具常量定义(FileEditTool、AgentTool、BashTool 等) - 实现基础命令框架(help、exit、config、model 等) - 添加 Ink TUI 组件库和布局引擎 - 包含内存管理、沙箱、shell 工具等基础工具类 - 设置预加载脚本和版本信息
961 lines
25 KiB
Markdown
961 lines
25 KiB
Markdown
# 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*
|