# OpenClaude 0.11.0 源码全貌参考

> **本文档定位**：OpenClaude（[Gitlawb/openclaude](https://github.com/Gitlawb/openclaude)，约 26k stars）是 Claude Code 的开源 fork，把单一 Anthropic 客户端改造成 **200+ provider 通用 coding agent**。本文是从源码出发的逐目录架构解构，可作为对照官方 Claude Code 内核的 "对位实现"。
>
> **报告生成方式**：从 `https://github.com/Gitlawb/openclaude` clone 最新 main（v0.11.0，2026-05-14 release），共 2451 个 .ts/.tsx/.py/.js 源文件、38 个 src/ 子目录、49 个内置工具。5 个并行 Explore agent 分工扫描后合成本文。
>
> **使用方式**：自研 agent 设计时遇到具体子系统（多 provider 路由 / IDE 桥接 / TUI 渲染 / skills 注入）时，回查对应章节。也可作为 Claude Code 2.1.88 内核 ([`claude-code-reference.md`](./claude-code-reference.md)) 的 **多 provider 对照实现**——OpenClaude 在保留 Claude Code 内核（main.tsx / query / Tool / hooks / skills / bridge / coordinator）的同时，新增了 `integrations/`、`grpc/`、`proto/`、`outputStyles/`、`vim/`、独立 `web/`、`vscode-extension/`、`python/` 这 8 块。

---

## 顶层架构总览

> 一图读 OpenClaude 0.11.0 全貌。从下往上：底层多 provider → 内核引擎 → 扩展能力 → 用户接口；从左往右：CLI/IDE → Web → 移动端。

```
╔══════════════════════════════════════════════════════════════════════════════════════════════╗
║                  用户接入层（Surface）                                                        ║
║  ┌──────────────┐  ┌─────────────────┐  ┌────────────┐  ┌───────────────┐  ┌──────────────┐ ║
║  │ CLI (Ink TUI)│  │ VSCode Ext      │  │ Web UI     │  │ gRPC Client   │  │ Python SDK   │ ║
║  │ openclaude  │  │ vscode-ext/     │  │ web/       │  │ grpc-cli      │  │ python/      │ ║
║  └──────┬───────┘  └────────┬────────┘  └─────┬──────┘  └───────┬───────┘  └──────┬───────┘ ║
╚═════════│═════════════════════│════════════════│═════════════════│══════════════════│═════════╝
          │                     │                │                 │                  │
          │                     │ HTTP poll      │ WS / fetch      │ gRPC            │ subprocess
          │                     ▼                ▼                 ▼                  ▼
          │           ┌──────────────────────────────────────────────────────────────────┐
          │           │  接口接入层  bridge/  remote/  server/  grpc/+proto/             │
          │           │  统一收敛到 entrypoints/{cli,sdk,mcp}                            │
          │           └────────────────────────┬─────────────────────────────────────────┘
          │                                    │
          ▼                                    ▼
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
│  内核引擎  Kernel                                                                            │
│   main.tsx (REPL React)  →  query.ts / QueryEngine.ts  →  Tool.ts / tools/ (49 工具)        │
│   ├─ coordinator/  (多 agent 协调，fork+resume)                                              │
│   ├─ tasks/         (后台任务框架)                                                           │
│   ├─ assistant/     (会话历史)                                                               │
│   ├─ buddy/         (AI 伴侣 / 旁观者)                                                       │
│   └─ hooks/         (90+ 文件钩子系统：每个生命周期都可插)                                    │
└─────────────────────────────────────────┬───────────────────────────────────────────────────┘
                                          │
       ┌──────────────────────────────────┼──────────────────────────────────┐
       │                                  │                                  │
       ▼                                  ▼                                  ▼
┌──────────────────┐              ┌─────────────────┐                ┌───────────────────┐
│ 扩展能力          │              │ 渲染与交互       │                │ 配置与状态         │
│ skills/  plugins/│              │ ink/  components/│                │ memdir/ migrations│
│ commands/        │              │ screens/         │                │ state/  context/  │
│ outputStyles/    │              │ keybindings/ vim/│                │ schemas/ types/   │
│ voice/  moreright│              │                  │                │ constants/        │
└──────────────────┘              └─────────────────┘                └───────────────────┘
                                          │
                                          ▼
╔══════════════════════════════════════════════════════════════════════════════════════════════╗
║  多 Provider 路由层  integrations/  upstreamproxy/  (★ OpenClaude 核心差异化)                ║
║                                                                                              ║
║  Profile (用户配置)                                                                          ║
║       ▼                                                                                      ║
║  ProfileResolver  →  Registry (vendors × gateways)  →  RouteMetadata  →  Compatibility      ║
║       ▼                                                                                      ║
║  Vendor Descriptor (define.ts) + Gateway Adapter                                             ║
║       ▼                                                                                      ║
║  Upstream Proxy (转译 OpenAI ↔ Anthropic / Gemini / 本地协议)                               ║
║       ▼                                                                                      ║
║  ┌─────────┬──────────┬─────────┬────────┬────────┬────────┬──────────┬───────┬──────────┐ ║
║  │ Anthr.  │ OpenAI   │ Google  │ DeepS. │ Groq   │ Mistral│ Together │ NIM   │ Ollama   │ ║
║  │ + 11 家 │ + 18 网关 (OpenRouter / Together / NIM / Venice / MiMo …) + 200+ 模型        │ ║
║  └─────────┴──────────┴─────────┴────────┴────────┴────────┴──────────┴───────┴──────────┘ ║
╚══════════════════════════════════════════════════════════════════════════════════════════════╝
```

---

## 目录

- **[Part I — 内核与工具层](#part-i--内核与工具层)**：main.tsx / query / Tool / 49 内置工具 / coordinator / tasks / assistant / buddy
- **[Part II — 多 Provider 路由系统](#part-ii--多-provider-路由系统-openclaude-核心差异化)** ★：integrations / upstreamproxy / provider scripts
- **[Part III — UI 与命令层](#part-iii--ui-与命令层)**：commands / keybindings / ink / components / screens / outputStyles / vim / voice
- **[Part IV — 扩展性与接口层](#part-iv--扩展性与接口层)**：skills / plugins / hooks / bridge / remote / server / grpc / web / vscode-extension / python
- **[Part V — 基础设施与杂项层](#part-v--基础设施与杂项层)**：cli / entrypoints / bootstrap / state / memdir / schemas / types / constants / migrations / services / utils / 启动脚本 / Android
- **[附录 A — 与 Claude Code 2.1.88 的差异点汇总](#附录-a--与-claude-code-2188-的差异点汇总)**
- **[附录 B — 自研 Agent 内核可借鉴清单](#附录-b--自研-agent-内核可借鉴清单)**

---

# Part I — 内核与工具层


## 架构流动图

```
┌──────────────────────────────────────────────────────────────────────┐
│                                                                      │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                  main.tsx (React 根组件)                      │   │
│  │          [4677 行] — 启动、CLI 解析、REPL 初始化            │   │
│  └────────────────────────┬────────────────────────────────────┘   │
│                           │                                         │
│                           ▼                                         │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │          replLauncher.tsx → ink.ts (终端 UI)                │   │
│  │       渲染消息流、用户输入、工具调用界面                     │   │
│  └────────────────────────┬────────────────────────────────────┘   │
│                           │                                         │
│                           ▼                                         │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │            query() —— query.ts [1914 行]                    │   │
│  │  用户输入 → 消息准备 → API 调用 → 工具执行循环              │   │
│  │  - 消息构建（用户 / 系统 / 上下文）                        │   │
│  │  - token 预算跟踪                                          │   │
│  │  - 自动 compact 触发                                       │   │
│  │  - 权限检查集成                                            │   │
│  └────────────────────────┬────────────────────────────────────┘   │
│                           │                                         │
│              ┌────────────┼────────────┐                            │
│              ▼            ▼            ▼                            │
│  ┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐    │
│  │  query.ts      │ │ QueryEngine.ts  │ │ 权限系统         │    │
│  │  消息流机制     │ │ SDK 模式集成    │ │ Tool.ts / 检验  │    │
│  │  (1914 行)     │ │ (1430 行)       │ │ Permission API  │    │
│  └────────────────┘ └─────────────────┘ └──────────────────┘    │
│                           │                                         │
│              ┌────────────┴────────────┐                            │
│              ▼                         ▼                            │
│  ┌───────────────────────┐  ┌─────────────────────────────────┐   │
│  │  API 调用             │  │  Tool 执行引擎                  │   │
│  │  /messages            │  │  StreamingToolExecutor          │   │
│  │  (claude API)         │  │  (runTools via             │   │
│  │                       │  │   toolOrchestration)            │   │
│  └───────────────────────┘  └────────────────────────────────┘   │
│              │                         │                           │
│              └────────────┬────────────┘                           │
│                           ▼                                         │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │          tools.ts —— 工具池 [386 行]                        │   │
│  │  getTools()                                                │   │
│  │  - 49 个内置工具（BashTool, FileEditTool, ..., Skill...）  │   │
│  │  - MCP 工具集成 (ListMcpResourcesTool, ...)                 │   │
│  │  - 权限过滤 (filterToolsByDenyRules)                       │   │
│  │  - 工具池组装 (assembleToolPool)                           │   │
│  └────────────────────────┬────────────────────────────────────┘   │
│                           │                                         │
│              ┌────────────┴────────────┐                            │
│              ▼                         ▼                            │
│  ┌─────────────────────────┐  ┌────────────────────────────────┐  │
│  │   src/tools/ [49 文件]  │  │   MCP 工具 (MCP 服务器)       │  │
│  │                         │  │   ListMcpResourcesTool        │  │
│  │ 核心类：                │  │   ReadMcpResourceTool         │  │
│  │ - AgentTool            │  │   MCPTool                      │  │
│  │ - BashTool             │  │                               │  │
│  │ - FileRead/Edit/Write  │  └────────────────────────────────┘  │
│  │ - WebSearch/WebFetch   │                                       │
│  │ - TaskCreate/Update    │                                       │
│  │ - SkillTool            │                                       │
│  └─────────────────────────┘                                       │
│                           │                                         │
│              ┌────────────┴────────────┐                            │
│              ▼                         ▼                            │
│  ┌──────────────────────────────┐ ┌────────────────────────────┐  │
│  │  工具执行结果                 │ │  coordinator/ [387 行]      │  │
│  │  - 返回到 query 循环         │ │  多 Agent 协调              │  │
│  │  - 下一回合准备              │ │  - Worker 生成 (AgentTool)  │  │
│  │  - 历史持久化                │ │  - 工具权限分配             │  │
│  └──────────────────────────────┘ │  - 消息路由                 │  │
│                                    └────────────────────────────┘  │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘
```

---

## 一、main.tsx —— React REPL 主组件与状态机

**职责**
- 启动入口：CLI 参数解析，配置加载，认证初始化
- React 应用根：useState 管理全局状态，消息队列，UI 事件监听
- 生命周期：工具链接，历史恢复，信号处理，graceful shutdown
- 性能监测：启动时间探针，首次 API 调用延迟追踪，成本统计

**关键文件与 LOC**
- `src/main.tsx` (4677 行) — 最大的单一文件，包含 React 组件定义、事件处理器、副作用 hooks
- `src/replLauncher.tsx` (22 行) — 轻量级启动器，调用 main 中的 `launchRepl()`
- `src/ink.ts` (85 行) — ink 库初始化与配置
- `src/interactiveHelpers.tsx` (375 行) — 对话式 UI 辅助（对话框、屏幕、错误展示）

**核心数据结构**
```typescript
// main.tsx 中的全局状态树（React Context via AppState）
type AppState = {
  messages: Message[]          // 对话历史
  activeMessageId?: string     // 当前选中消息（恢复/编辑）
  mcp: { tools: Tool[], ... }  // MCP 服务器与工具列表
  stats: StatsStore            // cost / token / API duration 追踪
  flags: {                      // 命令行标志缓存
    verbose: boolean
    debug: boolean
    model?: string
    ...
  }
}

// 消息流类型（从 types/message.ts）
type Message = 
  | UserMessage              // 用户输入 + 粘贴内容
  | AssistantMessage         // Claude 响应 + 工具调用块
  | AttachmentMessage        // 文件变更、MCP 资源、记忆体
  | ProgressMessage          // 工具执行进度
  | SystemLocalCommandMessage // Bash/本地命令输出
```

**调用链**
1. `main()` CLI 启动 → `launchRepl()` → React render loop
2. 用户输入 event → `useQueueProcessor()` hook 拦截 → 入队消息
3. `processSlashCommand()` 处理 `/help`, `/config` 等（本地，无 query）
4. 普通提示 → 入队到消息队列 → `query()` 调用（异步）
5. `query()` 返回工具块流 → 执行工具 → 结果作为新消息 append
6. React state 更新 → 屏幕重绘 → 用户看到工具进度与结果

**可借鉴点**
- **React 并发友好**：消息队列与 async generator 配合避免阻塞渲染
- **性能优化**：启动时在后台并行化（MDM 读、Keychain 预取、MCP 连接）
- **权限与 hooks 整合**：useCanUseTool() 在 query 执行前检查，同时维护 denial tracking
- **多模式支持**：SDK、print、REPL 通过功能开关（feature gates）同一代码库实现

---

## 二、query.ts —— 查询主引擎 [1914 行]

**职责**
- 消息准备：构建用户 + 系统 + 上下文消息，应用 compaction
- API 调用：调度 /messages, 处理流式响应，token budget 跟踪
- 工具循环：从 API 解析工具块，决定并发 vs 顺序执行
- 权限与 hooks：前置 hooks、工具权限检查、后置 hooks 执行
- 自动 compact：检测 token 警告状态，触发消息压缩

**关键文件与 LOC**
- `src/query.ts` (1914 行) — 核心 async generator，yield 消息 / 工具进度
- `src/query/*.ts` — 模块化辅助
  - `config.ts` — buildQueryConfig()
  - `deps.ts` — ProductionDeps（注入模式）
  - `tokenBudget.ts` — token 预算追踪
  - `transitions.ts` — 终止条件（Terminal | Continue）
  - `stopHooks.ts` — 停止时 hooks

**核心数据结构**
```typescript
// query() 签名
async function* query(
  userMessage: string,
  toolUseContext: ToolUseContext,  // Tools, commands, permission context
  querySource: 'repl_main_thread' | 'sdk' | ...,
  queryDeps?: QueryDeps,
): AsyncGenerator<
  StreamEvent | Message | ToolUseSummaryMessage,
  Terminal | Continue,  // 最终返回值：停止 or 继续
  undefined
>

// StreamEvent = API 流事件（streaming messages）
// Message = 工具结果、附件等
// ToolUseSummaryMessage = 工具执行总结
```

**调用链**
1. main.tsx / QueryEngine.ts 调用 `query(userMessage, context)`
2. 准备消息：
   - fetchSystemPromptParts() → 获取 system prompt
   - prependUserContext() + appendSystemContext() → 注入 git status、claudeMd
   - createAttachmentMessages() → 粘贴内容、文件变更、MCP 资源
   - 内存 prefetch 消费
3. 检查 token 预算：
   - calculateTokenWarningState() 判断是否触发 auto-compact
   - 若是，buildPostCompactMessages() 压缩历史
4. 调用 API（via claude.ts）：`messages.create({ model, messages, tools, ... })`
5. 处理流响应（for await of response）：
   - 累积工具块 → parseToolUseBlocks()
   - 执行工具：runTools() 并发执行，捕获结果
   - 生成工具摘要（optional）：generateToolUseSummary()
   - 检查结束原因（stop_reason）：
     - 'end_turn' → 返回 Terminal
     - 'tool_use' → 下一轮继续
     - 'max_tokens' → 检查 budget，可能 continue
6. Yield 结果给 main.tsx → 显示在 UI

**可借鉴点**
- **迭代器复用**：AsyncGenerator 使多个"轮数"（工具调用循环）流畅表达
- **权限透明性**：Tool 检查 + 前置 hooks（auto-deny for background agents） = 无提示快速路径
- **Streaming 设计**：工具块到达时立即 yield，不等整个响应完成 → 低延迟 UI
- **Compaction 集成**：token 预算在循环开始检查，无缝 compact 历史后继续

---

## 三、QueryEngine.ts —— SDK 与多模式适配 [1430 行]

**职责**
- SDK 兼容性：规范化 SDK 消息格式（SDKMessage → Message），处理回放、compact 边界
- 多模式网关：REPL / print / SDK 统一入口，特定模式的定制处理
- 会话持久化：加载 / 保存会话，断点恢复（teleport, CCR）
- 配置注入：model override、prompt override、permission mode 配置

**关键文件与 LOC**
- `src/QueryEngine.ts` (1430 行) — 主类，synchronous wrapper around query.ts
- 与 `query.ts` 的关系：
  - query.ts = 单次 turn 的 async generator
  - QueryEngine = 会话级别的循环包装器，管理历史与状态

**核心数据结构**
```typescript
// SDK 消息映射
type SDKMessage = 
  | { type: 'user', text: string, attachments?: ... }
  | { type: 'assistant', text: string, tool_use?: { id, name, input } }
  | { type: 'user_replay', ... }  // 恢复时的重放块

// QueryEngine 初始化参数
interface QueryEngineInit {
  appState: AppState
  setAppState: (f: AppState => AppState) => void
  toolUseContext: ToolUseContext
  permissionContext: ToolPermissionContext
  modelUsageByModel: Map<string, Usage>  // cost tracking
  mcpClients: MCPServerConnection[]
  // ... 其他上下文
}

// 会话状态（持久化到 ~/.claude/sessions/）
type SessionSnapshot = {
  messages: Message[]
  stats: { cost, tokens, duration }
  sessionMode: 'normal' | 'coordinator'  // SDK 新增
  // ... metadata
}
```

**调用链**
1. main.tsx 或 SDK entrypoint 创建 QueryEngine 实例
2. `engine.processUserMessage(input)` 入口
3. 规范化输入（若来自 SDK，反序列化 SDKMessage → Message）
4. 调用 `query(input, context)` generator，逐个 yield 处理
5. 会话持久化：
   - 消息 append 到 ~/.claude/sessions/SESSION_ID.json
   - cost / token 累积到 cost-tracker.ts
   - 在 shutdown 时 flush
6. 模式特定处理：
   - SDK：返回 SDKMessage[], 不显示 REPL UI
   - Print：纯文本输出，无交互
   - REPL：完整 React UI，实时进度

**可借鉴点**
- **分层抽象**：query() 处理单次循环逻辑，QueryEngine 处理会话状态 → 关注点分离
- **SDK 适配**：统一代码路径，通过模式开关处理输出格式差异
- **持久化简洁**：JSON 序列化 Message[]，加载时反序列化，无 ORM
- **Cost 追踪**：模型使用量字典，支持多模型混用计费

---

## 四、Tool.ts —— 工具注册与权限框架 [807 行]

**职责**
- 类型定义：Tool 接口、ToolInputJSONSchema、工具属性（name, description, inputSchema）
- 权限模型：ToolPermissionContext（mode, rules 集合），getEmptyToolPermissionContext()
- 工具查询：findToolByName(), toolMatchesName()（支持别名与模糊匹配）
- 进度与通知：ToolProgressData 联合类型，MCP / Agent / Bash 等专用进度

**关键文件与 LOC**
- `src/Tool.ts` (807 行) — 接口 + 权限类型定义
- 与 tools.ts 的关系：
  - Tool.ts = 接口定义
  - tools.ts = 实现与工具池管理

**核心数据结构**
```typescript
export type Tool = {
  name: string
  description: string
  inputSchema: ToolInputJSONSchema
  isEnabled?: () => boolean  // Feature gate
  mcpInfo?: { serverName: string; toolName: string }
  execute(
    input: unknown,
    context: ToolUseContext,
  ): Promise<ToolResult | AsyncIterable<ToolResult>>
}

export type ToolPermissionContext = DeepImmutable<{
  mode: 'default' | 'bypass' | 'auto' | 'scripted' | 'ask'
  additionalWorkingDirectories: Map<string, AdditionalWorkingDirectory>
  alwaysAllowRules: ToolPermissionRulesBySource  // { 'tool_name': { ... } }
  alwaysDenyRules: ToolPermissionRulesBySource
  alwaysAskRules: ToolPermissionRulesBySource
  isBypassPermissionsModeAvailable: boolean
  awaitAutomatedChecksBeforeDialog?: boolean  // Coordinator 用
  prePlanMode?: PermissionMode  // Plan mode 前的模式备份
}>

export type ToolProgressData = 
  | BashProgress             // exit_code, stdout_preview, ...
  | AgentToolProgress        // agent_id, output_summary, ...
  | WebSearchProgress        // query, results_count, ...
  | MCPProgress              // server_name, operation, ...
  | SkillToolProgress        // skill_name, status, ...
  | REPLToolProgress
  | TaskOutputProgress
```

**调用链**
1. tools.ts 定义 Tool[] 数组 → Anthropic API 的 tools param
2. query() 中解析 API 响应的 tool_use 块
3. findToolByName() 查询工具定义
4. 权限检查（useCanUseTool hook）→ ToolPermissionContext 评估规则
5. tool.execute(input, context) → 异步执行
6. 结果转为 ToolResult → 构建 tool_result message

**可借鉴点**
- **权限模型清晰**：分离 allow / deny / ask 规则，支持模式级别与工具级别
- **异步 iterator 支持**：工具可流式返回结果 → 大输出不阻塞
- **MCP 集成点**：mcpInfo 字段标记远程工具，与内置工具无缝混合

---

## 五、tools.ts —— 工具池管理 [386 行]

**职责**
- 工具注册：getAllBaseTools() 返回 49 个内置工具的完整列表
- 条件启用：feature gates、permission 过滤、mode 判断
- MCP 集成：assembleToolPool() 与 getMergedTools() 组合内置 + MCP 工具
- 工具搜索：isToolSearchEnabledOptimistic() 决定是否启用 Tool Search 工具

**关键文件与 LOC**
- `src/tools.ts` (386 行) — 唯一的工具注册清单

**49 个内置工具分类**

### 1. **核心文件操作** (5)
- **FileReadTool** — 读取文件内容
- **FileEditTool** — 编辑文本文件（行级别修改）
- **FileWriteTool** — 创建或覆盖文件
- **GlobTool** — 文件搜索（glob 模式）
- **GrepTool** — 正则搜索文件内容

### 2. **执行与 Shell** (5)
- **BashTool** — 执行 Bash 命令
- **PowerShellTool** — Windows PowerShell（条件启用）
- **NotebookEditTool** — Jupyter notebook 编辑
- **LSPTool** — 语言服务器协议（code intelligence）
- **REPLTool** — 内部虚拟机（--bare 模式）

### 3. **AI 与 Agent** (6)
- **AgentTool** — 生成子 Agent / Worker（coordinator 核心）
- **SkillTool** — 调用项目 skills（slash 命令包装）
- **AskUserQuestionTool** — 向用户提问（交互式）
- **BriefTool** — 生成执行摘要
- **SendMessageTool** — 向 Worker 发送消息（coordinator）
- **TaskOutputTool** — 获取后台任务输出

### 4. **Web 与网络** (4)
- **WebSearchTool** — Web 搜索（Brave, Bing, DuckDuckGo 等）
- **WebFetchTool** — 获取网页内容
- **ListMcpResourcesTool** — 列出 MCP 资源
- **ReadMcpResourceTool** — 读取 MCP 资源

### 5. **任务与工作流** (8)
- **TaskCreateTool** — 创建后台任务
- **TaskGetTool** — 获取任务详情
- **TaskUpdateTool** — 更新任务
- **TaskListTool** — 列出所有任务
- **TaskStopTool** — 停止任务（同时停止工作的 Agent）
- **EnterPlanModeTool** — 进入计划模式
- **ExitPlanModeTool** — 退出计划模式
- **VerifyPlanExecutionTool** — 验证计划执行（条件）

### 6. **团队协作** (2)
- **TeamCreateTool** — 创建 Agent 团队（agent swarms）
- **TeamDeleteTool** — 删除团队

### 7. **工作树与隔离** (2)
- **EnterWorktreeTool** — 创建 git worktree 分支
- **ExitWorktreeTool** — 删除 worktree

### 8. **IDE 与编程工具** (3)
- **TodoWriteTool** — 管理 todo 列表
- **ToolSearchTool** — 搜索可用工具（工具发现）
- **MonitorTool** — 后台进程监控（流式输出）

### 9. **特殊与诊断** (8)
- **SyntheticOutputTool** — 工具摘要与输出合成
- **ScheduleCronTool (3 个)** — Cron 计划
  - CronCreateTool
  - CronDeleteTool
  - CronListTool
- **RemoteTriggerTool** — 远程触发（条件）
- **WorkflowTool** — 工作流脚本（条件）
- **SleepTool** — 延迟（内部）
- **MCPTool** — 通用 MCP 工具包装

### 10. **实验与内部** (6)
- **WebBrowserTool** — 浏览器自动化（实验）
- **OverflowTestTool** — 超限测试（诊断）
- **CtxInspectTool** — 上下文检查（实验）
- **TerminalCaptureTool** — 终端捕获（实验）
- **SnipTool** — 历史片段（实验）
- **ListPeersTool** — 列出同行 agents（实验）

**调用链**
1. `getTools(permissionContext)` → 返回可用工具列表
   - 适用 feature gates（简单模式、REPL 模式等）
   - 过滤 deny 规则 → filterToolsByDenyRules()
   - 启用检查 → tool.isEnabled()
2. `assembleToolPool(context, mcpTools)` → 合并内置 + MCP 工具
   - 按名称排序 → prompt cache 稳定
   - uniqBy 去重（内置优先级更高）
3. tools 传入 API → Anthropic /messages 端点
4. 工具执行时 → findToolByName() 查询 Tool 定义，调用 execute()

**可借鉴点**
- **Feature Gate 灵活性**：同一代码库支持 10+ 个特性变体（COORDINATOR_MODE, KAIROS, WORKFLOW_SCRIPTS 等）
- **MCP 透明集成**：内置 + MCP 工具无缝混合，按名称去重
- **启用检查分阶段**：getAllBaseTools() 返回全集（用于缓存），getTools() 应用过滤

---

## 六、coordinator/ —— 多 Agent 协调系统 [387 行]

**职责**
- Coordinator 角色定义：master agent 指挥 worker agents 完成任务
- Worker 工具限制：定义 ASYNC_AGENT_ALLOWED_TOOLS，coordinator 可委派给 worker 的工具
- 系统提示注入：getCoordinatorSystemPrompt() 告知 coordinator 其角色 + 工具
- 用户上下文补充：getCoordinatorUserContext() 告知 worker 可用工具列表

**关键文件与 LOC**
- `src/coordinator/coordinatorMode.ts` (369 行) — 核心配置与检查
- `src/coordinator/workerAgent.ts` (18 行) — Worker 类型（轻量级）

**核心数据结构**
```typescript
// Coordinator 模式检查
export function isCoordinatorMode(): boolean {
  return feature('COORDINATOR_MODE') && isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)
}

// Worker 可用工具列表
const ASYNC_AGENT_ALLOWED_TOOLS = new Set([
  'bash',           // 执行
  'read',           // 文件读
  'edit',           // 文件编辑
  'write',          // 文件写
  'web_search',     // 网络
  'web_fetch',
  'skill',          // 项目 skills
  'agent',          // 可递归生成子 worker
  'task_*',         // 任务管理
  // ... 约 25 个工具
])

const INTERNAL_WORKER_TOOLS = new Set([
  'team_create',
  'team_delete',
  'send_message',
  'synthetic_output',
])  // 不对 worker 公开，仅 coordinator 用
```

**调用链**
1. main.tsx 启动时检查 COORDINATOR_MODE 环境变量
2. 若启用 → matchSessionMode() 检查会话是否一致
3. QueryEngine 调用 getCoordinatorUserContext() → 注入 Worker 工具列表到系统提示
4. API 返回 agent_tool 调用 → query.ts 检查 AgentTool 定义
5. AgentTool.execute() 创建子进程 agent：
   - 创建独立 AppState 副本
   - 创建 subagent ToolUseContext（工具池已过滤为 ASYNC_AGENT_ALLOWED_TOOLS）
   - 调用 query() 递归，worker 在其范围内工作
   - 结果作为 task-notification 消息返回到 coordinator
6. Coordinator 通过 SendMessageTool 继续 worker 工作
7. TaskStopTool 可停止任何 worker

**Coordinator 系统提示示例**
```
你是 Claude Code，一个多 agent 协调器。
- 你的角色：指挥 worker 完成任务，合成结果
- 你的工具：
  - Agent 工具：生成新 worker
  - SendMessage：向已有 worker 发送消息
  - TaskStop：停止 worker
  - subscribe_pr_activity / unsubscribe_pr_activity：订阅 GitHub 事件
- Worker 能访问的工具：[Bash, Read, Edit, ..., Skill, Agent, TaskStop, ...]
- Worker 也可访问 MCP 服务器：[server1, server2, ...]
- Scratchpad 目录：/tmp/claude-code-scratchpad (跨 worker 共享知识)
```

**可借鉴点**
- **权限分离清晰**：Coordinator ↔ Worker 工具集合有明确界限，避免 worker 滥用权限
- **Scratchpad 模式**：跨 worker 共享文件系统，用于交换中间结果与知识
- **消息驱动**：Worker 通过 task-notification 消息报告进度，Coordinator 订阅并反应
- **递归能力**：Agent 可生成子 Agent，形成树状 worker 池，支持复杂多层工作

---

## 七、辅助子系统

### **history.ts** (464 行)
- **职责**：会话历史与粘贴内容管理
- **关键函数**：
  - addToHistory() — 添加用户提示到 ~/.claude/history
  - expandPastedTextRefs() — [Pasted text #1] 占位符替换
  - formatPastedTextRef() / formatImageRef() — 格式化引用
- **接口**：HistoryEntry (id, timestamp, text), PastedContent (type, content/hash)

### **context.ts** (189 行)
- **职责**：全局上下文注入（git 状态、claude.md、当前日期）
- **关键函数**：
  - getSystemContext() — git branch / status / recent commits
  - getUserContext() — claude.md 文件发现、currentDate
- **缓存**：memoize 装饰器，会话期间不重计算

### **commands.ts** (781 行)
- **职责**：斜线命令注册与路由
- **关键**：
  - 100+ 个命令定义（commit, review, config, help, login, ...）
  - processSlashCommand() 本地执行（无 query 调用）
  - getCommands() 返回可用命令列表
- **特性**：Skill 包装（/commit → SkillTool）

### **cost-tracker.ts** (379 行)
- **职责**：模型成本与 token 使用统计
- **关键**：getModelUsage(), getTotalCost(), getTotalAPIDuration()
- **支持**：多模型计费，cache 命中率统计

### **Task.ts** (124 行)
- **职责**：后台任务类型定义
- **关键**：Task interface，TaskResult, TaskProgressCallback

### **setup.ts** (438 行)
- **职责**：启动向导与 onboarding
- **关键**：showSetupScreens(), OAuth 认证，repo 选择

### **dialogLaunchers.tsx** (132 行)
- **职责**：交互式对话框启动
- **关键**：launchAssistantInstallWizard(), launchResumeChooser(), launchSnapshotUpdateDialog()

### **interactiveHelpers.tsx** (375 行)
- **职责**：REPL 辅助 UI 函数
- **关键**：exitWithError(), getRenderContext(), renderAndRun()

### **costHook.ts** (22 行)
- **职责**：React hook 包装，cost-tracker 订阅

### **projectOnboardingState.ts** (47 行)
- **职责**：项目 onboarding 状态管理

---

## 八、messages.ts 中的关键工具函数

**消息构建**
- createUserMessage() — 用户输入 + 粘贴内容
- createSystemMessage() — 系统提示
- createAssistantAPIErrorMessage() — API 错误处理
- createAttachmentMessage() — 文件变更、MCP 资源
- createToolUseSummaryMessage() — 工具执行摘总

**消息处理**
- normalizeMessagesForAPI() — 验证 Anthropic API 格式
- getMessagesAfterCompactBoundary() — Compact 后的消息切片
- createUserInterruptionMessage() — 用户中断标记

---

## 九、main.tsx React 状态机详解

**主要 useState 钩子**
```typescript
const [messages, setMessages] = useState<Message[]>([])           // 对话历史
const [isWaitingForResponse, setIsWaitingForResponse] = useState(false)
const [activeMessageId, setActiveMessageId] = useState<string>()  // 恢复编辑
const [searchQuery, setSearchQuery] = useState('')                // 搜索历史
const [selectedToolName, setSelectedToolName] = useState<string>() // 工具详情

// 性能与分析
const [costSummary, setCostSummary] = useState<CostSummary>()
const [startTime] = useState(Date.now())

// Coordinator 状态
const [agents, setAgents] = useState<Map<AgentId, AgentState>>()  // 所有 worker
const [selectedAgentId, setSelectedAgentId] = useState<AgentId>()
```

**事件处理流程**
```
用户输入 (REPL)
    ↓
onInputChange() → setInput() → React 重绘
    ↓
用户按 Enter
    ↓
onSubmit() → 验证、queueCommand(input)
    ↓
useQueueProcessor() hook 拦截 → query(input) 异步调用
    ↓
for await (const event of query(...)) {
  if (event.type === 'tool_use_block') {
    → 显示工具执行进度 UI
    → 执行工具、收集结果
    → 作为 tool_result 继续 API 循环
  }
  if (event.type === 'message') {
    → setMessages([...messages, event])
    → 重绘历史区域
  }
}
    ↓
turn 完成 → setIsWaitingForResponse(false)
```

**副作用钩子（useEffect）**
- 监听 messages 变化 → 保存历史、更新成本
- 监听 resume flag → 加载会话
- 监听 settings → 重新连接 MCP、刷新工具
- Signal handlers → SIGINT/SIGTERM → graceful shutdown

---

## 十、关键算法与模式

### **1. 消息规范化与 Compaction**
```
消息序列：
[system, user_1, assistant_1, tool_result_1, user_2, assistant_2, ...]

auto-compact 触发：
→ calculateTokenWarningState() 检查 budget
→ 若超 80% → buildPostCompactMessages()
→ 压缩中间消息为 "conversation summary + context"
→ 维持最后 N 条消息完整性
```

### **2. 工具执行并发策略**
```
工具块集合：[tool_use_1, tool_use_2, tool_use_3]

检查是否可并发：
→ 工具依赖分析（BashTool 与 FileEditTool 有冲突 → 串行）
→ 若独立 → Promise.all() 并发
→ StreamingToolExecutor 处理流式结果

结果收集：
→ 每个工具返回 ToolResult
→ 构建 tool_result messages
→ 返回到 API 继续循环
```

### **3. 权限检查两层**
```
第 1 层：工具定义时
→ Tool 注册时检查 isEnabled() → feature gates

第 2 层：工具执行前
→ useCanUseTool(toolName, context) hook
→ 评估 ToolPermissionContext 规则
→ 若拒绝 → createPermissionDenialMessage()
→ 若需要提示 → 显示权限对话框
```

### **4. MCP 工具无缝集成**
```
MCP 服务器连接：
→ main.tsx 启动时 getMcpToolsCommandsAndResources()
→ mcpTools 数组 += MCP 工具

工具池组装：
→ assembleToolPool(builtInTools, mcpTools)
→ 按名称去重（内置优先级更高）
→ 按名称排序 → prompt cache 稳定

执行：
→ mcpInfo 字段标记 MCP 工具
→ MCPTool 包装器调用 MCP 服务器
```

---

## 十一、可借鉴的工程实践

| 实践 | 实现 | 价值 |
|------|------|------|
| **消息流异步** | AsyncGenerator query() | 低延迟 UI，流式工具结果 |
| **权限模型** | ToolPermissionContext + 三层规则 | 细粒度控制，用户友好提示 |
| **工具池动态** | feature gates + isEnabled() | 同一代码库支持 10+ 变体 |
| **会话持久化** | JSON 序列化 + 增量保存 | 快速恢复，支持断点继续 |
| **Cost 追踪** | Map<Model, Usage> + 实时累积 | 多模型计费透明 |
| **Compaction 集成** | token budget + auto-compact | 无缝长对话支持 |
| **MCP 集成** | 透明混合 + 名称去重 | 扩展性强，无闭包 |
| **React 并发友好** | 消息队列 + useCallback 优化 | 不阻塞 UI 渲染 |
| **Coordinator 模式** | 递归 agent + scratchpad | 复杂多步任务自动化 |
| **错误处理** | Hook + Catch-all + 重试 | 网络波动自愈 |

---

## 十二、总结

OpenClaude 内核是一个**消息驱动的异步引擎**，其核心：
1. **main.tsx** — React REPL，UI 状态机与事件监听
2. **query.ts** — Async generator，单次 turn 的消息 ↔ API ↔ 工具流程
3. **QueryEngine.ts** — 会话级别包装，SDK 兼容，历史管理
4. **Tool.ts + tools.ts** — 工具注册、权限、MCP 集成
5. **coordinator/** — 多 agent 协调，worker 权限隔离
6. **history.ts, context.ts, commands.ts** — 上下文、命令、历史

其设计精髓：
- **分离关注点**：turn 逻辑 vs 会话逻辑 vs UI
- **权限透明**：两层检查 + 可配置规则
- **扩展友好**：feature gates、MCP、skills、agents
- **性能优化**：启动并行化、token 预算、流式结果

实现了一个**生产级 AI IDE 的核心**，支持 SDK、REPL、print 等多模式，具有会话恢复、成本控制、权限管理、多 agent 协调等企业级特性。


---

# Part II — 多 Provider 路由系统（OpenClaude 核心差异化）


## 架构概览：从用户配置到真实 LLM API

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                        用户配置（Profile & Env Vars）                        │
│  /provider → resolveProfileRoute() → 用户选择的 provider 字符串              │
└──────────────────────────┬──────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│              ProfileResolver 层（兼容性与路由解析）                          │
│  isProviderPreset() ─► routeForPreset()                                     │
│  getVendor(id) / getGateway(id) ─► ResolvedProfileRoute                     │
│  {vendorId, gatewayId?, routeId}                                            │
└──────────────────────────┬──────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│         Registry（注册表 & 发现服务）                                         │
│  ensureIntegrationsLoaded() ─► VENDOR_DESCRIPTORS / GATEWAY_DESCRIPTORS     │
│  ├─ registerVendor() / registerGateway()                                     │
│  ├─ getVendor(vendorId) / getGateway(gatewayId)                              │
│  ├─ getCatalogEntriesForRoute() ─► ModelCatalogEntry[]                       │
│  └─ getAllModels() ─► ModelDescriptor[] 全模型列表                           │
└──────────────────────────┬──────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│    RouteMetadata 层（路由元数据）                                             │
│  getRouteDescriptor(routeId) ─► RouteDescriptor                              │
│  getRouteDefaultBaseUrl() / getRouteDefaultModel()                           │
│  resolveRouteIdFromBaseUrl() ─► 从自定义 baseUrl 反向查询                   │
│  getRouteLabel() / getTransportKindForRoute()                                │
└──────────────────────────┬──────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│        模型发现 & 缓存 (Discovery Service & Cache)                            │
│  discoverModelsForRoute(routeId) ─► RouteDiscoveryResult                     │
│  ├─ 静态目录 (source: 'static')                                              │
│  ├─ 网络发现 (source: 'network' via OpenAI /models API)                     │
│  ├─ 缓存命中 (source: 'cache' with TTL)                                      │
│  └─ 过期缓存降级 (source: 'stale-cache')                                     │
│  DiscoveryService：ollama、openai-compatible、custom 三种发现模式             │
└──────────────────────────┬──────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│         Compatibility & Runtime Metadata 层（兼容性处理）                    │
│  compatibility.ts：                                                          │
│    ├─ PRESET_ROUTE_MAP (Anthropic v4 → openai/gemini 映射)                  │
│    └─ routeForPreset() / vendorIdForPreset()                                 │
│  runtimeMetadata.ts：                                                        │
│    ├─ 模型到具体 API 名称的映射 (providerModelMap)                           │
│    ├─ 上下文窗口和 Token 上限查询                                             │
│    └─ OpenAI Shim 配置 (removeBodyFields, maxTokensField 等)                │
└──────────────────────────┬──────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│    OpenAI Shim / Transport Config（传输适配层）                              │
│  TransportKind: anthropic-native / gemini-native / openai-compatible / ..    │
│  OpenAIShimTransportConfig：                                                │
│    ├─ headers、supportsApiFormatSelection、supportsAuthHeaders              │
│    ├─ preserveReasoningContent (DeepSeek R1)                                │
│    ├─ thinkingRequestFormat (deepseek-compatible)                           │
│    ├─ removeBodyFields (过滤不支持的 body 字段)                              │
│    └─ maxTokensField (max_tokens vs max_completion_tokens)                  │
│  ▌工具调用格式统一化：所有 OpenAI 兼容 API → Claude tool_use format         │
└──────────────────────────┬──────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│       Upstream Proxy / Gateway（上游代理）                                    │
│  upstreamproxy.ts / relay.ts：                                              │
│    ├─ CCR (Cloud Code Runtime) 环境支持                                     │
│    ├─ WebSocket → TCP CONNECT 中继                                          │
│    ├─ MITM TLS termination（可选的组织凭证注入）                             │
│    └─ NO_PROXY 例外清单 (anthropic.com, github.com 等)                      │
│  网络路由：所有 OpenAI 兼容请求都可过 upstream proxy 到真实 LLM API          │
└──────────────────────────┬──────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│              真实 LLM API（200+ 支持的 Provider）                              │
│  Anthropic 原生（anthropic.ts）                                             │
│    └─ https://api.anthropic.com (x-api-key 认证)                           │
│  OpenAI 兼容（openai.ts + 任意 OpenAI /v1 端点）                            │
│    ├─ OpenAI（gpt-5.4）                                                      │
│    ├─ DeepSeek（deepseek-v4-pro with reasoning）                           │
│    ├─ Groq（llama-3.3-70b）                                                  │
│    ├─ Mistral（devstral-latest）                                             │
│    ├─ Moonshot/Kimi（8k-latest）                                             │
│    └─ 200+ 其他兼容端点                                                      │
│  Gemini 原生（gemini.ts）                                                    │
│    └─ https://generativelanguage.googleapis.com/v1beta/openai                │
│  本地 Ollama（ollama.ts）                                                     │
│    └─ http://localhost:11434/v1 (无认证)                                    │
│  网关/聚合服务                                                                │
│    ├─ OpenRouter（200+ 模型）                                                │
│    ├─ GitLawb OpenGateway（GitLawb 企业集成）                                │
│    ├─ Hicap（响应模式）                                                      │
│    ├─ Together.ai、Atomic Chat、LM Studio 等                                 │
│    └─ 中国本地（Xiaomi MiMo、MiniMax、Bankr 等）                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

---

## 1. 核心子系统：Registry（注册表）

### 职责
Registry 是全局单例模式，存储所有 Provider Descriptor（厂商、网关、模型、品牌），提供按 ID 查询的能力。它是 OpenClaude 多 provider 系统的基础层。

### 关键文件
- **src/integrations/registry.ts**（390 行）：核心实现
- **src/integrations/index.ts**（129 行）：加载器入口
- **src/integrations/generated/integrationArtifacts.generated.js**：自动生成的 Descriptor 数组

### 核心数据结构

```typescript
// 五大注册表 Map（私有全局状态）
const _brands = new Map<string, BrandDescriptor>()       // 品牌（如 Claude、Opus）
const _vendors = new Map<string, VendorDescriptor>()     // 厂商（如 Anthropic、OpenAI）
const _gateways = new Map<string, GatewayDescriptor>()   // 网关（如 Ollama、OpenRouter）
const _anthropicProxies = new Map<string, AnthropicProxyDescriptor>()  // Anthropic 代理
const _models = new Map<string, ModelDescriptor>()       // 模型（如 gpt-5、claude-opus）
```

### 调用链
1. **初始化**：`ensureIntegrationsLoaded()` 逐个 register 所有 Descriptor
2. **查询**：`getVendor(id)`、`getGateway(id)`、`getModel(id)` 都是直接 Map 查询
3. **列表**：`getAllVendors()`、`getAllGateways()` 返回完整列表
4. **目录**：`getCatalogEntriesForRoute(routeId)` 查询路由的模型目录
5. **验证**：`validateIntegrationRegistry()` 检查 Descriptor 完整性

### 可借鉴点
- **Map-based 注册表**：O(1) 查询，线程安全（Node 单线程）
- **Descriptor 不可变**：一旦注册不能修改，防止运行时修改
- **验证逻辑详尽**：检查重复、缺失的引用、冲突的 preset ID、默认模型
- **测试友好**：`_clearRegistryForTesting()` 支持单元测试隔离

---

## 2. 核心子系统：ProfileResolver（用户配置解析）

### 职责
将用户保存的 profile 字符串（如 "anthropic"、"openrouter"、"ollama"）映射到具体的路由描述符，处理向后兼容性（Anthropic v4 preset 名称等）。

### 关键文件
- **src/integrations/profileResolver.ts**（48 行）：路由解析算法
- **src/integrations/compatibility.ts**（60 行）：Preset 映射表

### 核心数据结构

```typescript
export type ResolvedProfileRoute = {
  vendorId: string           // 真实的 vendor（如 'openai', 'anthropic'）
  gatewayId?: string         // 如果是网关，则有这个值（如 'ollama'）
  routeId: string            // 用于查询具体 Descriptor 的 ID
}
```

### 调用链
```typescript
resolveProfileRoute("gpt-4o") → {
  // 1. 尝试 isProviderPreset("gpt-4o") → false
  // 2. 尝试 getVendor("gpt-4o") → undefined
  // 3. 尝试 getGateway("gpt-4o") → undefined
  // 4. 如果都失败 → 回退到 {vendorId: "openai", routeId: "unknown-fallback"}
  
  // 或者若输入 "openai" 是已知 preset：
  routeForPreset("openai") → {
    vendorId: "openai",
    routeId: "openai"
  }
}
```

### 可借鉴点
- **分层解析**：Preset → Vendor → Gateway → Fallback，清晰的优先级
- **容错设计**：未知 provider 回退到 OpenAI 兼容，不报错
- **向后兼容**：PROVIDER_PRESET_MANIFEST 保存历史 preset 映射

---

## 3. 核心子系统：DiscoveryService（模型发现）

### 职责
通过网络探测或静态配置发现给定路由上可用的模型列表，支持缓存和降级。是支持动态 provider（Ollama、OpenRouter、网关）的关键。

### 关键文件
- **src/integrations/discoveryService.ts**（528 行）：主逻辑
- **src/integrations/discoveryCache.ts**（331 行）：缓存层

### 核心数据结构

```typescript
export type RouteDiscoveryResult = {
  routeId: string                           // 路由 ID
  models: ModelCatalogEntry[]                // 发现的模型列表
  stale: boolean                             // 缓存是否过期
  error: DiscoveryCacheError | null          // 发现时的错误
  source: 'network' | 'cache' | 'stale-cache' | 'static' | 'error'
}

// 模型发现配置（在 Descriptor 中定义）
export type ModelDiscoveryConfig = {
  kind: 'openai-compatible' | 'ollama' | 'custom'
  requiresAuth?: boolean
  mapModel?: (raw: unknown) => ModelCatalogEntry | null  // 自定义映射器
}
```

### 调用链

1. **启动探测**：`refreshStartupDiscoveryForActiveRoute()` 在 app 初始化时运行
   - 读取 env vars（OPENAI_BASE_URL、OPENAI_API_KEY）
   - 调用 `refreshStartupDiscoveryForRoute(routeId, {baseUrl, apiKey})`

2. **发现执行**：`discoverModelsForRoute(routeId, options?)`
   - 检查 static catalog 是否存在
   - 若有 discovery config，从缓存或网络获取
   - 支持 `forceRefresh` 跳过缓存

3. **缓存管理**：`getDiscoveryCacheKey(routeId, {baseUrl, apiKey, headers})`
   - 基于 baseUrl、API key 哈希、自定义 headers 生成唯一 key
   - TTL 可配置（如 Groq 1d）

4. **发现种类**：
   - **ollama**：调用 `probeOllamaModelCatalog({baseUrl})` → 解析 `/api/tags`
   - **openai-compatible**：调用 `listOpenAICompatibleModels({baseUrl, apiKey})` → 解析 `/models` 响应
   - **custom**：provider 自定义逻辑（如 Atomic Chat）

### 可借鉴点
- **三层缓存**：静态 → 新鲜缓存 → 过期缓存（graceful degradation）
- **隐私友好**：`isEssentialTrafficOnly()` 支持禁止非必需 discovery 流量
- **自适应映射**：`discovery.mapModel()` 允许 per-provider 的 model 过滤（如 Groq 去掉 whisper 模型）
- **启动友好**：`discoveryRefreshMode: 'startup'` 仅在应用启动时一次发现

---

## 4. 核心子系统：RouteMetadata（路由元数据查询）

### 职责
提供路由相关的元数据查询（默认 baseUrl、默认模型、auth 信息、transport 种类等），支持从自定义 baseUrl 反向查询到路由 ID。

### 关键文件
- **src/integrations/routeMetadata.ts**（652 行）：完整实现

### 核心函数

| 函数 | 作用 |
|------|------|
| `getRouteDescriptor(routeId)` | 查询任何路由的完整描述符 |
| `getRouteDefaultBaseUrl(routeId)` | 查询默认的 API 端点 URL |
| `getRouteDefaultModel(routeId)` | 查询默认模型（从 defaultModel 或 catalog[0]） |
| `getTransportKindForRoute(routeId)` | 获取 transport 类型（决定如何序列化请求） |
| `resolveRouteIdFromBaseUrl(baseUrl, opts?)` | 从 baseUrl 反向查找路由（自定义端点场景） |
| `resolveActiveRouteIdFromEnv(processEnv, opts?)` | 从环境变量推断当前活跃路由 |
| `resolveRouteCredentialValue({routeId, processEnv})` | 查询该路由的 API key（从 env 变量） |

### 调用链示例

```typescript
// 用户设置自定义 OpenAI-compatible baseUrl
resolveRouteIdFromBaseUrl("https://api.minimax.io/v1")
  → 检查 MiniMax 特定的 host 匹配
  → 返回 "minimax"（或基于 classification 返回 openai）

// 查询 API key
resolveRouteCredentialValue({
  routeId: "deepseek",
  processEnv: process.env
}) → 按优先级查询 process.env 中的 credentialEnvVars
   → 返回第一个非空值或 undefined
```

### 可借鉴点
- **Host 匹配**：支持特定 provider 的 host 识别（MiniMax、X.ai、Xiaomi MiMo）
- **Env 变量层次**：同一 route 支持多个环境变量（优先级排序）
- **验证路由**：检查 baseUrl 是否与已知网关/厂商匹配
- **本地路由检测**：自动识别 localhost:11434（Ollama）、localhost:1234（LM Studio）

---

## 5. 核心子系统：Compatibility & Routing（兼容性处理）

### 职责
处理 Claude API 和其他 Provider 之间的协议差异。重点是将任意 OpenAI 兼容 API 的请求/响应适配成 Claude SDK 期望的格式。

### 关键文件
- **src/integrations/compatibility.ts**（60 行）：Preset 映射
- **src/integrations/runtimeMetadata.ts**（404 行）：运行时适配配置生成

### 核心概念：OpenAI Shim

OpenAI Shim 是 OpenClaude 的核心创新——它将任意 OpenAI /v1 兼容服务适配成 Claude API 格式：

```typescript
// OpenAIShimTransportConfig（在 Descriptor 中定义）
{
  headers?: Record<string, string>                 // 额外 HTTP 头
  supportsApiFormatSelection?: boolean             // 是否支持 ?api_format=openai
  supportsAuthHeaders?: boolean                    // 是否支持 Authorization: Bearer
  maxTokensField?: 'max_tokens' | 'max_completion_tokens'  // Token 字段名适配
  removeBodyFields?: string[]                      // 删除不支持的 body 字段
  preserveReasoningContent?: boolean               // 保留思考内容（DeepSeek）
  requireReasoningContentOnAssistantMessages?: boolean  // 强制 assistant 消息包含思考
  thinkingRequestFormat?: 'deepseek-compatible'    // 思考格式转换
  defaultAuthHeader?: OpenAIShimAuthHeaderConfig   // auth header 配置
}
```

### 模型映射算法

```typescript
// src/integrations/runtimeMetadata.ts 中的关键函数
matchesCatalogEntryModel(routeId, entry, modelApiName) {
  // 1. 直接匹配 entry.apiName
  if (entry.apiName === modelApiName) return true
  
  // 2. 若 entry 有 modelDescriptorId，查询 ModelDescriptor
  const modelDesc = getModel(entry.modelDescriptorId)
  
  // 3. 匹配 modelDesc.defaultModel
  if (modelDesc.defaultModel === modelApiName) return true
  
  // 4. 检查 providerModelMap[routeId]
  // 例如：同一个"claude-opus-4.6"在不同 provider 有不同名称
  return modelDesc.providerModelMap?.[routeId] === modelApiName
}
```

**例子**：
- 同一个逻辑模型 "claude-opus-4.6" 在：
  - Anthropic API 中叫 `claude-opus-4.6`
  - Bankr 中叫 `claude-opus-4.6`
  - OpenRouter 中可能叫 `anthropic/claude-opus-4.6`
  - MiniMax 可能不支持
  - 通过 `providerModelMap` 映射，Claude SDK 可统一引用

### 工具调用格式转换

OpenClaude 的关键任务：**任意 OpenAI 兼容 API → Claude tool_use format**

虽然代码中具体的工具转换逻辑在 `src/services/api/openaiShim.ts`（不在 integrations 范围内），但 descriptor 的角色是：

```typescript
// Descriptor 声明该 route 的能力
supportsApiFormatSelection: true/false  // 是否能切换到 Claude 格式
supportsFunctionCalling: true/false      // 是否支持工具调用
```

Shim 在运行时：
1. 接收用户的 Claude SDK 格式请求（带 tools 数组）
2. 根据 `supportsApiFormatSelection`，决定是否转换为 OpenAI `functions` 格式
3. 接收响应，反向转换回 `tool_use` block 格式

### 可借鉴点
- **Descriptor-驱动适配**：adapter 配置完全在 Descriptor 中，无硬编码
- **provider 优先级路由**：通过 `validation.routing.fallbackWhenUseOpenAI` 支持有条件回退
- **流式输出适配**：不同 provider 的 streaming 格式有差异（delta vs function_call），Shim 统一处理
- **推理内容保留**：DeepSeek R1 有 `thinking` 字段，Shim 识别并保留给 Claude SDK

---

## 6. Vendors（厂商）— 11 个一级 LLM 提供商

### 支持的 Vendors

| ID | 标签 | 分类 | 默认模型 | 认证 | 特殊功能 |
|---|---|---|---|---|---|
| **anthropic** | Anthropic | anthropic-native | claude-sonnet-4-6 | x-api-key | 原生 API，支持 vision、tool_use、streaming |
| **openai** | OpenAI | openai-compatible | gpt-5.4 | Bearer token | OpenAI /v1 标准实现 |
| **gemini** | Google Gemini | gemini-native | gemini-3-flash | API key | Gemini API，支持 vision、multimodal |
| **deepseek** | DeepSeek | openai-compatible | deepseek-v4-pro | API key | R1 推理模型，preserveReasoningContent |
| **groq** | Groq | openai-compatible | llama-3.3-70b | API key | 低延迟推理，whisper/guard 过滤 |
| **mistral** | Mistral AI | openai-compatible | devstral-latest | API key | Mistral 云端服务，支持特定覆盖 |
| **moonshot** | Kimi/Moonshot | openai-compatible | 8k-latest | API key | 中文优化，8K 上下文 |
| **minimax** | MiniMax | openai-compatible | minimax-m2.7 | API key | 中文模型，支持 MiniMax-Text-01 vision |
| **xiaomi-mimo** | Xiaomi MiMo | openai-compatible | mimo-v2.5-pro | API key | 中文，国内部署，支持动态发现 |
| **bankr** | Bankr Bot | openai-compatible | claude-opus-4.6 | API key | 聚合网关，支持多个 Claude 模型 |
| **zai** | Zai (Zero to AI) | openai-compatible | ? | API key | 可能是小众网关 |
| **venice** | Venice.ai | openai-compatible | ? | API key | 开源模型网关 |
| **xai** | X.AI (Grok) | openai-compatible | ? | API key | X 公司的 Grok 模型 |

### Vendor Descriptor 结构

```typescript
export interface VendorDescriptor {
  id: string                           // 全局唯一 ID
  label: string                        // 用户界面显示名称
  classification: 'native' | 'openai-compatible' | ...
  defaultBaseUrl: string               // 如 https://api.openai.com/v1
  defaultModel: string                 // 默认推荐模型
  requiredEnvVars: string[]             // 必需的环境变量（文档用）
  setup: SetupMetadata                 // 认证模式（api-key / oauth / adc）
  transportConfig: TransportConfig     // 协议适配配置
  catalog: ModelCatalogConfig          // 模型目录（静态或发现）
  preset?: ProviderPresetMetadata      // 是否支持 /provider 保存
  validation?: {                        // 认证和路由验证
    kind: 'credential-env' | 'gemini-credential' | ...
    routing?: ValidationRoutingMetadata
    credentialEnvVars: string[]
  }
  isFirstParty?: boolean                // Anthropic 一方（用于特殊处理）
  usage?: UsageMetadata                 // 额度/使用量查询支持
}
```

### 每个 Vendor 的关键差异

#### 1. anthropic.ts - Anthropic 原生
```typescript
transportConfig: { kind: 'anthropic-native' }  // 不需要 openaiShim
preset: {
  id: 'anthropic',
  description: 'Native Claude API (x-api-key auth)',
  apiKeyEnvVars: ['ANTHROPIC_API_KEY'],
  baseUrlEnvVars: ['ANTHROPIC_BASE_URL'],
  modelEnvVars: ['ANTHROPIC_MODEL'],
}
```
**特点**：一级 provider，直接调用 Anthropic `/v1/messages` 端点。

#### 2. openai.ts - OpenAI 基础
```typescript
transportConfig: {
  kind: 'openai-compatible',
  openaiShim: {
    supportsApiFormatSelection: true,    // 可切换格式
    supportsAuthHeaders: true,            // Authorization header
  },
}
preset: {
  id: 'openai',
  description: 'OpenAI API with API key',
  apiKeyEnvVars: ['OPENAI_API_KEY'],
  baseUrlEnvVars: ['OPENAI_BASE_URL'],
}
validation: {
  routing: {
    matchDefaultBaseUrl: true,            // https://api.openai.com/v1
    fallbackWhenUseOpenAI: true,          // 当 CLAUDE_CODE_USE_OPENAI=1
  },
}
```
**特点**：标准 OpenAI /v1 实现，支持自定义 baseUrl。

#### 3. deepseek.ts - DeepSeek（思考模型）
```typescript
transportConfig: {
  kind: 'openai-compatible',
  openaiShim: {
    preserveReasoningContent: true,      // ◄── 保留 thinking 内容
    requireReasoningContentOnAssistantMessages: true,
    reasoningContentFallback: '',
    thinkingRequestFormat: 'deepseek-compatible',
    maxTokensField: 'max_tokens',
    removeBodyFields: ['store'],          // DeepSeek 不支持 store
  },
}
```
**特点**：R1 推理模型支持，思考内容映射到 Claude thinking block。

#### 4. gemini.ts - Google Gemini（原生协议）
```typescript
transportConfig: {
  kind: 'gemini-native',                // ◄── 不是 OpenAI 兼容
  openaiShim: {
    removeBodyFields: ['store'],          // Gemini 也不支持 store
  },
}
defaultBaseUrl: 'https://generativelanguage.googleapis.com/v1beta/openai'
```
**特点**：Google 原生 API，虽然提供 OpenAI 兼容端点但有特殊处理。

#### 5. minimax.ts - MiniMax（中文+特殊配置）
```typescript
validation: {
  routing: {
    matchBaseUrlHosts: ['api.minimax.io', 'api.minimax.chat'],
  },
}
// 12 个模型，从 M2 到 Vision-01
catalog: {
  source: 'static',
  models: [
    { id: 'minimax-m2.7', apiName: 'MiniMax-M2.7', label: 'MiniMax M2.7', ... },
    // ... Text-01, Vision-01 variants
  ],
}
```
**特点**：完整的中文 LLM 模型列表，host 识别支持多个域名。

### 可借鉴点
- **分类清晰**：anthropic-native vs openai-compatible，明确的 transport 类型
- **per-vendor 覆盖**：`openaiShim` 可选，允许原生协议与兼容协议共存
- **模型完整性**：每个 vendor 的 catalog 都包含真实支持的模型列表
- **环境变量多元化**：同一 vendor 可支持多套 env var 命名（如 OPENAI_MODEL / BANKR_MODEL）

---

## 7. Gateways（网关/聚合服务）— 18 个网关

### 支持的 Gateways

| ID | 标签 | 类别 | 默认模型 | 模型发现 | 特殊功能 |
|---|---|---|---|---|---|
| **ollama** | Ollama | local | llama3.1:8b | 动态发现 | 本地推理，无认证 |
| **openrouter** | OpenRouter | aggregating | openai/gpt-5-mini | 混合(hybrid) | 200+ 模型聚合，平衡路由 |
| **groq** | Groq | aggregating | llama-3.3-70b | 混合 | 低延迟推理 |
| **mistral** | Mistral AI | hosted | devstral-latest | 静态 | Mistral 云端网关 |
| **lmstudio** | LM Studio | local | (动态) | 动态 | 本地/网络 LM Studio 服务 |
| **hicap** | Hicap | hosted | (custom) | 混合 | 响应模式，自定义模型 |
| **atomic-chat** | Atomic Chat | local | (动态) | 动态 | 本地模型服务，启动探针 |
| **github** | GitHub Models | hosted | (动态) | 动态 | GitHub 免费额度，OAuth |
| **together** | Together.ai | aggregating | ? | 混合 | Together 模型网关 |
| **azure-openai** | Azure OpenAI | hosted | ? | 静态 | Microsoft Azure 部署 |
| **bedrock** | AWS Bedrock | hosted | ? | 静态 | Amazon Bedrock Claude API |
| **vertex** | Google Vertex AI | hosted | ? | 静态 | Google Cloud Vertex AI |
| **dashscope-cn** | 阿里 DashScope | hosted | ? | 静态 | 中国内地，Qwen 等 |
| **dashscope-intl** | DashScope Intl | hosted | ? | 静态 | 国际版 DashScope |
| **kimi-code** | Kimi Code | hosted | (custom) | 静态 | 月之暗面，编程优化 |
| **nvidia-nim** | NVIDIA NIM | hosted | ? | 静态 | NVIDIA 推理微服务 |
| **gitlawb-opengateway** | GitLawb OpenGateway | aggregating | ? | 混合 | GitLawb 企业网关 |
| **atomic-chat** | Atomic Chat | local | (动态) | 动态 | 本地模型加载服务 |

### Gateway Descriptor 结构

```typescript
export interface GatewayDescriptor extends RouteMetadata {
  id: string
  label: string
  category: 'local' | 'hosted' | 'aggregating'
  defaultBaseUrl: string
  defaultModel: string
  supportsModelRouting: boolean         // 是否支持任意模型选择
  setup: SetupMetadata
  startup?: StartupMetadata             // 自动检测、启动探针
  transportConfig: TransportConfig
  catalog: ModelCatalogConfig
  preset?: ProviderPresetMetadata
  usage?: UsageMetadata
}
```

### 关键 Gateway 详解

#### 1. ollama.ts - 本地推理
```typescript
id: 'ollama',
defaultBaseUrl: 'http://localhost:11434/v1',
supportsModelRouting: true,           // 支持任意 ollama 模型
setup: {
  requiresAuth: false,                 // 无认证
  authMode: 'none',
},
startup: {
  autoDetectable: true,                // 可自动检测
  probeReadiness: 'ollama-generation', // 尝试运行模型测试就绪性
},
catalog: {
  source: 'dynamic',
  discovery: { kind: 'ollama' },        // 通过 /api/tags 发现
  discoveryCacheTtl: '1d',
  discoveryRefreshMode: 'background-if-stale',
  allowManualRefresh: true,
},
```
**特点**：完全本地，无凭证，支持后台自动发现。

#### 2. openrouter.ts - 模型聚合
```typescript
id: 'openrouter',
defaultBaseUrl: 'https://openrouter.ai/api/v1',
defaultModel: 'openai/gpt-5-mini',
supportsModelRouting: true,
setup: {
  requiresAuth: true,
  authMode: 'api-key',
  credentialEnvVars: ['OPENROUTER_API_KEY'],
},
catalog: {
  source: 'hybrid',                      // 静态 + 动态混合
  discovery: { kind: 'openai-compatible' },
  models: [
    { id: 'openrouter-gpt-5-mini', apiName: 'openai/gpt-5-mini', ... },
  ],
},
```
**特点**：200+ 模型，混合目录，支持任意 provider 模型路由。

#### 3. atomic-chat.ts - 本地模型服务
```typescript
id: 'atomic-chat',
defaultBaseUrl: 'http://localhost:8000/v1',
setup: {
  requiresAuth: false,
  authMode: 'none',
},
startup: {
  probeReadiness: 'openai-compatible-models',  // 探测 /models
},
catalog: {
  source: 'dynamic',
  discovery: { kind: 'openai-compatible' },
},
```
**特点**：本地 UI 服务，自动发现，无凭证。

#### 4. groq.ts - 低延迟推理（带模型过滤）
```typescript
catalog: {
  source: 'hybrid',
  discovery: {
    kind: 'openai-compatible',
    mapModel(raw: unknown) {
      const model = raw as { id?: string; active?: boolean }
      // 过滤 Groq 的非推理模型
      if (/(whisper|distil-whisper|guard)/i.test(model.id)) {
        return null  // ◄── 不包含在结果中
      }
      return {
        id: model.id,
        apiName: model.id,
        label: model.id,
      }
    },
  },
},
```
**特点**：自定义 mapModel，可选择性包含模型。

#### 5. github.ts - GitHub Models（OAuth）
```typescript
defaultBaseUrl: 'https://models.inference.ai.azure.com',
setup: {
  requiresAuth: true,
  authMode: 'oauth',  // ◄── OAuth，不是 api-key
},
catalog: {
  source: 'hybrid',
  discovery: { kind: 'openai-compatible' },
},
```
**特点**：OAuth 认证（GitHub 账号登录），免费额度。

### 可借鉴点
- **category 分类**：local 不需要凭证，aggregating 聚合多个模型，hosted 第三方服务
- **autoDetectable**：本地 gateway（ollama、lmstudio）标记为可自动检测，支持启动时自动选择
- **hybrid 目录**：既有静态模型列表又支持动态发现，兼顾启动速度和完整性
- **per-gateway 过滤**：Groq 的 `mapModel` 演示了如何筛选不适合的模型

---

## 8. 核心差异：OpenClaude vs. Claude Code 原版

### Claude Code 原版（Anthropic 官方）
```
只支持 3 种 provider：
├─ Anthropic（原生 API）
├─ AWS Bedrock
└─ Google Vertex AI
```

**特点**：
- 严格的 Anthropic 生态
- 最安全、官方支持最好
- 企业级认证（ADC / IAM）

### OpenClaude（GitLawb Fork）
```
支持 200+ provider：
├─ 一级厂商（11 个）
│  ├─ Anthropic（原生）
│  ├─ OpenAI（gpt-5.4）
│  ├─ DeepSeek（推理模型）
│  ├─ Gemini（Google）
│  ├─ Groq、Mistral、Moonshot（各类型）
│  └─ 中国本地（MiniMax、Xiaomi、Kimi、etc）
├─ 网关聚合（18 个）
│  ├─ 本地（Ollama、LM Studio、Atomic Chat）
│  ├─ 聚合服务（OpenRouter、Groq、Together）
│  ├─ 企业（Azure、Bedrock、Vertex）
│  └─ 中国（DashScope、GitLawb OpenGateway）
└─ 动态发现
   ├─ 支持任意 OpenAI /v1 兼容端点
   └─ 自动发现模型列表
```

### 差异对比表

| 维度 | Claude Code | OpenClaude |
|------|-------------|-----------|
| **支持的 Provider 数** | 3 | 200+ |
| **本地推理** | 无 | Ollama、LM Studio、Atomic Chat |
| **模型发现** | 无 | OpenAI /models API、Ollama /api/tags |
| **中文模型** | 无 | MiniMax、Kimi、DashScope、Xiaomi MiMo |
| **推理模型** | 不支持 | DeepSeek R1（preserveReasoningContent） |
| **模型路由** | 固定 provider | 动态选择 200+ 模型 |
| **自定义端点** | 不支持 | 完全支持（任意 OpenAI 兼容端点） |
| **缓存策略** | 固定 | 可配置 TTL（1d、1h、etc） |
| **网关聚合** | 无 | OpenRouter、Groq、GitLawb OpenGateway |
| **代码** | 单一 provider 路径 | 通用 OpenAI Shim 路径 |

### 迁移路径

```
Claude Code 用户的迁移：

ANTHROPIC_API_KEY=sk-... ─┐
ANTHROPIC_BASE_URL=...   ├─ /provider ─► 保存为 "anthropic" preset
ANTHROPIC_MODEL=...      ─┘

↓ 可选：尝试其他 provider

OPENAI_API_KEY=... ─────► /provider ─► 选 "openai"
DeepSeek 推理模型 ──────► /provider ─► 选 "deepseek"
本地 Ollama ────────────► /provider ─► 选 "ollama"（自动发现）
```

---

## 9. 关键数据流示例

### 场景 1：用户启动 OpenClaude with OpenAI API Key

```
$ export CLAUDE_CODE_USE_OPENAI=1
$ export OPENAI_API_KEY=sk-...
$ export OPENAI_BASE_URL=https://api.openai.com/v1  # 可选
$ openclaude

↓

init.ts / loadPersistedProfile()
  ↓
resolveActiveRouteIdFromEnv(process.env)
  ├─ 检查 CLAUDE_CODE_USE_OPENAI=1 ✓
  ├─ 返回 routeId = "openai"
  └─ 如果环境变量不同，可能返回其他 routeId

↓

refreshStartupDiscoveryForActiveRoute()
  ├─ baseUrl = process.env.OPENAI_BASE_URL ?? "https://api.openai.com/v1"
  ├─ routeId = "openai"
  ├─ apiKey = resolveRouteCredentialValue({routeId: "openai", processEnv})
  │           → 按优先级查询 OPENAI_API_KEY
  └─ discoverModelsForRoute("openai", {baseUrl, apiKey})
       ├─ getRouteCatalog("openai") → 获取静态模型列表
       ├─ 如果有 discovery config，发起 GET /models
       ├─ 缓存结果（默认 1 天或无）
       └─ 返回 RouteDiscoveryResult {
            routeId: "openai",
            models: [gpt-5.4, gpt-5-mini, ...],
            source: "network" or "cache",
            error: null
          }

↓

运行时（用户在 Claude Code 中输入提示词）
  ├─ 活跃路由 = "openai"
  ├─ 获取 routeDescriptor = getRouteDescriptor("openai")
  ├─ 序列化请求为 OpenAI 格式（带 tool_use 映射）
  ├─ 发送到 baseUrl + "/v1/chat/completions"
  │   Authorization: Bearer sk-...
  ├─ 接收 OpenAI 格式响应
  ├─ 解析并映射回 Claude tool_use block 格式
  └─ 返回给用户界面
```

### 场景 2：用户启动 Ollama + 发现模型

```
$ export OPENAI_BASE_URL=http://localhost:11434/v1
$ ollama run qwen2.5-coder:7b  # 后台启动 Ollama
$ openclaude

↓

resolveRouteIdFromBaseUrl("http://localhost:11434/v1")
  ├─ parseUrl() → hostname = "localhost", port = 11434
  ├─ 匹配规则 host.endsWith(':11434') ✓
  └─ 返回 routeId = "ollama"

↓

refreshStartupDiscoveryForActiveRoute()
  ├─ routeId = "ollama"
  ├─ baseUrl = "http://localhost:11434/v1"
  ├─ apiKey = undefined（ollama.setup.requiresAuth = false）
  └─ discoverModelsForRoute("ollama", {baseUrl})
       ├─ catalog = getRouteCatalog("ollama") → { source: 'dynamic', discovery: { kind: 'ollama' } }
       ├─ probeOllamaModelCatalog({baseUrl})
       │   └─ GET http://localhost:11434/api/tags → 列出所有加载的模型
       │      返回 [{ name: "qwen2.5-coder:7b" }, { name: "llama3.1:8b" }, ...]
       ├─ 转换为 ModelCatalogEntry[] 并缓存（TTL 1 天）
       └─ 返回 RouteDiscoveryResult {
            routeId: "ollama",
            models: [{id: "qwen2.5-coder:7b", apiName: "qwen2.5-coder:7b"}, ...],
            source: "network",
            error: null
          }

↓

运行时（用户在模型列表中选择 qwen2.5-coder:7b）
  ├─ 序列化为 OpenAI 兼容请求
  ├─ POST http://localhost:11434/v1/chat/completions
  │   { model: "qwen2.5-coder:7b", messages: [...] }
  ├─ Ollama 处理（无需凭证）
  └─ 返回 OpenAI 格式响应
```

### 场景 3：用户配置 DeepSeek + 思考内容映射

```
/provider ─► 选择 "deepseek"
输入 API key
↓

getVendor("deepseek") → {
  id: "deepseek",
  transportConfig: {
    kind: 'openai-compatible',
    openaiShim: {
      preserveReasoningContent: true,
      thinkingRequestFormat: 'deepseek-compatible',
      ...
    }
  }
}

↓

运行时（调用 DeepSeek V4 Pro）
  ├─ 用户请求："理解这段代码"
  ├─ Claude SDK 封装为标准请求
  ├─ Shim 转换为 DeepSeek 格式
  │   { model: "deepseek-v4-pro", messages: [...] }
  ├─ DeepSeek 返回：{
  │     reasoning_content: "我来分析这个 Python 代码...",
  │     content: "这段代码实现了..."
  │   }
  ├─ Shim 映射回 Claude thinking block 格式：
  │   blocks = [
  │     { type: "thinking", thinking: "我来分析..." },
  │     { type: "text", text: "这段代码..." }
  │   ]
  └─ 返回给用户界面（展示思考过程 + 答案）
```

---

## 10. 模型路由算法（Model Routing）

OpenClaude 的模型路由支持两种模式：

### 模式 1：精确模型选择（Model-aware）

```typescript
用户选择模型："gpt-5.4"
↓
runtimeMetadata.getCatalogEntryForModel("openai", "gpt-5.4")
  ├─ 查找 catalog 中是否有匹配的 entry
  ├─ 检查 entry.apiName、entry.modelDescriptorId.defaultModel
  └─ 返回 ModelCatalogEntry { id: "gpt-5.4", apiName: "gpt-5.4" }
↓
构建请求：{ model: "gpt-5.4", ... }
```

### 模式 2：通用 OpenAI 兼容（Model-agnostic）

```typescript
用户选择模型："my-custom-model"（自定义模型名）
↓
如果路由支持 supportsModelRouting = true
  ├─ 直接使用用户指定的模型名
  ├─ 构建请求：{ model: "my-custom-model", ... }
  └─ 发送到 provider，由 provider 验证
```

### 模型提示词生成

当用户在 Claude Code 中调用 AI 时，系统自动：

```
1. 读取用户选择的 routeId 和 model
2. 查询 getRouteDescriptor(routeId).catalog
3. 查询 ModelDescriptor（如果 entry.modelDescriptorId 存在）
4. 从 ModelDescriptor.providerModelMap[routeId] 获取真实 API 名称
5. 发送给 LLM API

例：
  routeId = "openrouter"
  model = "gpt-5-mini"（用户看到的名称）
  ↓ lookup ModelDescriptor for "gpt-5-mini"
  ↓ modelDescriptor.providerModelMap["openrouter"] = "openai/gpt-5-mini"
  ↓ POST /chat/completions { model: "openai/gpt-5-mini", ... }
```

---

## 11. 支持的 Vendors 和 Gateways 完整清单

### Vendors（按 classification）

**Anthropic 原生（1）**
- anthropic

**OpenAI 兼容（12）**
- openai、deepseek、groq、mistral、moonshot、minimax、xiaomi-mimo、bankr、zai、venice、xai、kimi-code?

**Gemini 原生（1）**
- gemini

### Gateways（按 category）

**本地（3）**
- ollama、lmstudio、atomic-chat

**聚合/代理（5）**
- openrouter、groq、together、github、gitlawb-opengateway

**企业/云平台（5）**
- azure-openai、bedrock、vertex、dashscope-cn、dashscope-intl

**其他（1）**
- hicap（响应模式）、kimi-code（Moonshot 编程优化）、nvidia-nim

### Anthropic 代理（Proxy）
可能包括 Bedrock、Vertex 等的专用代理实现。

---

## 总结

OpenClaude 的多 provider 路由系统通过以下关键创新超越了 Claude Code 原版：

1. **统一的 Descriptor 架构**：所有 provider 用同一套配置模板，无需硬编码
2. **通用 OpenAI Shim**：任意 OpenAI /v1 兼容 API 都能工作
3. **动态模型发现**：支持 Ollama、OpenRouter 等网关的实时模型列表
4. **灵活的 Profile 系统**：用户可保存多个 provider 配置，随时切换
5. **企业友好**：支持自定义 baseUrl、upstream proxy、企业网关
6. **中文生态支持**：MiniMax、Kimi、DashScope 等国内大模型优先
7. **推理模型支持**：DeepSeek R1 的思考内容映射
8. **缓存和降级**：发现服务支持 TTL、过期降级、离线运行

这些特性使 OpenClaude 成为真正的"多 provider fork"，而不仅是简单的 API 多选。

---

# Part III — UI 与命令层


## 1. Slash 命令系统（Commands）

### 职责
OpenClaude 的命令系统提供了 118 个 slash 命令，分为以下类别：

#### 会话管理（Session Management）
- `/session` - 会话操作与切换
- `/resume` - 恢复历史会话
- `/context` - 上下文管理（交互和非交互）
- `/teleport` - 跨会话传送
- `/tag` - 会话标签
- `/export` - 导出会话内容
- `/share` - 共享会话

#### 模型与配置（Model & Config）
- `/model` - 模型选择与配置
- `/provider` - Provider 管理
- `/config` - 系统配置
- `/env` - 环境变量管理
- `/remote-env` - 远程环境配置
- `/theme` - 主题选择
- `/logo` - Logo 定制
- `/output-style` - 输出样式选择（OpenClaude 新增）
- `/vim` - Vim 模式切换（OpenClaude 新增）
- `/keybindings` - 快捷键定制

#### 调试与分析（Debug & Diagnostics）
- `/doctor` - 系统诊断
- `/cost` - 成本跟踪
- `/stats` - 统计信息
- `/debug-tool-call` - 工具调用调试
- `/perf-issue` - 性能问题分析
- `/heap-dump` - 堆转储
- `/cache-probe` - 缓存探测
- `/cache-stats` - 缓存统计
- `/usage` - 使用统计
- `/insights` - 会话分析报告

#### 代码操作（Code Operations）
- `/commit` - Git 提交（内部）
- `/commit-message` - 提交消息生成
- `/commit-push-pr` - 一键提交推送PR（内部）
- `/diff` - 文件差异展示
- `/review` - 代码审查
- `/ultrareview` - 超级审查
- `/security-review` - 安全审查
- `/auto-fix` - 自动修复
- `/autofix-pr` - PR 自动修复（内部）
- `/rewind` - 撤销更改

#### 工作流与任务（Workflows & Tasks）
- `/tasks` - 任务管理
- `/passes` - Pass 编制
- `/skills` - 技能库管理
- `/knowledge` - 知识库
- `/memory` - 内存管理
- `/plan` - 功能规划
- `/effort` - 工作量估算
- `/summary` - 总结生成

#### 集成与插件（Integrations & Plugins）
- `/mcp` - MCP 服务器管理
- `/plugin` - 插件管理
- `/reload-plugins` - 插件重载
- `/buddy` - Buddy 模式（内部条件）
- `/agents` - 代理管理
- `/fork` - 子代理创建
- `/peers` - Peer 通信（内部）

#### 身份认证与权限（Auth & Permissions）
- `/login` - 登录
- `/logout` - 登出
- `/oauth-refresh` - OAuth 刷新（内部）
- `/permissions` - 权限管理
- `/trust-dialog` - 信任对话
- `/mcp-approval` - MCP 服务器授权

#### 提示与帮助（Info & Help）
- `/help` - 帮助信息
- `/version` - 版本信息（内部）
- `/release-notes` - 发版说明
- `/wiki` - Wiki 浏览
- `/feedback` - 反馈提交
- `/onboarding` - 入门教程
- `/desktop` - 桌面应用启动
- `/mobile` - 移动应用启动

#### IDE 与工具（IDE & Tools）
- `/ide` - IDE 配置
- `/install-github-app` - GitHub App 安装
- `/install-slack-app` - Slack App 安装
- `/lsp` - LSP 配置
- `/chrome` - Chrome 集成
- `/terminalSetup` - 终端设置

#### 高级功能（Advanced Features）
- `/voice` - 语音模式（条件加载）
- `/bridge` - Bridge 模式（内部条件）
- `/assistant` - 助手模式（Kairos）
- `/brief` - Brief 模式（Kairos）
- `/proactive` - 前摄模式（内部条件）
- `/thinkback` - 思维回放
- `/thinkback-play` - 思维回放播放
- `/workflows` - 工作流脚本（条件加载）
- `/torch` - Torch 模式（内部条件）
- `/ultraplan` - UltraPlan（内部）

#### 其他
- `/clear` - 清空屏幕
- `/color` - 颜色显示
- `/copy` - 复制
- `/exit` - 退出
- `/compact` - 压缩会话
- `/upgrade` - 升级通知
- `/rate-limit-options` - 限流选项
- `/extra-usage` - 额外使用配额
- `/branch` - 分支管理
- `/files` - 文件管理
- `/add-dir` - 添加目录
- `/context-visualization` - 上下文可视化
- `/breaks` - 中断管理

### 关键文件

```
/tmp/openclaude-src/src/commands.ts (670 行)
  - COMMANDS() 数组：所有命令注册
  - getSkills()：动态加载技能
  - getCommandName()：命令名称解析
  - isCommandEnabled()：命令启用检查

/tmp/openclaude-src/src/types/command.ts
  - PromptCommand：提示型命令（由 Claude 处理）
  - LocalCommand：本地 JS 命令
  - LocalJSXCommand：TUI 组件命令
  - CommandResultDisplay：'skip' | 'system' | 'user'
  - LocalJSXCommandContext：命令上下文

/tmp/openclaude-src/src/commands/*/index.ts|js
  - 118 个命令目录，每个实现一个 slash 命令
```

### 核心数据结构

```typescript
type Command = 
  | PromptCommand      // 发送给 Claude 的提示
  | LocalCommand       // 本地 JS 执行
  | LocalJSXCommand    // React JSX TUI 渲染

interface PromptCommand {
  type: 'prompt'
  name: string
  description: string
  contentLength: number      // 用于 token 估算
  progressMessage: string
  source: 'builtin' | 'plugin' | 'bundled' | 'mcp'
  getPromptForCommand(args, context): Promise<ContentBlockParam[]>
}

interface LocalJSXCommand {
  type: 'local-jsx'
  name: string
  description: string
  load(): Promise<{ call: LocalJSXCommandCall }>
}

type LocalJSXCommandCall = (
  onDone: LocalJSXCommandOnDone,
  context: LocalJSXCommandContext,
  args: string
) => Promise<React.ReactNode>
```

### 调用链

```
用户输入 /command args
  ↓
commands.ts: parseCommand()
  ↓
COMMANDS() 数组查找
  ↓
├─ PromptCommand → 转为系统消息发送给 Claude
├─ LocalJSXCommand → 加载并调用 call()，获得 React.ReactNode
│                     由 Ink 渲染引擎渲染
└─ LocalCommand → 加载 load()，调用返回的 LocalCommandResult

LocalJSXCommand 的渲染流程：
  call() 返回 React.ReactNode
  ↓
  REPL.tsx 通过 setToolJSX() 设置
  ↓
  Ink 渲染引擎
  ↓
  终端显示
```

### 可借鉴点

1. **延迟加载（Lazy Loading）**: 用 `load()` 推迟导入，减少启动时间
2. **功能开关（Feature Flags）**: `feature('FLAG_NAME')` 条件加载命令
3. **双重模式**: 同时支持 prompt（模型驱动）和 JSX（UI 驱动）
4. **Memoize 缓存**: COMMANDS() 用 memoize 避免重复初始化
5. **命令分类方案**: 按职能而非字母序分类，易于维护

---

## 2. 快捷键系统（Keybindings）

### 职责

提供可配置的快捷键绑定系统，支持：
- 上下文感知的键盘映射（13+ 上下文）
- Chord 键支持（如 `ctrl+x ctrl+k`）
- 平台差异处理（Windows/Mac/Linux）
- 用户自定义覆盖
- 快捷键冲突检测

### 关键文件

```
/tmp/openclaude-src/src/keybindings/
  defaultBindings.ts  (274 行) - 系统默认快捷键
  types.ts            (134 行) - 类型定义
  parser.ts           - 快捷键语法解析
  resolver.ts         - 快捷键解析与查找
  match.ts            - 快捷键匹配算法
  KeybindingContext.tsx - React 上下文
  useKeybinding.ts    - React Hook
  validate.ts         - 快捷键验证
  loadUserBindings.ts - 用户快捷键加载
```

### 核心数据结构

```typescript
// 快捷键上下文（13 种）
type KeybindingContextName =
  | 'Global'           // 全局
  | 'Chat'             // 聊天输入
  | 'Autocomplete'     // 自动完成
  | 'Confirmation'     // 确认对话
  | 'Help'             // 帮助
  | 'Transcript'       // 会话记录
  | 'HistorySearch'    // 历史搜索
  | 'Task'             // 任务列表
  | 'MessageSelector'  // 消息选择
  | 'Diff'             // Diff 视图
  | 'Select'           // 通用选择
  | 'Settings'         // 设置
  | 'Plugin'           // 插件

// 快捷键动作（70+）
type KeybindingAction =
  | 'app:interrupt'         // Ctrl+C
  | 'app:exit'              // Ctrl+D
  | 'chat:submit'           // Enter
  | 'chat:cancel'           // Escape
  | 'chat:killAgents'       // Ctrl+X Ctrl+K
  | 'history:search'        // Ctrl+R
  | 'autocomplete:accept'
  | 'confirm:yes'
  | 'command:${string}'     // 动态命令

// Chord 键定义（按键序列）
type Chord = ParsedKeystroke[]

type ParsedKeystroke = {
  key: string         // 键名或字符
  ctrl: boolean
  alt: boolean
  shift: boolean
  meta: boolean
  super: boolean
}

// 按键绑定块
type KeybindingBlock = {
  context: KeybindingContextName
  bindings: Record<string, string | null>
  // 例: 'ctrl+c': 'app:interrupt'
}
```

### 默认快捷键核心

```typescript
// 全局快捷键（Global Context）
'ctrl+c'     → 'app:interrupt'         // 中断
'ctrl+d'     → 'app:exit'              // 退出
'ctrl+l'     → 'app:redraw'            // 重绘
'ctrl+t'     → 'app:toggleTodos'       // 切换任务
'ctrl+o'     → 'app:toggleTranscript'  // 切换会话记录
'ctrl+r'     → 'history:search'        // 历史搜索

// 聊天快捷键（Chat Context）
'enter'      → 'chat:submit'           // 提交
'escape'     → 'chat:cancel'           // 取消
'shift+tab'  → 'chat:cycleMode'        // 循环模式（Fast/Normal/Thinking）
'meta+p'     → 'chat:modelPicker'      // 模型选择
'meta+t'     → 'chat:thinkingToggle'   // 切换思考
'ctrl+_'     → 'chat:undo'             // 撤销（Ctrl+Shift+- on Kitty）
'ctrl+x ctrl+e' → 'chat:externalEditor' // 外部编辑器
'ctrl+s'     → 'chat:stash'            // 暂存

// Chord 键示例
'ctrl+x ctrl+k' → 'chat:killAgents'    // 串联两次按键
```

### 平台差异处理

```typescript
// Windows Terminal VT 模式检查（Shift+Tab 支持）
const SUPPORTS_TERMINAL_VT_MODE =
  getPlatform() !== 'windows' ||
  (isRunningWithBun()
    ? satisfies(process.versions.bun, '>=1.2.23')
    : satisfies(process.versions.node, '>=22.17.0 <23.0.0 || >=24.2.0'))

// 模式循环快捷键
const MODE_CYCLE_KEY = SUPPORTS_TERMINAL_VT_MODE 
  ? 'shift+tab' 
  : 'meta+m'  // Windows 降级方案

// 图像粘贴（平台适配）
const IMAGE_PASTE_KEY = getPlatform() === 'windows' 
  ? 'alt+v'   // Windows: Ctrl+V 被系统保留
  : 'ctrl+v'
```

### 调用链

```
终端按键输入
  ↓
parse-keypress.ts: 解析 KeyboardEvent
  ↓
KeybindingContext (React Context)
  ↓
useKeybinding Hook
  ↓
resolver.ts: 查询当前上下文的绑定
  ↓
match.ts: 精确匹配快捷键
  ↓
执行对应 action（dispatch 或函数调用）
```

### 快捷键验证

- `reservedShortcuts.ts`: 禁止重绑 `ctrl+c`, `ctrl+d`（内核中断/退出）
- 用户 `~/.claude/keybindings.json` 覆盖系统默认
- 冲突检测：同一上下文不允许同键不同值

### 可借鉴点

1. **上下文分层**: 13 种上下文隔离不同 UI 的快捷键空间
2. **Chord 键支持**: 允许序列键（如 Vim `g c` 风格）
3. **平台适配**: 运行时检测终端能力，动态调整快捷键
4. **保留键位**: Ctrl+C/D 硬编码，防止用户破坏核心中断
5. **用户可配置**: JSON 格式易于编辑，Hot-reload 不需重启

---

## 3. Ink TUI 渲染引擎（Ink Layer）

### 职责

Ink 是 OpenClaude 的 React-based Terminal UI 渲染引擎，类似于浏览器中的 DOM，但针对终端。

**核心职责：**
- React 组件 → 终端 ANSI 输出
- 终端 I/O 管理（stdin/stdout/stderr）
- 键盘与鼠标事件处理
- Yoga 布局引擎集成
- 屏幕缓存与差异更新
- 终端能力检测与适配

### 关键文件（956KB, 14099 行）

```
/tmp/openclaude-src/src/ink/
├── ink.tsx                    (最顶层导出)
├── root.ts                    (Ink 根实例)
├── renderer.ts                (React Reconciler)
├── reconciler.ts              (DOM 协调)
├── render-to-screen.ts        (渲染到屏幕)
├── screen.ts                  (屏幕缓存)
├── terminal.ts                (终端驱动)
├── termio/
│   ├── csi.ts                 (光标/清屏/字体命令)
│   ├── dec.ts                 (DeC 专有命令)
│   └── osc.ts                 (操作系统命令)
├── components/                (基础组件库)
│   ├── Box.tsx                (布局容器)
│   ├── Text.tsx               (文本)
│   ├── Button.tsx             (按钮)
│   ├── Link.tsx               (链接)
│   ├── ScrollBox.tsx          (滚动容器)
│   └── AlternateScreen.tsx    (备屏模式)
├── hooks/
│   ├── use-input.ts           (键盘输入)
│   ├── use-app.ts             (应用上下文)
│   ├── use-selection.ts       (文本选择)
│   └── use-terminal-*.ts      (终端特性)
├── events/
│   ├── keyboard-event.ts
│   ├── click-event.ts
│   ├── input-event.ts
│   └── emitter.ts
├── focus.ts                   (焦点管理)
├── dom.ts                      (DOM 树结构)
├── parse-keypress.ts          (键盘解析)
├── colorize.ts                (ANSI 着色)
├── wrap-text.ts               (文本换行)
├── stringWidth.ts             (字符宽度计算)
├── measurement/
│   ├── measure-element.ts
│   ├── measure-text.ts
│   └── get-max-width.ts
├── selection.ts               (文本选择状态机)
├── search-highlight.ts        (搜索高亮)
├── optimizer.ts               (帧优化)
└── ...（共 50+ 文件）
```

### 核心数据结构

```typescript
// Ink 根实例
interface Ink {
  private terminal: Terminal
  private renderer: Renderer
  private screen: Screen
  private focusManager: FocusManager
  private frameBuffer: FrameEvent[]
  
  render(node: ReactNode): Promise<void>
  unmount(): Promise<void>
}

// DOM 节点（与浏览器 DOM 平行）
type DOMElement = {
  type: 'text' | 'box' | 'component'
  parent: DOMElement | null
  children: DOMElement[]
  props: Record<string, any>
}

// 屏幕缓存
interface Screen {
  cells: Cell[][]              // 终端字符矩阵
  width: number
  height: number
  dirty: boolean
}

// 帧事件（用于差异更新）
type FrameEvent = {
  type: 'stdout' | 'interactive'
  content: string              // ANSI 输出
}

// 终端特性检测
interface Terminal {
  stdout: NodeJS.WriteStream
  stdin: NodeJS.ReadStream
  width: number
  height: number
  supportsHyperlinks: boolean
  supportsTabStatus: boolean
  supportsMouseTracking: boolean
}
```

### 渲染流程

```
React.render(<App />)
  ↓
useLayoutEffect()
  ↓
React Reconciler（协调）
  ↓
Ink Renderer（生成 DOM 树）
  ↓
Yoga Layout Engine（计算位置/大小）
  ↓
render-to-screen.ts（DOM → ANSI 文本）
  ↓
screen.ts（屏幕缓存）
  ↓
差异检测（仅输出变更行）
  ↓
termio/csi.ts（生成终端命令）
  ↓
stdout 输出（终端显示）
```

### Ink 组件库

```typescript
// 基础组件
<Box />              // Flexbox 容器（支持 width/height/flex)
<Text />             // 文本（支持 color/bold/italic)
<Newline />          // 换行符
<Spacer />           // 空白（flex: 1 用于填充）
<Button />           // 可点击按钮
<Link />             // 终端超链接

// 高级组件
<ScrollBox />        // 可滚动容器
<AlternateScreen />  // 使用备屏模式（全屏 TUI）
<RawAnsi />          // 原始 ANSI 输出
<NoSelect />         // 不可选文本
<Ansi />             // ANSI 字符串渲染

// Hooks
useInput()           // 键盘输入监听
useStdin()           // 标准输入
useApp()             // Ink 应用上下文
useSelection()       // 文本选择状态
useTerminalSize()    // 终端尺寸变化
useTerminalFocus()   // 窗口焦点事件
useTerminalTitle()   // 设置终端标题
useTabStatus()       // iTerm2 标签状态
```

### 终端 I/O 优化

```typescript
// CSI（Control Sequence Introducer）命令生成
import { cursorMove, cursorPosition, ERASE_SCREEN } from './termio/csi.js'

// 示例：光标移动到 (10, 20)
const moveCmd = cursorPosition(10, 20)  // → "\x1b[10;20H"

// 鼠标/键盘支持检测
supportsHyperlinks()        // 超链接渲染
supportsTabStatus()         // iTerm2 标签
supportsMouseTracking()     // 鼠标点击

// 差异更新（避免全屏重绘）
const diff = calculateDiff(oldScreen, newScreen)
writeDiffToTerminal(diff)   // 仅输出变更部分
```

### 可借鉴点

1. **React Reconciler**: 复用 React 生态，但针对终端优化
2. **Yoga 布局**: 与 Web CSS Flexbox 一致，易于迁移
3. **差异更新**: 仅输出变更行，减少闪烁与 I/O
4. **终端能力检测**: 运行时判断支持的特性（鼠标、超链接等）
5. **焦点管理**: 支持多个 TUI 元素的焦点切换
6. **性能优化**: Frame Buffer + 60fps 限流

---

## 4. 组件库（Components）

### 职责

提供业务层 React 组件，基于 Ink 原语和设计系统。分层：

```
Ink Primitives (Box, Text, Button)
  ↓
Design System (ThemedBox, ThemedText, Color Tokens)
  ↓
Business Components (Messages, Diff, Permissions, etc.)
```

### 关键子目录（4M，140+ 组件）

```
/src/components/
├── design-system/            (颜色/主题系统)
│   ├── color.ts
│   ├── ThemeProvider.tsx
│   ├── ThemedBox.tsx
│   └── ThemedText.tsx
├── PromptInput/              (聊天输入框)
│   ├── PromptInput.tsx       (主容器)
│   ├── VimTextInput.tsx      (Vim 模式)
│   └── BaseTextInput.tsx     (基础输入)
├── messages/                 (消息展示)
│   ├── MessageRow.tsx
│   ├── Message.tsx
│   ├── Messages.tsx
│   └── MessageTimestamp.tsx
├── diff/                     (代码差异展示)
│   ├── StructuredDiff.tsx
│   ├── FileEditToolDiff.tsx
│   └── StructuredDiffList.tsx
├── permissions/              (权限对话)
│   ├── PermissionRequest.tsx
│   ├── TrustDialog/
│   └── WorkerPendingPermission.tsx
├── mcp/                      (MCP 服务器 UI)
│   └── MCPServerApprovalDialog.tsx
├── Settings/                 (设置面板)
├── tasks/                    (任务列表)
├── skills/                   (技能管理)
├── agents/                   (代理管理)
├── memory/                   (内存管理)
├── HighlightedCode/          (代码高亮)
├── HelpV2/                   (帮助系统)
├── Spinner/                  (加载指示器)
├── StatusLine.tsx            (底部状态栏)
├── hooks/                    (自定义 React Hooks)
├── ui/                       (通用 UI 组件)
└── ...
```

### 设计系统核心

```typescript
// 主题颜色 Token
export const color = {
  black: '#000000',
  blue: '#0066ff',
  cyan: '#00ffff',
  green: '#00ff00',
  magenta: '#ff00ff',
  red: '#ff0000',
  white: '#ffffff',
  yellow: '#ffff00',
  gray: '#808080',
  // ...主题特定颜色
}

// ThemedBox：支持主题感知的容器
<ThemedBox 
  width="100%"
  padding={1}
  borderStyle="round"
  borderColor="blue"
  backgroundColor="black"
/>

// ThemedText：支持主题感知的文本
<ThemedText 
  bold
  color="green"
  inverse={false}
/>
```

### PromptInput 组件（核心）

```typescript
interface PromptInputProps {
  value: string
  onSubmit: (value: string) => void
  onCancel: () => void
  vimMode: boolean          // Vim 模式开关
  placeholder?: string
  multiline?: boolean
  autoComplete?: AutoCompleteResult[]
}

// 支持多种输入模式：
- 正常模式（readline 兼容）
- Vim 模式（OpenClaude 新增）
- 自动完成
- 多行编辑
```

### 调用链

```
REPL.tsx (大屏)
  ↓
<PromptInput />           (聊天输入)
  ├─ VimTextInput.tsx     (Vim 模式)
  └─ BaseTextInput.tsx    (正常模式)
  
<Messages />              (消息列表)
  ├─ <Message />          (单条消息)
  ├─ <StructuredDiff />   (代码差异)
  └─ <HighlightedCode />  (代码高亮)

<StatusLine />            (底部状态栏)
```

### 可借鉴点

1. **分层设计**: Primitives → Design System → Business Components
2. **主题系统**: 全局 ThemeProvider，所有组件自动适配
3. **Hooks 复用**: useInput, useSelection, useTerminalSize 等可复用
4. **组件库规模**: 140+ 组件覆盖从输入到显示的全链路

---

## 5. 大屏模式（Screens）

### 职责

实现 OpenClaude 的"主屏幕"模式，大屏、互动、持续对话。

### 关键文件

```
/src/screens/
├── REPL.tsx                  (主会话界面，~1000 行)
├── ResumeConversation.tsx    (恢复会话)
├── replInputSuppression.ts   (输入抑制规则)
├── replStartupGates.ts       (启动检查)
└── Doctor.tsx                (诊断屏幕)
```

### REPL.tsx 架构

REPL（Read-Eval-Print-Loop）是 OpenClaude 的主界面，集成：

```
┌─────────────────────────────────────────────┐
│ PromptInput (Vim mode)                      │
├─────────────────────────────────────────────┤
│ Messages (VirtualMessageList)               │
│ ├─ Assistant 消息 + StructuredDiff          │
│ ├─ User 消息                                │
│ └─ Tool 执行日志                            │
├─────────────────────────────────────────────┤
│ Spinner (thinking...)                       │
├─────────────────────────────────────────────┤
│ StatusLine (tokens, cost, model)            │
└─────────────────────────────────────────────┘
```

### 核心功能

```typescript
// 消息管理
<VirtualMessageList>       // 虚拟滚动，支持 1000+ 消息
  
// 输入处理（支持多种模式）
- PromptInputMode ('normal' | 'multiline')
- VimMode (INSERT | NORMAL)
- QueuedCommands (预加载命令)

// 事件处理
- onQuery: 提交聊天
- onQueuedCommand: 执行斜杠命令
- onInterrupt: Ctrl+C 中断
- onExit: Ctrl+D 退出

// 上下文同步
- 文件更改追踪
- MCP 服务器动态配置
- IDE 集成状态

// 调试工具
- <CostThresholdDialog /> 成本限制
- <IdleReturnDialog /> 空闲返回
- <SkillImprovementSurvey /> 反馈调查
```

### 调用链

```
REPL.tsx 挂载
  ↓
useMessages() Hook           (消息状态)
useInput() Hook              (键盘输入)
useTerminalSize() Hook       (屏幕尺寸)
useMoreRight() Hook          (UI 增强，OpenClaude)
useReplBridge() Hook         (与 IDE 通信)
  ↓
<PromptInput />
  ├─ handleSubmit()
  │   ↓
  │   API.query()            (调用 Claude)
  │   ↓
  │   setMessages()          (更新消息列表)
  │
  └─ Vim 模式状态机        (OpenClaude)
  
<Messages />
  ↓
VirtualMessageList           (虚拟滚动优化)
  ↓
渲染到 Ink 屏幕
```

### 可借鉴点

1. **虚拟滚动**: VirtualMessageList 支持 1000+ 消息不卡顿
2. **多模式输入**: 同时支持 normal 和 Vim 输入法
3. **Hook 协编**: 多个 Hook 组合管理复杂状态
4. **渐进式渲染**: Spinner 显示 thinking... 保持交互感

---

## 6. 输出样式系统（OutputStyles）—— OpenClaude 新增

### 职责

允许用户定义自定义输出样式，控制 Claude 回复的格式和风格。

### 关键文件

```
/src/outputStyles/
└── loadOutputStylesDir.ts      (样式加载与管理)

对应命令：/output-style
```

### 工作原理

```
用户目录结构：
  ~/.claude/output-styles/
    ├─ technical.md          (技术风格)
    ├─ casual.md             (随意风格)
    ├─ concise.md            (简洁风格)
    └─ verbose.md            (详细风格)

项目目录结构：
  .claude/output-styles/
    └─ custom.md             (项目定制风格)
```

### 样式定义格式

```markdown
---
name: Technical
description: Structured technical responses
keep-coding-instructions: true
---

You are a technical writer...
Focus on:
- Precise technical terminology
- Code examples with explanations
- Architecture diagrams in ASCII
```

### 核心数据结构

```typescript
interface OutputStyleConfig {
  name: string              // 样式名称
  description: string       // 样式描述
  prompt: string            // 注入的系统提示
  source: 'project' | 'user' // 来源
  keepCodingInstructions?: boolean  // 保留编码指令
}

// 加载流程
async function getOutputStyleDirStyles(cwd: string): Promise<OutputStyleConfig[]> {
  // 1. 查找 .claude/output-styles/*.md
  // 2. 加载 ~/claude/output-styles/*.md
  // 3. 项目样式覆盖用户样式
  // 4. 提取 frontmatter 和内容
  return styles
}
```

### 应用场景

- **技术风格**: 详尽的技术解释 + 代码注释
- **简洁风格**: TL;DR 优先，链接到详情
- **教学风格**: 分步骤解释，逐行代码注释
- **创意风格**: 故事叙述、比喻、示例
- **项目定制**: `.claude/output-styles/` 中的样式自动生效

### 可借鉴点

1. **Markdown + Frontmatter**: 易于编辑，不需编程
2. **项目级定制**: `.claude/output-styles/` 提供项目特定的风格
3. **动态加载**: Memoize + 缓存清理机制
4. **提示注入**: 样式作为系统提示的一部分，Claude 自然理解

---

## 7. Vim 模式（Vim）—— OpenClaude 新增

### 职责

在聊天输入框中提供完整的 Vim 编辑模式支持。

### 关键文件

```
/src/vim/
├── types.ts                  (状态机类型定义)
├── motions.ts                (运动命令)
├── operators.ts              (操作符：delete/change/yank)
├── textObjects.ts            (文本对象：word/sentence/paragraph)
└── transitions.ts            (状态转移逻辑)
```

### 状态机架构

```
VimState
├── mode: 'INSERT'
│   └── insertedText: string  (正在输入的文本)
│
└── mode: 'NORMAL'
    └── command: CommandState
        ├── idle              (等待命令)
        ├── count             (数字前缀，如 3j)
        ├── operator          (d/c/y 已按下)
        ├── operatorCount     (operator 后的数字)
        ├── operatorFind      (operator + find，如 d/pattern/)
        ├── operatorTextObj   (operator + text object，如 daw)
        ├── find              (f/F/t/T 命令)
        ├── g                 (g 前缀命令)
        ├── replace           (r 替换)
        └── indent            (>/< 缩进)
```

### 核心命令支持

#### 运动（Motions）

```vim
h, l        # 左右移动
j, k        # 上下移动（逻辑行）
gj, gk      # 上下移动（物理行）
w, W        # 单词开头（word/WORD）
b, B        # 单词末尾
e, E        # 单词结尾
0, ^, $     # 行位置（行首、非空首、行尾）
f/F/t/T c   # 查找字符 c
```

#### 操作符（Operators）

```vim
d           # 删除
c           # 修改（删除 + 进入 INSERT）
y           # 复制（yank）
```

#### 组合示例

```vim
dw          # 删除单词
d$          # 删除到行尾
3j          # 下移 3 行
caw         # 修改一个单词
d/pattern/  # 删除到 pattern
```

#### 文本对象（Text Objects）

```vim
aw, iw      # 一个单词（around/inner）
a", i"      # 双引号内
a', i'      # 单引号内
a(), a[]    # 括号/方括号
ab, aB      # ()/{} 对应的块
```

#### 特殊命令

```vim
x           # 删除当前字符
~           # 切换大小写
J           # 合并下一行
>>          # 右缩进
<<          # 左缩进
.           # 重复上一次修改
r<char>     # 替换当前字符为 <char>
```

### 核心数据结构

```typescript
type VimState =
  | { mode: 'INSERT'; insertedText: string }
  | { mode: 'NORMAL'; command: CommandState }

type CommandState =
  | { type: 'idle' }
  | { type: 'count'; digits: string }
  | { type: 'operator'; op: Operator; count: number }
  | { type: 'operatorCount'; op: Operator; count: number; digits: string }
  | { type: 'operatorFind'; op: Operator; count: number; find: FindType }
  | { type: 'operatorTextObj'; op: Operator; count: number; scope: TextObjScope }
  | { type: 'find'; find: FindType; count: number }
  // ...其他状态

type Operator = 'delete' | 'change' | 'yank'
type TextObjScope = 'inner' | 'around'
type FindType = 'f' | 'F' | 't' | 'T'

// 持久化状态（用于 . 重复和 p 粘贴）
type PersistentState = {
  lastChange: RecordedChange | null
  lastFind: { type: FindType; char: string } | null
  register: string
  registerIsLinewise: boolean
}
```

### 运动解析（motions.ts）

```typescript
// 纯函数：不修改状态，仅计算目标位置
export function resolveMotion(
  key: string,           // 'w', 'b', '$', etc
  cursor: Cursor,        // 当前光标位置
  count: number          // 重复次数
): Cursor {
  // 返回新光标位置
}

// 示例
const newPos = resolveMotion('w', cursor, 3)  // 向前 3 个单词
```

### 操作符执行（operators.ts）

```typescript
// 组织器模式：operator + motion
export function executeOperatorMotion(
  op: Operator,          // 'delete' | 'change' | 'yank'
  motion: string,        // 'w', 'j', '$', etc
  count: number,
  ctx: OperatorContext   // 文本缓冲、光标等
): void {
  // 根据 operator 和 motion 修改文本
}

// 例：dw (delete word)
executeOperatorMotion('delete', 'w', 1, ctx)
```

### 状态转移（transitions.ts）

```typescript
// 状态机驱动的键盘处理
export function handleKeyInVimMode(
  key: string,
  state: VimState,
  persistent: PersistentState,
  ctx: TransitionContext
): { newState: VimState; newPersistent: PersistentState } {
  // 根据当前状态和输入键，计算下一状态
  // 例：idle + 'd' → operator
  // 例：operator + 'w' → execute + idle
}
```

### 集成到 PromptInput

```typescript
// VimTextInput.tsx
<PromptInput vimMode={true} />
  ↓
handleKeydown()
  ↓
transitions.ts: handleKeyInVimMode()
  ↓
状态更新 (INSERT ↔ NORMAL)
  ↓
渲染光标和状态指示

// 显示当前 Vim 模式
[NORMAL] :3|j  # NORMAL 模式，count=3，motion=j
[INSERT]       # INSERT 模式，正在输入
```

### 可借鉴点

1. **状态机设计**: TypeScript discriminated unions 确保类型安全
2. **纯函数**: motions.ts 和 operators.ts 无副作用，易于测试
3. **可扩展性**: 新增运动或操作符只需扩展对应模块
4. **集成到 React**: VimState 可直接驱动组件渲染
5. **持久化**: lastChange 支持 `.` 重复，lastFind 支持 `;` 重复

---

## 总体架构关系图

```
┌─────────────────────────────────────────────────────────┐
│                      REPL.tsx (大屏)                      │
├─────────────────────────────────────────────────────────┤
│  ├─ PromptInput                                          │
│  │  ├─ VimTextInput (Vim 模式，OpenClaude)             │
│  │  └─ BaseTextInput (正常模式)                         │
│  ├─ Messages (消息列表)                                 │
│  │  ├─ Message + StructuredDiff                         │
│  │  └─ HighlightedCode                                  │
│  ├─ StatusLine (底部状态)                               │
│  └─ Command 执行 → LocalJSXCommand 组件                │
├─────────────────────────────────────────────────────────┤
│ React Hooks 层（keybindings, useInput, 等）              │
├─────────────────────────────────────────────────────────┤
│         Ink TUI 渲染引擎（950KB，50+ 文件）             │
│  ├─ React Reconciler → DOM 树                           │
│  ├─ Yoga Layout Engine → 位置/大小计算                 │
│  ├─ Screen Cache → ANSI 缓冲                           │
│  └─ Terminal Driver → stdout 输出                      │
├─────────────────────────────────────────────────────────┤
│         Commands 系统（118 个 slash 命令）              │
│  ├─ PromptCommand (发送给 Claude)                       │
│  ├─ LocalCommand (本地 JS)                              │
│  └─ LocalJSXCommand (React 组件)                       │
├─────────────────────────────────────────────────────────┤
│  快捷键系统 + OutputStyles + Vim 模式                    │
└─────────────────────────────────────────────────────────┘
```

---

## OpenClaude 特有创新

1. **OutputStyles**: 用户定义的输出格式模板系统
2. **Vim Mode**: 完整的 Vim 编辑模式状态机
3. **MoreRight**: UI 增强 Hook（stub in external build）
4. **VimTextInput**: Vim 模式集成到聊天输入框

---

## 文件统计

- **Commands**: 118 个目录 + 26K 行 commands.ts
- **Keybindings**: 14 个文件 + 274 行 defaultBindings.ts
- **Components**: 140+ 组件，4M 代码
- **Ink**: 50+ 文件，956KB，14099 行
- **Screens**: 4 个主屏（REPL + Doctor + Resume + ），1000+ 行 REPL.tsx
- **OutputStyles**: 1 个加载器
- **Vim**: 5 个模块，状态机 + motions + operators
- **Voice**: 1 个启用标志（stub）
- **MoreRight**: 1 个 Hook stub


---

# Part IV — 扩展性与接口层


## 概述

OpenClaude 是 Claude Code 的多 provider fork，核心扩展性通过 **四层接口** 实现：Skills（AI 可调用任务）、Plugins（功能组件）、Hooks（生命周期回调）、以及 Bridge/Remote（IDE 与远程会话集成）。新增的 gRPC、Web、VSCode 扩展让系统支持浏览器、IDE 和 Python SDK 的多端接入。

---

## 文字版架构图

```
┌─────────────────────────────────────────────────────────────────┐
│                        用户与外部接入端                          │
├──────────────┬──────────────────┬──────────────────┬────────────┤
│   浏览器Web  │   VSCode IDE     │   CLI 进程       │  Python SDK│
│   (Vite UI)  │   (扩展)         │   (主程序)       │  (Provider │
│              │                  │                  │   Router)  │
└──────┬───────┴──────┬───────────┴──────┬───────────┴────┬───────┘
       │ HTTP/WS      │ Bridge API       │ WebSocket      │ HTTP
       │              │ (轮询)           │ (远程会话)     │
┌──────▼──────────────▼─────────────────▼──────────────────▼───────┐
│                   OpenClaude 多协议网关层                        │
├──────────────────────────────────────────────────────────────────┤
│  Server (内嵌)    │   Bridge (HTTP/Poll) │  Remote (WebSocket)   │
│  src/server/      │   src/bridge/        │  src/remote/          │
│  (直连会话)       │   (IDE 轮询)         │  (流式推送)           │
└──────┬────────────┴──────┬────────────────┴──────┬────────────────┘
       │                   │                       │
┌──────▼───────────────────▼───────────────────────▼────────────────┐
│                    OpenClaude 内核（QueryEngine）                 │
├──────────────────────────────────────────────────────────────────┤
│  Skills System   │  Hooks System      │  Plugins System           │
│  (AI 任务层)     │  (生命周期)        │  (功能注册)               │
│  src/skills/     │  src/hooks/ (90+)  │  src/plugins/             │
└──────┬───────────┴──────┬─────────────┴──────┬─────────────────────┘
       │                  │                    │
┌──────▼──────────────────▼────────────────────▼──────────────────┐
│              底层工具与命令执行                                  │
├──────────────────────────────────────────────────────────────────┤
│  Tools (bash, read, write) │ Commands (内置 /slash) │ MCP Servers│
└──────────────────────────────────────────────────────────────────┘

新增协议路径：
  gRPC AgentService (src/grpc/) ← → proto/openclaude.proto
  Web React UI (web/src/) ←→ Server + WebSocket
  VSCode Extension (vscode-extension/) ←→ Bridge API
  Python Smart Router (python/) → Multi-provider dispatch
```

---

## 1. 技能系统 (src/skills/) — 188K

### 职责
- **加载与编译**：递归扫描 `~/.claude/skills/` 和 `.claude/skills/` 目录
- **条件激活**：根据 `paths` frontmatter 在文件变更时动态加载技能
- **MCP 集成**：通过 mcpSkillBuilders 注册远程工具为技能
- **三源合一**：Managed（策略）、User（用户主目录）、Project（项目目录）、Bundled（内置）、MCP（远程）

### 关键文件
- `loadSkillsDir.ts`（1172 行）：核心加载器，支持条件激活（path patterns）、去重（symlink 感知）
- `mcpSkillBuilders.ts`：MCP 工具的技能化桥接
- `bundledSkills.ts`：内置技能（/claude-api, /loop, /schedule 等）

### 核心数据结构
```typescript
// 技能定义
type Command = {
  type: 'prompt'
  name: string                    // 唯一标识，支持命名空间：category:skill
  source: 'userSettings' | 'projectSettings' | 'bundled' | 'mcp'
  loadedFrom: 'skills' | 'commands_DEPRECATED' | 'plugin' | 'bundled' | 'mcp'
  description: string
  paths?: string[]                // gitignore 式路径模式（条件激活）
  hooks?: HooksSettings           // 钩子配置
  async getPromptForCommand(args, context): Promise<ContentBlock[]>
}

// 动态技能三态
- Unconditional Skills: 无 paths，启动时加载
- Conditional Skills: 有 paths，文件匹配时激活
- Dynamic Skills: 在会话中发现的技能目录（.claude/skills）
```

### 调用链
```
启动 → getSkillDirCommands()
    ├─ 加载 managed/user/project/additional 源
    ├─ findSkillMarkdownFiles() → 递归 find SKILL.md
    ├─ parseSkillFrontmatterFields() → 解析 frontmatter（name, description, hooks 等）
    ├─ createSkillCommand() → 生成 Command 对象
    ├─ 去重（symlink 感知 realpath）
    └─ 分离 unconditional/conditional

文件操作 → activateConditionalSkillsForPaths()
    ├─ 检查 paths 模式是否匹配（ignore 库）
    ├─ 激活的技能转入 dynamicSkills
    └─ 触发 skillsLoaded 信号

MCP 技能 → registerMCPSkillBuilders()
    ├─ MCP 工具转化为技能（wrapper）
    └─ 注册到技能列表
```

### 可借鉴点
- **条件路径模式**：技能可声明仅在特定文件（如 `src/**/*.ts`）时才加载，减少 token 消耗
- **去重策略**：realpath 感知 symlink，避免重复加载
- **MCP 无缝集成**：远程工具自动成为 AI 可调用的技能，无需手工配置

---

## 2. 插件系统 (src/plugins/) — 28K

### 职责
- **生命周期管理**：启用/禁用内置或市场插件
- **多组件容器**：单个插件可同时提供 skills、hooks、MCP servers
- **启用状态持久化**：用户设置中保存插件启用/禁用状态

### 关键文件
- `builtinPlugins.ts`（160 行）：内置插件注册表，定义插件清单结构

### 核心数据结构
```typescript
// 内置插件定义
type BuiltinPluginDefinition = {
  name: string
  description: string
  version: string
  defaultEnabled?: boolean
  isAvailable?: () => boolean    // 条件可用（如 OS 检查）
  skills?: BundledSkillDefinition[]
  hooks?: HooksConfig
  mcpServers?: MCP[]
}

// 已加载的插件（混合内置 + 市场）
type LoadedPlugin = {
  name: string
  source: string               // 'name@builtin' 或 'name@marketplace'
  enabled: boolean
  isBuiltin: boolean
  hooksConfig: HooksConfig
  mcpServers?: MCP[]
}
```

### 调用链
```
插件启用/禁用 → registerBuiltinPlugin()
    ├─ 注册 → BUILTIN_PLUGINS map
    └─ 查询 → getBuiltinPluginDefinition(name)

获取技能 → getBuiltinPluginSkillCommands()
    ├─ 遍历启用的插件
    ├─ 提取每个插件的 skills
    └─ 转化为 Command 对象

启用状态 → getBuiltinPlugins()
    ├─ 从用户设置读 enabledPlugins[id]
    ├─ 决策：user setting > plugin default > true
    └─ 分离为 enabled/disabled 列表
```

### 可借鉴点
- **模块化设计**：技能、钩子、MCP 可作为原子单位打包成插件
- **条件启用**：isAvailable() 允许插件自测环境（如 Windows only）
- **向后兼容**：市场插件与内置插件统一 API

---

## 3. 钩子系统 (src/hooks/) — 944K（90+ 文件）

### 职责
- **生命周期绑定**：技能执行前后、工具使用、UI 更新时触发
- **状态管理**：useRemoteSession, useMailboxBridge 等集中状态
- **权限与交互**：useSwarmPermissionPoller, useCanUseTool 权限控制
- **IDE 集成**：useIDEIntegration, useDiffInIDE 与编辑器交互

### 关键文件（按类别）

#### 核心钩子
| 文件 | 职责 |
|------|------|
| `useRemoteSession.ts` | 远程会话管理（WebSocket 连接、权限请求） |
| `useMailboxBridge.ts` | 邮箱轮询桥接（IDE 通过轮询发送消息） |
| `useSwarmPermissionPoller.ts` | 权限请求轮询（从远程会话拉取权限确认） |
| `useCommandQueue.ts` | 命令队列处理 |
| `useMergedClients.ts` | 多个 Claude API 客户端合并 |

#### IDE/Bridge 钩子
- `useIDEIntegration.tsx`：IDE 连接状态、文件编辑通知
- `useDiffInIDE.ts`：将 AI 生成的 diff 回写到编辑器
- `useIdeSelection.ts`：获取编辑器当前选中内容
- `useIdeAtMentioned.ts`：处理 @编辑器 的上下文注入

#### 权限与工具
- `useCanUseTool.tsx`：工具可用性检查（权限表单）
- `useApiKeyVerification.ts`：API 密钥验证
- `toolPermission/PermissionContext.ts`：权限上下文管理
- `toolPermission/handlers/{interactive,swarm,coordinator}Handler.ts`：权限请求路由

#### UI/输入处理
- `useTextInput.ts` / `useVimInput.ts`：文本输入处理
- `useGlobalKeybindings.tsx`：全局快捷键绑定
- `useTypeahead.tsx`：自动完成建议
- `useNotifyAfterTimeout.ts`：延迟通知

#### 通知系统（notifs/ 子目录）
- `useLspInitializationNotification.tsx`：LSP 初始化提醒
- `usePluginInstallationStatus.tsx`：插件安装状态
- `useRateLimitWarningNotification.tsx`：速率限制警告
- `useTeammateShutdownNotification.ts`：远程会话断开通知

### 核心数据结构
```typescript
// 钩子注册（在技能或插件中）
type HooksSettings = {
  'before-invoke'?: boolean | HookHandler    // 执行前
  'after-invoke'?: boolean | HookHandler     // 执行后
  'before-tool'?: boolean | HookHandler      // 工具使用前
  'after-tool'?: boolean | HookHandler       // 工具使用后
  'on-permission'?: boolean | HookHandler    // 权限请求
}

// 权限请求上下文
type PermissionContext = {
  alwaysAllowRules: {
    command: string[]           // 始终允许的命令
    readFile: string[]          // 始终允许读的文件
    writeFile: string[]         // 始终允许写的文件
  }
  askPermission: (prompt, type) => Promise<boolean>
}
```

### 调用链（关键示例）

#### 远程会话（WebSocket 推送）
```
useRemoteSession() 初始化
  ├─ 创建 RemoteSessionManager
  ├─ 建立 WebSocket（SessionsWebSocket）
  └─ 监听消息：
      ├─ SDK 文本消息 → 显示
      ├─ 工具调用 → 请求权限
      ├─ ActionRequired → 显示对话框
      └─ 服务端断开 → 重连

权限请求处理
  └─ onPermissionRequest()
      ├─ 对话框等待用户输入
      ├─ 用户确认 / 拒绝
      └─ sendEventToRemoteSession() 回复
```

#### 邮箱轮询（HTTP 轮询 fallback）
```
useMailboxBridge() 定期轮询
  ├─ 间隔：pollConfig (100ms–30s 自适应)
  ├─ 邮箱.poll() → 获取待发消息
  └─ onSubmitMessage() → 提交给 AI 引擎
```

#### IDE 差异同步
```
useDiffInIDE() 监听 diffData
  ├─ 从 AI 提取 diff
  ├─ 通过 bridge 发送编辑指令
  └─ IDE 执行代码编辑
```

### 可借鉴点
- **灵活的权限模型**：不仅有全局 allow/deny，还有条件规则、会话级覆盖
- **双向通道**：既支持推送（WebSocket）也支持轮询（邮箱），兼容不同 IDE
- **钩子与技能绑定**：技能可声明需要的钩子，增强 AI 可观测性

---

## 4. Bridge 系统 (src/bridge/) — 548K（核心 IDE 集成）

### 职责
- **HTTP 轮询网关**：IDE 通过轮询向 OpenClaude 发送消息（邮箱模式）
- **完成回写**：将代码编辑、权限响应等回写到 IDE
- **会话生命周期**：单会话或多会话模式下的会话创建、复用、销毁
- **跨防火墙兼容**：支持代理、信任设备 token、OAuth 刷新

### 关键文件

| 文件 | 大小 | 职责 |
|------|------|------|
| `bridgeMain.ts` | 1800 行 | 主循环：HTTP 长轮询、会话管理、错误恢复 |
| `bridgeApi.ts` | 400 行 | API 客户端：POST /work, POST /sessions 等 |
| `types.ts` | 200 行 | 数据结构：WorkResponse, SessionDoneStatus 等 |
| `replBridge.ts` | 500 行 | REPL 模式特化（异步 read/write） |
| `bridgeMessaging.ts` | 300 行 | 消息队列与确认机制 |
| `inboundMessages.ts` | 300 行 | 解析 IDE → Server 的消息（代码编辑、权限回复） |
| `trustedDevice.ts` | 150 行 | 信任设备 token 管理 |
| `jwtUtils.ts` | 200 行 | OAuth token 刷新调度 |
| `workSecret.ts` | 400 行 | 工作密钥解码与会话注册 |

### 核心数据结构
```typescript
// Bridge 配置
type BridgeConfig = {
  dir: string                       // 工作目录
  maxSessions: number               // 最大会话数
  spawnMode: 'single-session' | 'worktree' | 'same-dir'
  bridgeId: string                  // 本 bridge 实例 UUID
  environmentId: string             // 环境 ID（claude.ai 侧）
  sessionKey?: string               // 会话密钥（恢复用）
}

// 工作请求与响应
type WorkResponse = {
  id: string
  type: 'work'
  environment_id: string
  state: string                     // 'running' | 'completed' | ...
  data: {
    type: 'session' | 'healthcheck'
    id: string                      // 工作 ID
  }
  secret: string                    // base64 WorkSecret
  created_at: string
}

// 会话完成状态
type SessionDoneStatus = 'completed' | 'failed' | 'interrupted'

// IDE 消息类型（从 inboundMessages.ts）
type InboundMessage = 
  | { type: 'text', content: string }
  | { type: 'file_edit', path: string, content: string }
  | { type: 'permission_response', permitAll: boolean }
  | { type: 'interrupt' }
```

### 调用链（从 IDE 到 OpenClaude）

```
IDE 发送消息（邮箱）
  └─ Bridge 轮询：
      ├─ 间隔：pollConfig（适应系统压力）
      ├─ GET /work (通过邮箱获取 IDE 消息)
      ├─ 解析 WorkResponse.data
      └─ 转发给 OpenClaude 进程

OpenClaude 执行
  └─ Bridge 回写：
      ├─ 收集输出（文本、工具使用、权限请求）
      ├─ 打包成 SessionDoneStatus
      └─ 回写给 IDE：
          ├─ 编辑指令（diff）
          ├─ 权限请求对话框
          └─ 最终结果

会话复用（multi-session）
  ├─ spawnMode = 'worktree' → 每次新会话独立 git worktree
  ├─ spawnMode = 'same-dir' → 共享 cwd
  └─ spawnMode = 'single-session' → bridge 退出时销毁

OAuth 刷新（createTokenRefreshScheduler）
  └─ 在有效期前 5 分钟刷新
      ├─ 保持长轮询会话活跃
      └─ 防止 401 故障
```

### HTTP 轮询细节（vs WebSocket）

**为什么 Bridge 使用 HTTP 轮询而非 WebSocket？**
- IDE（特别是 VSCode）可能在代理或防火墙后
- HTTP 长连接经过代理时更稳定
- 轮询间隔自适应：无活动 → 30s，有活动 → 100ms
- 支持断网恢复：自动指数退避重连

**轮询间隔配置（src/bridge/pollConfig.ts）**
```typescript
type PollIntervalConfig = {
  poll_interval_ms_not_at_capacity: number  // 默认 1000ms
  poll_interval_ms_at_capacity: number      // 默认 200ms（有任务时加速）
  non_exclusive_heartbeat_interval_ms: number  // 心跳
  multisession_poll_interval_ms_*: number   // 多会话模式下的配置
}
```

### 可借鉴点
- **轮询自适应**：系统忙时加速轮询，空闲时减速，节约资源
- **会话复用策略**：支持单会话/多会话，git worktree 隔离
- **可信设备**：OAuth 高安全场景下的强身份验证
- **错误恢复**：指数退避、状态重建，不丢失会话上下文

---

## 5. 远程会话 (src/remote/) — 48K

### 职责
- **WebSocket 流式连接**：用于需要推送的场景（Web UI、远程 REPL）
- **权限请求对话**：双向交互，服务端发起权限确认
- **会话持久化**：跨浏览器标签页的消息恢复

### 关键文件
| 文件 | 职责 |
|------|------|
| `RemoteSessionManager.ts` | 远程会话生命周期、消息路由 |
| `SessionsWebSocket.ts` | WebSocket 连接管理、重连逻辑 |
| `sdkMessageAdapter.ts` | SDK 消息格式 ↔ 内部格式转换 |
| `remotePermissionBridge.ts` | 权限请求合成回复消息 |

### 核心数据结构
```typescript
type RemoteSessionConfig = {
  sessionId: string
  getAccessToken: () => string
  orgUuid: string
  hasInitialPrompt?: boolean
  viewerOnly?: boolean            // 纯查看模式（不发送中断）
}

type RemotePermissionResponse = 
  | { behavior: 'allow', updatedInput: Record<string, unknown> }
  | { behavior: 'deny', message: string }
```

### 调用链
```
Web UI / 远程 REPL
  └─ RemoteSessionManager 初始化
      ├─ 建立 WebSocket → SessionsWebSocket
      ├─ 发送初始消息：ChatRequest (via gRPC 或 SDK 流)
      └─ 监听服务端事件：
          ├─ TextChunk → 流式显示
          ├─ ToolCallStart → 请求权限确认
          ├─ ActionRequired → 等待用户输入
          └─ FinalResponse → 显示最终结果

权限交互
  ├─ 服务端发起 ActionRequired (prompt_id, question)
  ├─ 用户在 UI 回复
  ├─ 客户端发送 UserInput { reply, prompt_id }
  └─ 服务端恢复执行
```

### 可借鉴点
- **跨标签页恢复**：存储会话 ID，可在浏览器标签页间漫游
- **纯查看模式**：支持只读 REPL（不能中断，不刷新标题）

---

## 6. 内嵌 Server (src/server/) — 20K

### 职责
- **直连会话**：不经 claude.ai，在本机开启 HTTP 服务供 IDE 连接
- **会话索引**：持久化会话列表到 `~/.claude/server-sessions.json`
- **资源管理**：并发会话限制、空闲超时

### 关键文件
- `types.ts`：ServerConfig, SessionInfo, SessionIndex 等
- `directConnectManager.ts`：会话创建与生命周期

### 核心数据结构
```typescript
type ServerConfig = {
  port: number
  host: string
  authToken: string               // 简单认证
  unix?: string                   // Unix socket 替代 TCP
  idleTimeoutMs?: number          // 空闲多久自动关闭
  maxSessions?: number
  workspace?: string
}

type SessionIndexEntry = {
  sessionId: string
  transcriptSessionId: string     // 用于 --resume
  cwd: string
  permissionMode?: string
  createdAt: number
  lastActiveAt: number
}
```

### 调用链
```
IDE 连接
  └─ localhost:8000 (或指定端口)
      ├─ POST /sessions → 创建新会话
      ├─ GET /sessions/{id} → 查询状态
      └─ WebSocket /ws/{id} → 连接会话流

会话复用
  ├─ 检查 ~/.claude/server-sessions.json
  ├─ 若会话仍活跃，复用进程
  └─ 否则创建新进程
```

### 可借鉴点
- **会话持久化**：支持关闭 IDE 后继续 Server，重新连接可恢复
- **简化认证**：可用 authToken 代替 OAuth，适合团队 LAN 部署

---

## 7. gRPC 服务 (src/grpc/ + src/proto/) — 24K（OpenClaude 新增）

### 职责
- **RPC 流式通信**：双向流，客户端和服务端同时发送消息
- **比 HTTP 轮询更低延迟**：适合需要快速反馈的场景
- **Protocol Buffer 序列化**：更紧凑的消息格式

### 关键文件
| 文件 | 行数 | 职责 |
|------|------|------|
| `proto/openclaude.proto` | 101 | protobuf 定义：AgentService, ClientMessage, ServerMessage |
| `grpc/server.ts` | 200+ | gRPC 服务实现：handleChat 流处理 |

### 核心数据结构（protobuf）
```protobuf
service AgentService {
  rpc Chat(stream ClientMessage) returns (stream ServerMessage);
}

// 客户端 → 服务端
message ClientMessage {
  oneof payload {
    ChatRequest request = 2;      // 初始化请求
    UserInput input = 3;          // 用户响应
    CancelSignal cancel = 4;      // 中止信号
  }
}

message ChatRequest {
  string message = 1;
  string working_directory = 2;
  optional string model = 4;
  string session_id = 5;          // 会话持久化
}

// 服务端 → 客户端
message ServerMessage {
  oneof event {
    TextChunk text_chunk = 1;
    ToolCallStart tool_start = 2;
    ToolCallResult tool_result = 3;
    ActionRequired action_required = 4;
    FinalResponse done = 5;
    ErrorResponse error = 6;
  }
}

message ActionRequired {
  string prompt_id = 1;
  string question = 2;
  ActionType type = 3;  // CONFIRM_COMMAND | REQUEST_INFORMATION
}
```

### Bridge vs gRPC 对比

| 维度 | Bridge (HTTP 轮询) | gRPC |
|------|------|------|
| 协议 | HTTP/1.1 长轮询 | HTTP/2 双向流 |
| 延迟 | 100ms–30s（自适应） | 几 ms（流式推送） |
| 穿越防火墙 | 好（所有 HTTP 都过） | 不好（需配置反向代理） |
| 消息大小 | JSON（较大） | Protobuf（紧凑） |
| 客户端 | IDE 原生 HTTP | gRPC 客户端库 |
| 使用场景 | IDE 集成（VSCode, etc） | Web UI、Python SDK、移动端 |

### 可借鉴点
- **会话持久化**：gRPC ChatRequest 包含 session_id，支持跨连接恢复
- **流式权限请求**：ActionRequired 可在流中等待用户输入，无需额外往返
- **原子消息**：Protobuf oneof 保证单次只有一个事件类型，避免复杂状态机

---

## 8. Web 子项目 (web/) — 独立 Vite 项目（OpenClaude 新增）

### 结构
```
web/
├── src/
│   ├── App.tsx              # React 主应用
│   ├── content.ts           # 静态内容（导航、特性列表）
│   ├── main.tsx             # 入口
│   └── styles.css           # 全局样式
├── public/                  # 静态资源
├── vite.config.ts           # Vite 构建配置
├── package.json             # 依赖
└── bun.lock                 # 锁定文件（Bun 包管理）
```

### 职责
- **营销网站**：OpenClaude 官网，展示特性、安装指南
- **Web UI**（如果需要）：可扩展为完整的浏览器 IDE

### 与内核集成
```
Web 浏览器
  └─ Vite 开发服务器 / 构建输出
      ├─ 可内嵌 iframe 连接 gRPC 服务
      └─ 或通过 grpc-web 代理（@grpc/grpc-web）
          └─ gRPC Server (src/grpc/)
              └─ QueryEngine + Tools
```

### 可借鉴点
- **零配置 React**：Vite 速度快（HMR 亚秒级）
- **可扩展为 REPL UI**：通过 gRPC-web 接入 OpenClaude 内核

---

## 9. VSCode 扩展 (vscode-extension/) — OpenClaude 新增

### 结构
```
vscode-extension/
└── openclaude-vscode/
    ├── src/
    │   ├── extension.js              # 扩展入口、命令注册
    │   ├── state.js                  # 工作区状态管理
    │   ├── presentation.js           # UI 模型构建
    │   ├── chat/
    │   │   ├── chatProvider.js       # Chat View Provider
    │   │   ├── sessionManager.js     # 会话生命周期
    │   │   ├── processManager.js     # OpenClaude 进程启动
    │   │   ├── diffController.js     # Diff 视图与编辑
    │   │   ├── messageParser.js      # 消息解析
    │   │   ├── protocol.js           # 通信协议
    │   │   └── chatRenderer.js       # 消息渲染
    │   └── ...
    ├── package.json
    └── extension.manifest.json        # VSCode 扩展清单
```

### 职责
- **启动 OpenClaude**：在 VS Code 中启动 claude 进程
- **Chat View 集成**：显示会话消息、权限请求、diff
- **代码编辑回写**：处理 diff，通过 VSCode API 应用编辑
- **桥接通信**：通过 Bridge HTTP 轮询与 OpenClaude 通信

### 与 Bridge 的集成
```
VSCode 扩展
  └─ ChatProvider 启动会话
      ├─ sessionManager.js 创建 OpenClaude 进程
      ├─ 进程回传 Bridge 端口号
      └─ 扩展连接 Bridge HTTP API：
          ├─ GET /work (邮箱轮询)
          ├─ POST /permission (权限回复)
          └─ POST /edit (代码编辑)

权限请求
  ├─ Bridge 轮询到权限请求
  ├─ 转化为 VSCode QuickPick 对话框
  └─ 用户确认后，回复给 Bridge

代码编辑
  ├─ Bridge 从 OpenClaude 收到编辑指令
  ├─ diffController.js 解析 diff
  └─ VSCode TextEdit API 应用修改
```

### 可借鉴点
- **ProcessManager**：管理子进程生命周期，支持启动/重启/停止
- **DiffController**：将 unified diff 转化为 VSCode TextEdit，精确应用
- **SessionManager**：复用会话逻辑，保持同一 Bridge 连接

---

## 10. Python 桥接 (python/) — OpenClaude 新增

### 文件结构
```
python/
├── smart_router.py          # 智能路由：自动选择最优 provider
├── atomic_chat_provider.py  # Atomic Chat provider（本地 LLM）
├── ollama_provider.py       # Ollama provider（本地推理）
├── __init__.py
├── requirements.txt
└── tests/
```

### 职责

#### 1. smart_router.py（核心 — 智能路由）
```python
# 功能：根据延迟、成本、健康状态选择最优 provider
class Provider:
  name: str                    # "openai" | "gemini" | "ollama" | "atomic-chat"
  ping_url: str               # 健康检查 URL
  api_key: str                # API 密钥
  cost_per_1k_tokens: float   # 成本
  latency_ms: float           # 实测延迟
  error_rate: float           # 错误率

class SmartRouter:
  async initialize()          # 启动时探测所有 provider
  async route(messages, model, stream)  # 路由单个请求
  score(strategy)             # 计分：latency | cost | balanced
```

**使用场景**：
```python
from smart_router import SmartRouter
router = SmartRouter()
await router.initialize()

# 请求自动路由到最优 provider
result = await router.route(
  messages=[{"role": "user", "content": "..."}],
  model="sonnet",
  stream=True
)
```

**环境变量**：
```bash
ROUTER_MODE=smart              # 智能路由
ROUTER_STRATEGY=balanced       # 成本×延迟 均衡
ROUTER_FALLBACK=true           # 自动故障转移
OPENAI_API_KEY=...
GEMINI_API_KEY=...
OLLAMA_BASE_URL=http://localhost:11434
ATOMIC_CHAT_BASE_URL=http://127.0.0.1:1337
```

#### 2. atomic_chat_provider.py（本地推理）
```python
# 简单 wrapper：适配 OpenAI 兼容 API
class AtomicChatProvider:
  async chat(messages, model)
  stream=True → 逐 token 推送
```

#### 3. ollama_provider.py（本地推理）
```python
# Ollama 兼容，支持 LLaMA 2, Mistral 等开源模型
class OllamaProvider:
  async chat(messages, model)
  async pull(model)            # 下载模型
```

### Python SDK 使用示例
```python
# 直接调用 smart_router
router = SmartRouter()
await router.initialize()

response = await router.route(
  messages=[{"role": "user", "content": "解释一下什么是 gRPC"}],
  model="gpt-4",  # 自动降级到 gpt-4-mini 如果超预算
  stream=True
)

# 或使用特定 provider
from atomic_chat_provider import AtomicChatProvider
provider = AtomicChatProvider()
response = await provider.chat(messages, model="local-llm")
```

### 与 OpenClaude 内核的集成
```
OpenClaude gRPC Server (src/grpc/)
  │
  ├─ 客户端 A: VSCode 扩展 (TypeScript, Bridge HTTP)
  ├─ 客户端 B: Web UI (React, gRPC-web)
  └─ 客户端 C: Python SDK + SmartRouter
      ├─ 请求 → smart_router.route()
      ├─ 选择 provider (OpenAI, Ollama, Atomic Chat)
      └─ 调用 provider.chat()
          └─ 结果回传 gRPC Server

可选架构：SmartRouter 直接对接 LLM，不经 OpenClaude
  Python 应用
    └─ SmartRouter
        ├─ OpenAI API
        ├─ Gemini API
        ├─ Ollama (local)
        └─ Atomic Chat (local)
```

### 可借鉴点
- **多 provider 支持**：同时接入商业 + 开源 LLM
- **动态评分**：基于实时延迟和成本自动选择，不用硬编码
- **故障转移**：provider A 失败 → 自动降级到 B，提高可靠性
- **成本与延迟权衡**：允许策略切换（latency | cost | balanced）

---

## Skills vs Plugins vs Hooks — 边界说明

| 层级 | 何时用 | 例子 |
|------|--------|------|
| **Skills** | AI 需要作为任务调用的功能 | `/claude-api`（调用 Claude API）、`/loop`（重复执行）、自定义代码生成 workflow |
| **Plugins** | 多个 skills + hooks + MCP servers 的组合包 | 一个完整的代码审查插件，包括权限检查钩子、审查 skill、MCP 代码分析服务 |
| **Hooks** | 生命周期事件（before/after、权限、UI）| 技能执行前检查权限、AI 生成代码后自动格式化、IDE 文件变更时动态加载技能 |

### 决策树
```
需要 AI 调用？
  ├─ YES → Skills（可选：添加 hooks 控制生命周期）
  │   └─ 多个 skills 组成一套功能？
  │       └─ YES → 打包为 Plugin
  │
  └─ NO：生命周期事件？
      ├─ YES → Hooks（在技能或插件中注册）
      └─ NO：功能组件？
          └─ MCP server（技能不支持时）
```

### 分离关切示例
```
// skill：/code-review（AI 可调用）
// hooks：before-invoke 检查权限，after-invoke 提交改动

[SKILL.md]
---
name: code-review
description: 自动代码审查
hooks:
  before-invoke: true
  after-invoke: true
---

检查改动权限，允许则执行审查...

// 钩子执行
Hook before-invoke → useCanUseTool() 检查权限 → 提示对话框
Hook after-invoke → 自动 git commit
```

---

## 架构总结表

| 系统 | 源码位置 | 大小 | 职责 | 协议 |
|------|---------|------|------|------|
| Skills | src/skills/ | 188K | AI 可调用任务，条件激活 | 内部 |
| Plugins | src/plugins/ | 28K | 组件容器（skills+hooks+MCP） | 内部 |
| Hooks | src/hooks/ | 944K | 生命周期回调，权限控制 | 内部 |
| Bridge | src/bridge/ | 548K | IDE HTTP 轮询网关 | HTTP/Poll |
| Remote | src/remote/ | 48K | WebSocket 流式连接（Web/REPL） | WebSocket |
| Server | src/server/ | 20K | 直连本机会话 | HTTP/WS |
| gRPC | src/grpc/ + src/proto/ | 24K | 高性能 RPC 接口 | gRPC/HTTP2 |
| **Web** | **web/** | **独立项目** | 营销网站 + 可扩展 Web UI | HTTP/gRPC-web |
| **VSCode Ext** | **vscode-extension/** | **独立项目** | IDE 集成 | Bridge HTTP |
| **Python SDK** | **python/** | **独立项目** | 多 provider 智能路由 | HTTP/gRPC |

---

## 关键扩展点

### 1. 新增 AI provider（Python 层）
```python
class MyProvider:
  async chat(messages, model, stream):
    # 连接你的 LLM
    pass

# 注册到 SmartRouter
smart_router.providers.append(MyProvider(...))
```

### 2. 新增 Skill（CLAUDE.md 兼容）
```markdown
---
name: my-skill
description: Custom task
allowed-tools: [bash, read, write]
paths: src/**/*.py  # 条件激活
---

执行逻辑...
```

### 3. 新增 Hook（在技能中）
```markdown
---
hooks:
  before-invoke: true
  after-invoke: true
  on-permission: true
---
```

### 4. 新增 MCP server
```typescript
// 自动被技能系统包装为 skill
registerMCPSkillBuilders({ ... })
```

### 5. 新增 IDE（通过 Bridge）
任何支持 HTTP 的编辑器都能通过 Bridge 连接：只需实现邮箱轮询 + diff 回写。

---

## 总结

OpenClaude 的扩展性设计遵循 **分层接口** 模式：
1. **Skills**：AI 任务层（what）
2. **Hooks**：生命周期控制层（when）
3. **Plugins**：功能组合层（组织）
4. **Bridge/Remote/Server/gRPC**：通信协议层（how）
5. **Web/VSCode/Python**：客户端适配层（where）

这样可以让新的 provider、IDE、功能独立演进，同时保持与内核的松耦合。gRPC 与 Bridge 并存，分别服务低延迟场景（gRPC）和高兼容性场景（Bridge HTTP 轮询）。


---

# Part V — 基础设施与杂项层


## 1. CLI 模块 (src/cli/ — 488K)

**职责**
负责交互式终端界面的输出、流式传输、状态同步和远程通信。是用户与核心引擎之间的唯一接口，处理所有实时反馈、权限提示和流事件的渲染。

**关键文件**
- `print.ts` (212KB) — 核心渲染引擎，INK/React 组件树和色彩输出
- `structuredIO.ts` — 结构化事件流（工具调用、权限请求）
- `remoteIO.ts` — 云端会话管理（CCR 基础设施、会话令牌）
- `transports/` — 四种传输层：WebSocket、SSE、混合模式、gRPC
- `handlers/` — 命令执行句柄（代理、插件、审查）

**核心数据结构**
```typescript
- PrintState: 全局渲染队列、待处理消息、权限队列
- TransportConfig: 传输选择、远程端点、认证令牌
- ToolPermissionContext: 权限状态、拒绝理由、用户响应
```

**调用链**
```
cli.tsx (entrypoint)
  → init() [bootstrap] → loadPlugins/loadMCP → getTools()
    → print.tsx [INK renderer] → structuredIO [event streaming]
      → selected-transport (WS/SSE/hybrid/gRPC)
        → backend (Anthropic/OpenAI-compatible/Gemini)
```

**可借鉴点**
- 多传输抽象：同一事件模型支持 4 种不同后端（本地 CLI、Web、远程 gRPC、Android Termux）
- 流式安全：NDJSON 序列化防止 JSON 部分写入导致客户端解析失败
- 权限即时反馈：权限请求与执行同步，不阻塞主循环

---

## 2. 入口点模块 (src/entrypoints/ — 388K)

**职责**
三重入口点，每个支持不同的调用方式。CLI 是交互式终端，SDK 是编程化会话管理，MCP 是工具暴露。

### 2.1 CLI 入口 (cli.tsx)

**职责**
- 快速路径检测（--version 零导入）
- 全局填充（Node 18 File 兼容性）
- 特性禁用（禁用 Claude.ai 特定 beta 如工具搜索）
- 环境设置（gRPC 内存、corepack 固定）

**核心流程**
```
1. 解析 --version/--help 快速路径
2. 动态加载 init()（配置、OTP、应急）
3. 初始化 CLI 渲染器（INK/React）
4. 启动主循环（提示 → 工具调用 → 流式输出）
```

**特点**
- Feature flag 驱动（build.ts 预处理替换为字面值，Dead Code Elimination）
- 禁用实验性 API beta（防止 Anthropic 特定功能崩溃）

### 2.2 SDK 入口 (sdk/index.ts)

**职责**
- 会话管理（创建、列表、删除）
- 查询执行（Query Engine）
- 权限控制（自动批准/手动提示/拒绝）
- 类型导出（Zod schema + TypeScript）

**核心 API**
```typescript
- createSession(project_dir, model) → SessionId
- deleteSession(id) / listSessions()
- query(id, prompt, options) → AsyncIterator<QueryEvent>
- setPermissionMode(mode: 'auto' | 'manual' | 'deny')
```

**特点**
- Stub 泄露检测：启动时验证核心模块不是 TUI 存根
- 分离构建：dist/sdk.mjs 单独打包，零 CLI 依赖
- 类型安全：agentSdkTypes.ts 导出运行时校验的 Zod 类型

### 2.3 MCP 入口 (mcp.ts)

**职责**
- 将 OpenClaude 工具暴露为 MCP Server
- 工具去重（MCP 工具优先，去除重复的内置工具）
- 权限网关（工具调用前校验权限）
- 错误转化（Zod 错误 → JSON Schema）

**核心流程**
```
MCP StdioServerTransport
  → loadReexposedMcpTools() [加载外部 MCP servers]
  → getCombinedTools(builtins, external)
  → StdioServer.setRequestHandlers(
      list_tools → 返回并集
      call_tool → validatePermissions → executeAndStreamResult()
    )
```

**特点**
- 反向集成：MCP 本身是 Claude Code 的 MCP Server（自我引用）
- 权限一致性：使用相同的权限上下文校验工具使用
- 内置命令：MCP_COMMANDS 常量包含 review 命令（本地 git 审查）

---

## 3. 初始化与启动模块 (src/bootstrap/ + src/entrypoints/init.ts — 56K + part of 388K)

**职责**
全局初始化：从 process.env 解析到第一条提示。包括配置、OTP、权限、模型选择、memoize 缓存。

**核心初始化阶段**
```
1. enableConfigs() — 加载 CLAUDE.md / settings.json / provider profile
2. applySafeConfigEnvironmentVariables() — 信任前仅加载公开变量
3. 权限对话（信任本项目）→ 完整环境变量应用
4. 模型选择 → Provider 可达性校验
5. MCP 服务器发现
6. 插件加载
7. 内存（MEMORY.md / auto-memory）加载
```

**关键服务初始化**
- LSP 管理器（JavaScript/TypeScript 增强）
- OAuth 客户端（Codex、GitHub、Gemini）
- 政策限制（企业合规）
- 远程托管设置（SSO/MDM）
- 预连接 Anthropic API（TCP 优化）

**特点**
- Memoize 装饰器：init() 多次调用同一次执行
- 诊断日志（PII 清理）：启动时间点检测性能瓶颈
- 优雅关闭：cleanup registry 注册退出钩子

---

## 4. 上下文与状态管理 (src/context/ + src/state/ — 56K + 64K)

### 4.1 React Context (src/context/)

**用途**
- `notifications.tsx` — 祝贺、建议、警告的瞬时通知队列
- `modalContext.tsx` — 权限对话、确认框、错误对话
- `stats.tsx` — 成本、token 使用、性能指标
- `QueuedMessageContext.tsx` — 排队的用户输入
- `overlayContext.tsx` — 浮层状态（工具输出、日志）
- `voice.tsx` — 语音模式状态

### 4.2 全局应用状态 (src/state/)

**AppStateStore (21KB)**
```typescript
type State = {
  originalCwd: string              // 稳定项目根（worktree 后不变）
  projectRoot: string              // 用于历史、技能、会话身份
  cwd: string                       // 当前工作目录（EnterWorktree 可更新）
  modelUsage: {[modelName]: ModelUsage}
  mainLoopModelOverride: ModelSetting | undefined
  totalCostUSD / totalAPIDuration / totalToolDuration
  turnHookDurationMs / turnToolDurationMs / turnClassifierDurationMs
  strictToolResultPairing: boolean // HFI 模式：工具结果不匹配则失败
  sdkAgentProgressSummariesEnabled: boolean
  ...
}
```

**特点**
- 分离 originalCwd 和 cwd：支持 worktree 后稳定的会话身份
- 模型成本追踪：每模型分离使用统计
- 特殊模式标志：Kairos（持久会话）、strictToolResultPairing（HFI 调试）

**selectors.ts** — 衍生状态计算（e.g., 总成本 = sum(usage))

---

## 5. 持久化内存模块 (src/memdir/ — 104K)

**职责**
长期记忆管理：与 Claude Code 原版 CLAUDE.md 和 MEMORY.md 并行运行，支持私有和团队作用域。

### 5.1 与 Claude Code 原版的关系

| 功能 | 原版 Claude Code | OpenClaude |
|------|-----------------|-----------|
| CLAUDE.md | 项目范围内的工作指南 | 保持不变 |
| MEMORY.md | 用户/反馈/项目记忆 | 支持 + 新增 auto-memory |
| 作用域 | 单一（项目）| 双重：私有 + 团队 |
| 自动提取 | 无 | feature('EXTRACT_MEMORIES') |
| 同步 | 文件系统 | 文件系统 + 远程团队同步 |

### 5.2 内存类型 (memoryTypes.ts)

```typescript
type MemoryType = 'user' | 'feedback' | 'project' | 'reference'

// user（总是私有）
// - 用户角色、目标、知识、偏好
// - 保存：学习用户特征时
// - 使用：定制回应时

// feedback（默认私有，仅在项目范围内保存为团队）
// - 工作方法指导、规则原因、边界条件判断
// - 保存：用户更正或确认方法时
// - 使用：引导未来行为

// project（倾向团队）
// - 进行中的工作、截止日期、协调问题
// - 保存：学习谁在做什么时
// - 使用：理解上下文并预测协调障碍

// reference（私有或团队）
// - 外部链接、API 文档、架构图
// - 保存：发现有用的资源时
// - 使用：快速查询已知事实
```

### 5.3 核心文件

**memdir.ts** — 入口点
- `truncateEntrypointContent()` — 行数 ≤200 且字节 ≤25KB 的安全截断
- 支持前言（yaml frontmatter）：`type: user`, `created_at`, `scope: private/team`
- 警告追加：超长条目显示截断警告

**paths.ts** — 路径管理
- `getAutoMemPath()` — `~/.openclaude/memory/{projectId}/auto.md`
- `getUserMemPath()` — `{projectRoot}/.claude/MEMORY.md`
- `getTeamMemPath()` — `{projectRoot}/.claude/MEMORY_TEAM.md`（需 feature('TEAMMEM')）

**findRelevantMemories.ts** — 向量检索
- 基于问题相似度的前 K 召回（余弦相似度 / BM25 混合）
- 自动转换相对日期为绝对日期（防止时间流逝后失效）

**teamMemPaths.ts / teamMemPrompts.ts** — 团队内存同步
- 远程托管：git sync 或 Git Lawb API
- 权限：团队成员之间共享，不导出给外部 API

### 5.4 自动记忆提取 (feature: EXTRACT_MEMORIES)

运行时发现新事实并建议保存：
```
用户回应: "这与 Jira-2048 相关，下周要合并"
  → 自动检测：项目初始化 + 截止日期
  → 建议写入：private feedback + team project 记忆
```

---

## 6. Zod 校验与类型 (src/schemas/ + src/types/ — 12K + 156K)

**职责**
运行时类型安全与通用类型定义。

**schemas/hooks.ts** 仅有文件 — 钩子定义 (Zod)
- HookCallbackMatcher / PluginHookMatcher
- 事件筛选（匹配规则）

**types/ 目录** — TypeScript 纯类型导出
```
command.ts      — 斜线命令定义与执行
message.ts      — Message / UserMessage 类型
permissions.ts  — 权限模式、令牌、拒绝理由
plugin.ts       — 插件加载/错误/类型
ids.ts          — SessionId / AgentId 等 branded types
logs.ts         — 日志格式、诊断事件
textInputTypes.ts — 文本输入队列、排队命令
```

**generated/** — 自动生成的类型（SDK、agentSdkTypes）

---

## 7. 常量库 (src/constants/ — 176K)

**核心常量**
- `prompts.ts` (53KB) — 系统提示（agent 角色、指令、工具说明）
- `outputStyles.ts` — 色彩配置、主题
- `oauth.ts` — OAuth 提供商端点、范围
- `apiLimits.ts` — 速率限制、token cap
- `betas.ts` — 可选 API beta 标志
- `cyberRiskInstruction.ts` — 安全政策文本
- `product.ts` — 品牌字符串、版本
- `spinnerVerbs.ts` — 进度动画文本

---

## 8. 配置升级迁移 (src/migrations/ — 48K)

**用途**
向后兼容的版本升级。每个文件处理一个语义化迁移。

**迁移列表**
- `migrateFennecToOpus.ts` — Claude 2 → Claude 3 Opus
- `migrateOpusToOpus1m.ts` / `migrateOpusToOpus1m.ts` — 上下文窗口扩展
- `migrateSonnet1mToSonnet45.ts` / `migrateSonnet45ToSonnet46.ts` — 模型版本更新
- `migrateAutoUpdatesToSettings.ts` — 自动更新策略
- `migrateEnableAllProjectMcpServersToSettings.ts` — MCP 服务器发现
- `resetAutoModeOptInForDefaultOffer.ts` — opt-in 重置

**特点**
- 非破坏性：原设置保留，添加新字段或转换值
- 仅运行一次：迁移标志防止重复

---

## 9. 本地编译模块 (src/native-ts/ — 148K)

**职责**
本机 C++ 模块的 TypeScript 转译。Bun 原生扩展。

**模块**
- `color-diff/` — 像素差异算法（GUI 屏幕比较）
- `file-index/` — 文件树索引（快速路径查询）
- `yoga-layout/` — Facebook Yoga 布局引擎（INK UI）

**特点**
- 直接包装 C++ （无 FFI 边界成本）
- 仅在需要时链接（Bun 构建集成）

---

## 10. 启动脚本 (bin/ + scripts/)

### 10.1 bin/openclaude (705 字节)
```bash
#!/usr/bin/env node
# 检查 dist/cli.mjs 存在性
# 存在 → 导入并执行
# 不存在 → 错误提示 + build 或 bun run dev
```

### 10.2 scripts/build.ts (39KB)

**职责**
- Bun bundler 配置
- Feature flag 预处理（字面值替换）
- 外部包列表管理
- Telemetry 剥离插件
- 构建后恢复源文件

**Feature Flag** (build.ts 行 22-62)
```typescript
禁用（需 Anthropic 基础设施）：
  VOICE_MODE, PROACTIVE, KAIROS, BRIDGE_MODE, DAEMON,
  AGENT_TRIGGERS, ABLATION_BASELINE, CONTEXT_COLLAPSE,
  COMMIT_ATTRIBUTION, UDS_INBOX, BG_SESSIONS,
  WEB_BROWSER_TOOL, CHICAGO_MCP, COWORKER_TYPE_TELEMETRY, MCP_SKILLS

启用（上游默认）：
  COORDINATOR_MODE, BUILTIN_EXPLORE_PLAN_AGENTS, BUDDY, MONITOR_TOOL, TEAMMEM, MESSAGE_ACTIONS

启用（新功能）：
  DUMP_SYSTEM_PROMPT, CACHED_MICROCOMPACT, AWAY_SUMMARY,
  TRANSCRIPT_CLASSIFIER, ULTRATHINK, TOKEN_BUDGET, HISTORY_PICKER,
  QUICK_SEARCH, SHOT_STATS, EXTRACT_MEMORIES, FORK_SUBAGENT,
  VERIFICATION_AGENT, PROMPT_CACHE_BREAK_DETECTION, HOOK_PROMPTS
```

**外部包管理**
- CLI_EXTERNALS — Node.js 内置 + 生产依赖（不打包）
- SDK_EXTERNALS — SDK 不依赖 React/Ink（分离构建）

### 10.3 scripts/start-grpc.ts (50 行)

**职责**
gRPC 无头服务器启动。镜像 CLI bootstrap 流程。

```
init() → enableConfigs() → OAuth 令牌水合
  → 配置文件应用 → Provider 校验
  → GrpcServer.start(port, host)
```

支持环境变量：`GRPC_PORT` (default 50051), `GRPC_HOST` (default localhost)

### 10.4 scripts/grpc-cli.ts (130 行)

轻量级 gRPC 客户端，镜像 CLI 的权限提示行为。

---

## 11. README.md — OpenClaude 的核心卖点

### 与原版 Claude Code 对比

| 特性 | Claude Code | OpenClaude |
|------|---|---|
| 提供商 | Anthropic Claude API only | **多提供商** |
| 支持平台 | macOS/Linux/Windows | **+ Android (Termux)** |
| 本地模型 | ✗ | **Ollama** |
| 源代码 | 闭源 | **MIT 开源** |
| VS Code 集成 | ✓ | ✓ (捆绑扩展) |
| gRPC 服务器 | ✗ | **✓ 无头模式** |
| 提供商路由 | ✗ | **✓ agentModels + agentRouting** |

### 核心卖点

1. **统一 CLI 跨提供商**
   - OpenAI 兼容（OpenRouter、DeepSeek、Groq、Mistral、LM Studio）
   - Gemini、GitHub Models、Codex、Ollama、Atomic Chat
   - 一个工作流，多个后端

2. **保存提供商配置文件**
   - `/provider` 交互式设置
   - `~/.openclaude.json` 中的配置文件
   - 无需手动 env 编辑

3. **完整工具支持**
   - Bash、文件读写编辑
   - Grep、glob、代理、任务
   - MCP（Model Context Protocol）
   - Web 工具

4. **Web 搜索开箱即用**
   - 非 Claude 模型：DuckDuckGo 免费回退
   - Anthropic 模型：原生提供商搜索
   - 可选：Firecrawl 集成更好的网页抓取

5. **代理路由优化成本**
   ```json
   {
     "agentModels": {
       "cheap-model": { "base_url": "...", "api_key": "..." },
       "strong-model": { "base_url": "...", "api_key": "..." }
     },
     "agentRouting": {
       "Explore": "cheap-model",
       "Plan": "strong-model",
       "default": "strong-model"
     }
   }
   ```

6. **无头 gRPC 服务器**
   - CI/CD、自定义 UI、多语言客户端
   - StdIO + 双向流式传输
   - 权限请求即时发送

---

## 12. PLAYBOOK.md — 本地 Ollama 工作流

**日常启动**
```powershell
bun run dev:profile      # 快速启动，使用已保存的配置文件
bun run dev:fast         # 低延迟预设 (llama3.2:3b)
bun run dev:code         # 更好的编码质量 (qwen2.5-coder:7b)
```

**配置文件初始化**
```bash
bun run profile:init -- --provider ollama --model llama3.1:8b
bun run profile:init -- --provider ollama --goal coding  # 自动推荐
bun run profile:recommend -- --goal coding --benchmark   # 预览
```

**诊断**
```bash
bun run doctor:runtime         # 人类可读检查
bun run doctor:runtime:json    # JSON 诊断（自动化）
bun run doctor:report          # 持久化报告为 reports/doctor-runtime.json
bun run hardening:check        # 快速 smoke + runtime doctor
bun run hardening:strict       # 包含 typecheck
```

**推荐的本地模型**
| 用途 | 模型 | 注意 |
|------|------|------|
| 快速 | llama3.1:8b | 通用 |
| 编码（高质量）| qwen2.5-coder:14b | 需要更多硬件 |
| 低资源 | 小版本模型 | 推理质量降低 |

**重启后恢复检查清单**
```
bun run doctor:runtime
bun run doctor:report
bun run smoke
```

---

## 13. ANDROID_INSTALL.md — 新平台支持

**为什么 OpenClaude 支持 Android？**
- 原版 Claude Code 仅支持 macOS/Linux/Windows
- **OpenClaude 新增** Termux 支持，通过 proot-distro Ubuntu 环境

**部署模型**
```
Termux (Android 应用)
  → proot-distro (虚拟 Ubuntu chroot)
    → Bun runtime + Node.js
      → OpenClaude CLI
        → OpenRouter / 其他免费提供商
```

**为什么需要 proot？**
- Bun 本地支持 Linux x86_64 和 ARM64，但不支持 Android 进程模型
- proot 创建完整的 Ubuntu 文件系统，Bun 可在其中运行
- 下载大小：~200-400 MB Ubuntu + Bun

**推荐免费模型（OpenRouter）**

截至 2026 年 4 月：
- **`qwen/qwen3.6-plus-preview:free`**（最佳免费，预览期）
  - 1M token 上下文窗口
  - Terminal-Bench 2.0（超过 Claude Opus 61.6 vs 59.3）
  - Chain-of-thought 推理 + 本地工具调用
  - 无 TPM 限制（仅 20 req/min, 200 req/day）

- 其他免费选项：
  - `qwen/qwen3-coder:free` — 纯编码任务
  - `openai/gpt-oss-120b:free` — OpenAI 开放模型
  - `nvidia/nemotron-3-super-120b-a12b:free` — MoE 混合
  - `meta-llama/llama-3.3-70b-instruct:free` — 可靠通用

**为什么不用 Groq/Cerebras 免费层？**
- Groq: TPM 限制太低（6K-12K tokens/min），OpenClaude 系统提示 ~50K
- Cerebras: 即使 llama3.1-8b 也超过 TPM 限制
- OpenRouter 免费层无 TPM 限制

**使用**
```bash
# Step 1: Termux 中
pkg update && pkg upgrade
pkg install nodejs-lts git proot-distro
git clone https://github.com/Gitlawb/openclaude.git
cd openclaude
npm install && npm link

# Step 2: proot Ubuntu 中
proot-distro install ubuntu
proot-distro login ubuntu
curl -fsSL https://bun.sh/install | bash
cd /data/data/com.termux/files/home/openclaude
bun run build

# Step 3: 配置 OpenRouter 环境变量
echo 'export CLAUDE_CODE_USE_OPENAI=1' >> ~/.bashrc
echo 'export OPENAI_API_KEY=your_key' >> ~/.bashrc
echo 'export OPENAI_BASE_URL=https://openrouter.ai/api/v1' >> ~/.bashrc
echo 'export OPENAI_MODEL=qwen/qwen3.6-plus-preview:free' >> ~/.bashrc
source ~/.bashrc

# Step 4: 启动
node dist/cli.mjs
# 选择选项 3（第三方平台）
```

**Android 是否是新平台？**
- **是的**。Claude Code 从未支持 Android。
- OpenClaude 通过 Termux + proot 首次添加 Android 支持（0.11.0）。
- 这是对原版 Claude Code 功能的重大扩展。

---

## 14. 服务层高层概述 (src/services/ — 3M)

服务层（3M）按子目录分类，仅列出关键服务，不逐文件展开。

| 子目录 | 用途 | 关键文件 |
|--------|------|---------|
| `api/` | Anthropic/OpenAI API 包装 | client 初始化、速率限制 |
| `oauth/` | OAuth 流（Codex、GitHub、Gemini） | token 存储、刷新 |
| `mcp/` | MCP 服务器管理与去重 | client、handler、权限 |
| `plugins/` | 插件加载与生命周期 | 沙箱、权限、事件 |
| `github/` | 仓库信息、分支、PR 操作 | search、webhook |
| `lsp/` | LSP（Language Server Protocol） | TypeScript/JavaScript 增强 |
| `SessionMemory/` | 会话中的内存管理 | 追踪、同步 |
| `analytics/` | Telemetry / GrowthBook（功能标志） | 事件记录、A/B 测试 |
| `compact/` | 上下文压缩（模型级） | 消息摘要、工具结果截断 |
| `contextCollapse/` | 上下文折叠优化 | 消息聚合 |
| `extractMemories/` | 自动记忆提取 | 事实检测、建议 |
| `autoDream/` | 自动代理模式（功能禁用） | 代理调度 |
| `autoFix/` | 自动错误修复工作流 | 故障检测、补救 |
| `wiki/` | 可搜索的知识库 | 文档索引 |
| `tips/` | 上下文帮助提示 | 工具提示库 |
| `toolUseSummary/` | 工具使用统计与摘要 | 调用计数、性能指标 |
| `remoteManagedSettings/` | 远程 MDM/SSO 设置 | 下载、应用 |
| `settingsSync/` | 跨设备设置同步 | git 推送、拉取 |
| `teamMemorySync/` | 团队记忆共享（feature: TEAMMEM） | 合并冲突、权限 |
| `policyLimits/` | 企业政策强制 | 速率限制、支出上限 |
| `PromptSuggestion/` | AI 驱动的提示建议 | 上下文相关性排名 |
| `AgentSummary/` | 代理执行摘要 | 结果聚合 |
| `MagicDocs/` | 生成式文档（特定功能） | 类型生成、评论 |

**关键架构模式**
- 惰性初始化：大多数服务仅在首次使用时启动
- 优雅降级：不可用服务不会阻塞主循环
- 特性门控：通过 feature() 标志分离可选服务

---

## 15. 工具和实用程序层高层概述 (src/utils/ — 8.6M)

工具层（8.6M）是最大的，列出主要子目录及单句说明。

| 子目录 | 用途 |
|--------|------|
| `bash/` | Bash 工具实现、命令执行、流式输出 |
| `git/` | Git 操作（提交、rebase、分支） |
| `github/` | GitHub API（search、PR、issue） |
| `model/` | 模型选择、成本计算、令牌计数 |
| `permissions/` | 权限模式、拒绝追踪、审计日志 |
| `settings/` | 配置文件解析、验证、缓存 |
| `shell/` | shell 检测、PowerShell/Bash 抽象 |
| `plugins/` | 插件发现、加载、权限 |
| `mcp/` | MCP 协议序列化、客户端连接 |
| `sandbox/` | 沙箱环境、限制、隔离 |
| `memory/` | 向量相似度、记忆检索 |
| `messages/` | 消息格式化、类型转换 |
| `todo/` | Todo 列表解析、状态管理 |
| `task/` | 任务队列、后台执行 |
| `hooks/` | 事件钩子、post-sampling 中间件 |
| `background/` | 后台任务调度 |
| `filePersistence/` | 文件缓存、写入批处理 |
| `secureStorage/` | 密钥库、OAuth 令牌存储 |
| `powershell/` | PowerShell 命令生成 |
| `computerUse/` | 屏幕像素对比、鼠标位置 |
| `dxt/` | 纹理压缩用于屏幕传输 |
| `claudeInChrome/` | Chrome 扩展集成（stub） |
| `deepLink/` | 深层链接解析 |
| `nativeInstaller/` | 本地依赖管理（ripgrep） |
| `teleport/` | 会话迁移（Kairos 模式） |
| `swarm/` | 多代理协调 |
| `ultraplan/` | 深度规划模式 |
| `suggestions/` | 行内建议 UI |
| `skills/` | 技能发现与加载 |
| `storage/` | 本地存储、数据库 |
| `telemetry/` | 事件跟踪、指标 |

**关键工具**
最常用的工具在 `tools.ts` 中列出并通过权限过滤：
- Read/Write/Edit 文件
- Bash / PowerShell 执行
- Grep / Glob 搜索
- Git 操作
- Agent / Task 执行
- MCP / Web 工具

---

## 总结

OpenClaude 基础设施分层清晰：

1. **入口层** — CLI/SDK/MCP 三个不同的调用方式
2. **初始化层** — memoized init() 的完整启动流程
3. **状态管理** — 分离的 React Context + 全局 AppStateStore
4. **持久化** — 文件系统优先（MEMORY.md + auto-memory），可选团队同步
5. **传输层** — 抽象多种后端（本地 CLI、WebSocket、SSE、gRPC）
6. **工具与服务** — 庞大的工具库 + 3M 服务模块，特性门控可选功能
7. **特性保护** — Feature flag 与 Dead Code Elimination，防止外部用户遭遇内部 API 500 错误

**最大差异** — 对比 Claude Code 原版：
- 多提供商支持（OpenAI/Gemini/Ollama/自定义）
- Android 支持（新平台）
- 无头 gRPC 服务器（CI/CD 集成）
- 开源 MIT 许可（贡献友好）
- 代理路由与成本优化（enterprise 场景）

---

## 附录 A — 与 Claude Code 2.1.88 的差异点汇总

OpenClaude 是 Claude Code 的活跃 fork，**~80% 内核共享**（main.tsx / query / Tool / hooks / skills / bridge / coordinator / memdir / remote / commands / ink），剩下 20% 是 OpenClaude 的差异化改造。本附录把差异按"新增 / 改造 / 删除 / 重命名"四类列出。

### A.1 新增模块（OpenClaude 独有）

| 模块 | 体积 | 作用 | 对应章节 |
|---|---|---|---|
| `src/integrations/` | 464K | 多 provider 路由（vendors × gateways × models × profile） | Part II 全章 |
| `src/upstreamproxy/` | 36K | 上游协议转译（OpenAI ↔ Anthropic ↔ Gemini） | Part II §5 |
| `src/grpc/` + `src/proto/` | 24K | gRPC 服务接口（取代 / 补充 HTTP bridge） | Part IV §7 |
| `src/outputStyles/` | 8K | 输出样式系统（默认 / explanatory / learning） | Part III §6 |
| `src/vim/` | 56K | Vim 模式编辑（normal / insert / visual） | Part III §7 |
| `web/` | 独立子项目 | Vite + React Web UI（远程访问内核） | Part IV §8 |
| `vscode-extension/` | 独立子项目 | VSCode 原生扩展 | Part IV §9 |
| `python/` | 独立子项目 | Python SDK + 本地 router | Part IV §10 |
| `scripts/provider-*.ts` | — | provider profile bootstrap / launch / recommend | Part II §2、Part V §10 |
| `ANDROID_INSTALL.md` | — | Termux + proot 安装 Android 支持 | Part V §13 |

### A.2 改造模块（与 Claude Code 不同实现）

| 模块 | Claude Code 2.1.88 | OpenClaude 0.11.0 |
|---|---|---|
| **API 客户端** | 仅 Anthropic SDK + Bedrock + Vertex | 通过 `integrations/` 路由到 11 vendors + 18 gateways + 200+ 模型 |
| **provider 配置** | 环境变量 `ANTHROPIC_API_KEY` | `~/.openclaude/profile.json` + `provider:init` / `provider:recommend` 引导 |
| **流式响应** | Anthropic SSE 直连 | OpenAI / Gemini / Anthropic 三种流式协议适配后归一 |
| **tool_use 协议** | Anthropic 原生 | `compatibility.ts` 把 OpenAI function_call / Gemini tool_call 转为统一 ToolUseBlock |
| **Cost tracking** | Anthropic billing | 多 vendor token 计价表（`integrations/models/`） |
| **MCP server 入口** | `entrypoints/mcp.ts` | 同名但兼容多 provider |
| **Codex 兼容模式** | 仅作为 provider | `dev:codex` profile + `codex:` prefix 命令 |

### A.3 已知删除 / 简化

> 主要是 Anthropic 私有特性。OpenClaude 公布的 fork 删了部分 enterprise 功能（如 Anthropic 后台 telemetry / sync 服务），用 `verify:privacy` 脚本（`scripts/verify-no-phone-home.ts`）保证不回传。具体清单需对比 `git log` 的初始 fork 提交。

### A.4 命名差异（同一概念不同名）

| Claude Code | OpenClaude |
|---|---|
| `claude` 主命令 | `openclaude` |
| `~/.claude/` 配置 | `~/.openclaude/` |
| 包名 `@anthropic-ai/claude-code` | `@gitlawb/openclaude` |
| 默认 model `claude-sonnet-4-6` 等 | profile 推荐：`gitlawb-opengateway/mimo`（自家网关） + 200+ 可选 |

---

## 附录 B — 自研 Agent 内核可借鉴清单

如果要做一个 Web/多租户/多 provider 的 agent 内核（如 FFAI Agent），OpenClaude 的以下设计值得借鉴 / 反思：

### B.1 直接借鉴

1. **多 provider 路由层 = `integrations/` 模式**：`vendor descriptor` + `gateway adapter` + `routeMetadata` 三层解耦——新增 provider 只需写一个 descriptor + 一个 gateway，不动内核。**强烈推荐复用此模式**。详见 Part II §1–§5。
2. **协议转译层 = `compatibility.ts` + `upstreamproxy/`**：OpenAI ↔ Anthropic ↔ Gemini 三协议互通的归一化方案，可直接照搬。Part II §5。
3. **Tool 接口规范 = `Tool.ts` 的 8 个生命周期方法**：`name / description / inputSchema / call / renderToolUseMessage / renderToolResultMessage / isReadOnly / isEnabled` —— 比直接用 OpenAI function calling 接口更适合 agent 场景。Part I §四。
4. **Hooks 系统 90+ 文件**：每个生命周期都可插（pre-tool / post-tool / on-message / on-response / on-error），是规则注入的最佳形态。Part IV §3。
5. **Skills + Plugins + Hooks 三层扩展**：边界明确（skill = 工作流模板 / plugin = 工具集合 / hook = 生命周期回调）。Part IV §3 末。
6. **memdir 持久化记忆**：分类型（user / feedback / project / reference）+ MEMORY.md 索引，是个比 single CLAUDE.md 更可演进的方案。Part V §5。

### B.2 反思借鉴（OpenClaude 也未完美解决）

1. **多 agent 协调（coordinator）依然是单进程内 fork**：要做分布式多 agent，得在此基础上加分布式 lock + 任务队列。Part I §六。
2. **gRPC vs HTTP bridge 并存**：OpenClaude 自己也没收敛——HTTP bridge 给 IDE，gRPC 给独立客户端。多租户场景应该统一到 gRPC（带 mTLS）。Part IV §4 vs §7。
3. **Web UI 独立子项目，但是只读**：`web/` 当前主要是状态展示，不能直接驱动 query。多租户场景需要把 Web 提升到与 CLI 平等的接入面（带 auth）。Part IV §8。
4. **single-tenant**：profile 配置在 `~/.openclaude/`，多租户场景必须改为 per-request profile。Part II §2。

### B.3 不建议照搬

1. **Ink TUI 引擎**：FFAI Agent 是 Web，不需要 Ink。但 Ink 的"虚拟 DOM 渲染流式输出"思路可借鉴到 Web 的流式 UI。Part III §3。
2. **49 个内置工具全部塞进 `tools/`**：体积膨胀（2.7M）。多租户场景应该把工具按 plan / org 切分按需加载。Part I §五。
3. **`CLAUDE.md` / `AGENTS.md` 双入口**：OpenClaude 是为兼容性，自研产品没必要双写——选一个就够。

---

## 附录 C — 架构问答补遗

> 阅读本文档过程中沉淀的几个反直觉点，单独抽出作为速查。

### C.1 "接入层"的真正含义

"接入层" = **外部客户端把请求送进 OpenClaude 内核的方式**。OpenClaude 内核（`main.tsx + query + tools`）是一个 Node 进程，外部客户端有 4 种方式触达：

| 接入方式 | 谁用 | 模块 | 特点 |
|---|---|---|---|
| **同进程直接调用** | CLI（`openclaude` 命令本身）、Python SDK in-proc 模式 | `entrypoints/cli.tsx`、`entrypoints/sdk` | 0 序列化最快；只能本机 |
| **HTTP 轮询** | VSCode 扩展、JetBrains 插件 | `bridge/` | 简单可靠、断开不丢状态、无需长连接 |
| **WebSocket 双向流** | Web UI、远程客户端 | `remote/` + `server/` | 双向流式、低延迟、server push |
| **gRPC** | Python SDK 远程模式、第三方多语言客户端 | `grpc/` + `proto/` | 强类型 + 多语言 + 流式 |

**关键澄清**：CLI **不走** bridge。CLI 自己就是宿主进程，直接 `import { query }`。bridge / remote / server / grpc 是给"另外一个进程"的客户端准备的。

### C.2 为什么内核画在 UI 之上（而不是之下）

传统 Web 是"UI → API → 内核 → DB"自上而下的请求链——UI 主动、内核被动。
Agent 反过来——**内核是中心编排器，UI 只是它驱动的输出设备之一**：

```
                   ┌──→ UI 渲染（推 token / 工具状态）
                   │
内核（query.ts）──┼──→ 工具执行（Read / Bash / Edit）
                   │
                   └──→ LLM 请求（流式接收）
```

`main.tsx` 是 React 组件，但它**不是用户调用 query**；query 跑起来后 React 通过 hooks 订阅状态变化、被动重渲。React 在这里被当成"渲染管线"，不是"控制器"。

### C.3 外部客户端接入：WebSocket / HTTP / gRPC 怎么选

| 场景 | 推荐 | 理由 |
|---|---|---|
| 浏览器 Web UI / 移动 App | **WebSocket** | 浏览器原生支持、双向流式必需 |
| VSCode / JetBrains 插件 | **HTTP 轮询（bridge 模式）** | IDE 进程隔离场景下，poll 简单到不会出 bug |
| Python / Go / Rust SDK 第三方集成 | **gRPC** | 强类型 + 自动生成 client + server-streaming |
| 微服务内调用 / 企业网关后 | **gRPC** | mTLS / 拦截器 / 限流生态成熟 |
| 一次性脚本、CI 集成 | **HTTP REST** | curl 就能调，无依赖 |
| 同机器子进程 | **stdin/stdout JSON-RPC** 或 **Unix socket** | 零网络栈开销 |

**WebSocket 的隐性成本**（常被忽略）：断线重连 / 消息去重 / 序号补齐都要自己实现；企业代理 / CDN 对 WS 支持参差不齐；多租户必须 sticky session 否则掉上下文；无 schema，演进时容易破契约。

**现代折中**：从零设计就用 **gRPC + server-streaming**——拿到 WebSocket 双向流式 90% 的能力，浏览器场景用 **gRPC-Web + Envoy/Connect-RPC** 转译。OpenClaude 当前 4 套并存（bridge + remote + grpc + cli）是从 Claude Code fork 来的历史包袱。

### C.4 一句话总结 OpenClaude 与 Claude Code 的本质差异

> **Claude Code 是"垂直整合的产品"**——内核为 Anthropic 模型量身定做，端到端优化。
> **OpenClaude 是"水平抽象的平台"**——同样的内核，但所有可能"上游不同"的地方都被开了一刀。

代码量上 OpenClaude 涨了 ~30%，**几乎全涨在 `integrations/` + `hooks/` + 多接入面**这三处，**核心 query/Tool/coordinator 改动很小**。典型的 "fork → 加抽象层 → 而非重写内核" 的演进路径。

> **跨实现对比**：与 Cursor / Aider / Cline / OpenCode / FFAI Agent 的横向对比见 [`agent-implementations-comparison.md`](./agent-implementations-comparison.md)。

---

## 文档元信息

- **OpenClaude 版本**：v0.11.0（2026-05-14 release）
- **源码位置**：`/tmp/openclaude-src/`（clone from `https://github.com/Gitlawb/openclaude`）
- **生成时间**：2026-05-14
- **生成方式**：5 个并行 Explore agent 扫描 38 个 src/ 子目录 + 4 个顶层独立子项目
- **总长度**：约 4400 行
- **配套文档**：[`claude-code-reference.md`](./claude-code-reference.md)（Claude Code 2.1.88 内核分析）；[`00-architecture.md`](./00-architecture.md)（FFAI Agent 内核架构 v0.1）

> 本报告非官方，仅供研究。
