# Claude Code 2.1.88 源码全貌参考

> **本文档定位**：为 FFAI Agent 内核（参见 [`00-architecture.md`](./00-architecture.md) v0.1）提供业界参考实现的逐目录解构。基于 npm 包 `@anthropic-ai/claude-code@2.1.88` 的 source map 还原源码（**非官方**，仅供研究），位置 `/home/chentao/Code/claude-code-sourcemap/restored-src/src/`。
>
> **报告生成方式**：4 个并行 Explore agent 扫描 35 个顶层子目录 + 18 个根文件（共 1332 个 .ts/.tsx 文件），按"职责 / 关键文件 / 数据结构 / 调用链 / 可借鉴点"五段输出。
>
> **使用方式**：自研 agent 设计时遇到具体子系统的实现选型问题，回查对应章节。**不是要照抄**——Claude Code 是 TUI/单租户/Codex provider，我们是 Web/多租户/多 provider，差异点见 `00-architecture.md` §4–§5。

---

## 目录

- [一、内核与工具层](#一内核与工具层)
  - [1. 主循环与引擎（根文件）](#1-主循环与引擎根文件)
  - [2. Tool.ts 工具接口规范](#2-toolts-工具接口规范)
  - [3. tools/ 43+ 内置工具](#3-tools-43-内置工具)
  - [4. query/ 查询配置与钩子](#4-query-查询配置与钩子)
  - [5. coordinator/ 多 agent 协调](#5-coordinator-多-agent-协调)
  - [6. tasks/ 后台任务框架](#6-tasks-后台任务框架)
- [二、UI 与命令层](#二ui-与命令层)
  - [7. commands/ Slash 命令系统](#7-commands-slash-命令系统)
  - [8. keybindings/ 快捷键系统](#8-keybindings-快捷键系统)
  - [9. components/ TUI 组件库](#9-components-tui-组件库)
  - [10. screens/ 大屏模式](#10-screens-大屏模式)
  - [11. ink/ TUI 渲染引擎](#11-ink-tui-渲染引擎)
  - [12. buddy/ AI 伴侣](#12-buddy-ai-伴侣)
  - [13. voice/ 语音交互](#13-voice-语音交互)
  - [14. 根文件：dialogLaunchers / interactiveHelpers / replLauncher / ink.ts](#14-根文件diaoglaunchers--interactivehelpers--replauncher--inkts)
- [三、扩展性与集成层](#三扩展性与集成层)
  - [15. skills/ 技能系统](#15-skills-技能系统)
  - [16. plugins/ 插件系统](#16-plugins-插件系统)
  - [17. hooks/ 钩子系统](#17-hooks-钩子系统)
  - [18. assistant/ 会话历史](#18-assistant-会话历史)
  - [19. remote/ WebSocket 远程会话](#19-remote-websocket-远程会话)
  - [20. server/ 与 bridge/ IDE 桥接](#20-server-与-bridge-ide-桥接)
  - [21. services/ 服务层](#21-services-服务层)
  - [22. memdir/ 持久化记忆](#22-memdir-持久化记忆)
  - [23. upstreamproxy/ 上游代理](#23-upstreamproxy-上游代理)
- [四、基础设施与杂项](#四基础设施与杂项)
  - [24. cli/ CLI 输出与 I/O 转发](#24-cli-cli-输出与-io-转发)
  - [25. entrypoints/ 程序入口](#25-entrypoints-程序入口)
  - [26. bootstrap/state.ts 全局初始化](#26-bootstrapstatets-全局初始化)
  - [27. context/ React Context 与会话上下文](#27-context-react-context-与会话上下文)
  - [28. state/ 状态存储](#28-state-状态存储)
  - [29. schemas/ Zod 校验](#29-schemas-zod-校验)
  - [30. types/ 公共类型](#30-types-公共类型)
  - [31. constants/ 常量库](#31-constants-常量库)
  - [32. migrations/ 配置升级迁移](#32-migrations-配置升级迁移)
  - [33. context.ts 根级会话上下文](#33-contextts-根级会话上下文)
  - [34. utils/ 工具函数库](#34-utils-工具函数库)
  - [35. moreright/ UI 增强（内部特性）](#35-moreright-ui-增强内部特性)
  - [36. native-ts/ 原生模块 TS 转译](#36-native-ts-原生模块-ts-转译)
  - [37. projectOnboardingState.ts 项目引导](#37-projectonboardingstatets-项目引导)
- [附录：对自研 Agent 内核的关键参考点（汇总）](#附录对自研-agent-内核的关键参考点汇总)

---

## 整体架构概览图

> 一张图看懂 Claude Code 2.1.88 的全貌。从下往上读：内核驱动 → 扩展能力 → 用户接口；从左往右读：本地能力 → 远程协作。

```
╔══════════════════════════════════════════════════════════════════════════════════════════════╗
║                                  用户 / IDE / 远程客户端                                      ║
╚═══════════════════════════════════════════════╤══════════════════════════════════════════════╝
                                                │
        ┌───────────────────────────────────────┼───────────────────────────────────────┐
        │                                       │                                       │
        ▼                                       ▼                                       ▼
┌────────────────┐              ┌────────────────────────────┐              ┌────────────────────┐
│ CLI 终端       │              │ IDE (VSCode/JetBrains)     │              │ Web / Mobile / CCR │
│ (Ink TUI)      │              │ via Bridge                 │              │ 远程会话            │
└───────┬────────┘              └────────┬───────────────────┘              └────────┬───────────┘
        │                                │                                           │
        │                                │ HTTP 轮询 pollWork/                       │ WebSocket
        │                                │ completeWork/permission                   │ + auth(oauth)
        │                                ▼                                           │
        │                       ┌────────────────────┐                               │
        │                       │  bridge/  server/  │◀──────────────────────────────┤
        │                       │  ・bridgeApi       │                               │
        │                       │  ・bridgeMain      │                               │
        │                       │  ・sessionRunner   │                               │
        │                       │  ・directConnect   │                               │
        │                       └────────┬───────────┘                               │
        │                                │                                           │
        ▼                                ▼                                           ▼
╔═══════════════════════════════════════════════════════════════════════════════════════════════╗
║                          ① Entrypoint 入口层  (entrypoints/)                                  ║
║  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐                  ║
║  │  cli.tsx     │  │  init.ts     │  │  mcp.ts      │  │  agentSdkTypes   │                  ║
║  │  (主入口)    │  │  (初始化)    │  │  (MCP Server)│  │  (SDK 协议类型)  │                  ║
║  └──────┬───────┘  └──────────────┘  └──────────────┘  └──────────────────┘                  ║
╚═════════╪═════════════════════════════════════════════════════════════════════════════════════╝
          │
          ▼
╔═══════════════════════════════════════════════════════════════════════════════════════════════╗
║                   ② Bootstrap 全局初始化  (bootstrap/state.ts ~ 1758 行)                      ║
║  ・读 .claude/config.json + settings.json     ・OAuth 令牌 / API key 加载                    ║
║  ・预连接 Anthropic API socket                ・初始化 OpenTelemetry Meter / Logger          ║
║  ・读 CLAUDE.md 缓存                          ・State 单一真实来源 (140+ 字段)               ║
║  ・migrations/ 11 个版本迁移自动跑            ・projectOnboardingState 引导状态机             ║
╚═════════╤═════════════════════════════════════════════════════════════════════════════════════╝
          │
          ▼
╔═══════════════════════════════════════════════════════════════════════════════════════════════╗
║              ③ UI 层  (ink/ + components/ + screens/ + buddy/ + voice/)                       ║
║                                                                                               ║
║  ┌────────────────────────────────────────────────────────────────────────────────────────┐  ║
║  │  screens/REPL.tsx  (5005 行 — 主交互循环)                                              │  ║
║  │  ┌─────────────────────┬─────────────────────┬───────────────────────┐                │  ║
║  │  │ VirtualMessageList  │   PromptInput       │  StatusLine + Dialog  │                │  ║
║  │  │ (5000+ 消息虚拟滚动)│   (输入框+附件)     │  (token/cost/idle)    │                │  ║
║  │  └─────────────────────┴─────────────────────┴───────────────────────┘                │  ║
║  └────────────────────────────────────────────────────────────────────────────────────────┘  ║
║                                                                                               ║
║  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌─────────────────┐  ┌────────────┐  ║
║  │ keybindings/ │  │ components/  │  │ outputStyles │  │  buddy/ 伴侣    │  │ voice/语音 │  ║
║  │ 17 ctx + 弦键│  │ 346 个 TSX   │  │              │  │  (装饰精灵)     │  │ push-talk  │  ║
║  │ 70+ actions  │  │ 12 子目录    │  │              │  │                 │  │            │  ║
║  └──────┬───────┘  └──────────────┘  └──────────────┘  └─────────────────┘  └────────────┘  ║
║         │                                                                                     ║
║  ┌──────▼─────────────────────────────────────────────────────────────────────────────────┐  ║
║  │  ink/ (35 文件) — 自研 TUI 引擎  ← 替代 npm Ink，深度定制                              │  ║
║  │  render-to-screen / DOM / events / focus / yoga-layout / wrap-ansi / hooks            │  ║
║  └────────────────────────────────────────────────────────────────────────────────────────┘  ║
╚═════════╤═════════════════════════════════════════════════════════════════════════════════════╝
          │  用户输入                              输出消息流  ▲
          │  (text + slash command + 快捷键)      (SDKMessage)│
          ▼                                                   │
╔═══════════════════════════════════════════════════════════════════════════════════════════════╗
║                                                                                               ║
║                    ④ 内核层  (Core Engine)  ★ 核心循环 ★                                     ║
║                                                                                               ║
║  ┌────────────────────────────────────────────────────────────────────────────────────────┐  ║
║  │  QueryEngine.ts  ──────────  会话生命周期 / SDK 入口 / 消息持久化                      │  ║
║  │       async *submitMessage(prompt) → AsyncGenerator<SDKMessage>                        │  ║
║  └──────────────────────────────────────┬─────────────────────────────────────────────────┘  ║
║                                         │                                                    ║
║                                         ▼                                                    ║
║  ┌────────────────────────────────────────────────────────────────────────────────────────┐  ║
║  │  query.ts ★ TAOR 主循环 ★  (1729 行)                                                   │  ║
║  │                                                                                        │  ║
║  │   ┌─────────────────────────────────────────────────────────────────────┐             │  ║
║  │   │       ┌──Think──┐    ┌──Act──┐     ┌──Observe──┐    ┌──Repeat──┐  │             │  ║
║  │   │   ──▶│ 权限检查 │──▶│ 工具执行│──▶│ 流式收集    │──▶│ 回灌 LLM  │──┐          │  ║
║  │   │       └─────────┘    └────────┘    └────────────┘    └───────────┘ │ │          │  ║
║  │   └────────────────────────────────────────────────────────────────────┘ │          │  ║
║  │                                                                          │          │  ║
║  │   ◀──── stop_reason: tool_use / end_turn / max_tokens ───────────────────┘          │  ║
║  │                                                                                      │  ║
║  │   ┌──────────────────────┐   ┌──────────────────────┐   ┌────────────────────────┐  │  ║
║  │   │ canUseTool 权限检查   │   │ runTools 调度        │   │ Compactor 5 层压缩      │  │  ║
║  │   │ (PreToolUse hook)    │   │ ・partition          │   │ ・文件读取去重          │  │  ║
║  │   │ • allow/deny/ask     │   │ ・concurrency-safe   │   │ ・工具结果摘要          │  │  ║
║  │   │ • permissionDenials  │   │ ・mutex on writes    │   │ ・旧轮次摘要            │  │  ║
║  │   └──────────────────────┘   └──────────┬───────────┘   │ ・系统消息收敛          │  │  ║
║  │                                         │                │ ・硬截断                │  │  ║
║  │                                         ▼                └────────────────────────┘  │  ║
║  │                              ┌────────────────────────┐                              │  ║
║  │                              │ StreamingToolExecutor   │                              │  ║
║  │                              │ ・边流边执行            │                              │  ║
║  │                              │ ・TrackedTool 状态机    │                              │  ║
║  │                              │ ・siblingAbortController│                              │  ║
║  │                              └────────────┬───────────┘                              │  ║
║  └───────────────────────────────────────────┼──────────────────────────────────────────┘  ║
║                                              │                                              ║
║                                              ▼                                              ║
║  ┌────────────────────────────────────────────────────────────────────────────────────────┐  ║
║  │  Tool.ts  ──────  工具接口四重契约（执行 / 渲染 / 权限 / 提示）                         │  ║
║  └──────────────────────────────────────┬─────────────────────────────────────────────────┘  ║
║                                         │                                                    ║
║                                         ▼                                                    ║
║  ┌────────────────────────────────────────────────────────────────────────────────────────┐  ║
║  │  tools/ ── 43+ 内置工具                                                                │  ║
║  │  ┌────────────┬──────────────┬──────────────┬────────────┬──────────────┬───────────┐  │  ║
║  │  │ 文件操作   │ 命令执行     │ 信息检索     │ Agent 协调 │ MCP          │ 任务/计划 │  │  ║
║  │  │ Read/Edit/ │ Bash/Power/  │ WebFetch/    │ Agent.spawn│ MCPTool/     │ Task*/    │  │  ║
║  │  │ Write/Glob/│ REPL         │ WebSearch/   │ /Team*/    │ ListResources│ TodoWrite/│  │  ║
║  │  │ Notebook   │              │ Grep/LSP     │ SendMessage│ /McpAuth     │ PlanMode  │  │  ║
║  │  └────────────┴──────────────┴──────────────┴────────────┴──────────────┴───────────┘  │  ║
║  └────────────────────────────────────────────────────────────────────────────────────────┘  ║
║                                                                                               ║
║  ┌──────────────────┐    ┌──────────────────────┐    ┌────────────────────────┐              ║
║  │ coordinator/     │    │ tasks/  后台任务      │    │ history.ts / costHook  │              ║
║  │ ・worker 模式    │    │ ・LocalShell/Agent    │    │ ・消息持久化            │              ║
║  │ ・工具子集约束   │    │ ・RemoteAgent         │    │ ・成本/token 追踪       │              ║
║  │ ・scratchpad 注入│    │ ・MonitorMcp/Workflow │    │                        │              ║
║  │ ・INTERNAL_TOOLS │    │ ・Watchdog 卡住检测   │    │                        │              ║
║  └──────────────────┘    │ ・id 前缀类型 (b/a/r)│    └────────────────────────┘              ║
║                           └──────────────────────┘                                            ║
╚═════════╤═════════════════════════════════════════════════════════════════════════════════════╝
          │
          ▼
╔═══════════════════════════════════════════════════════════════════════════════════════════════╗
║                         ⑤ 扩展层  (skills/ + plugins/ + hooks/ + commands/)                   ║
║                                                                                               ║
║  ┌─────────────────────────────────┐  ┌─────────────────────────────────┐                    ║
║  │ commands/  Slash 命令           │  │ skills/  技能系统                │                    ║
║  │ ・60+ 内置 + 67 子目录命令      │◀─│ ・Frontmatter (YAML 头块)        │                    ║
║  │ ・PromptCommand/LocalJSXCommand │  │ ・whenToUse 自主匹配             │                    ║
║  │ ・/help /compact /init /commit  │  │ ・realpath 去重                  │                    ║
║  │ ・getCommands(cwd)              │  │ ・paths glob 路径过滤            │                    ║
║  │   ・builtIn ・skill ・plugin    │  │ ・bundled + dir + plugin + MCP   │                    ║
║  │   ・mcp                         │  │ ・hooks 绑定                     │                    ║
║  └─────────────────────────────────┘  └────────────────┬────────────────┘                    ║
║                                                        │                                      ║
║  ┌─────────────────────────────────┐  ┌────────────────▼────────────────┐                    ║
║  │ plugins/  插件系统               │  │ hooks/  钩子系统                 │                    ║
║  │ ・组件容器                       │  │ ・10 个事件:                      │                    ║
║  │   skills + hooks + mcp + lsp    │  │   PreToolUse/PostToolUse/        │                    ║
║  │ ・builtin + marketplace         │  │   SessionStart/UserPromptSubmit/ │                    ║
║  │ ・defaultEnabled / isAvailable  │  │   PermissionDenied/FileChanged…  │                    ║
║  │ ・PluginInstallationManager     │  │ ・4 类型: command/prompt/http/   │                    ║
║  │   原子化 git clone 安装          │  │           agent                  │                    ║
║  │                                 │  │ ・if Permission 规则过滤          │                    ║
║  │                                 │  │ ・asyncRewake 事件驱动重评估     │                    ║
║  └─────────────────────────────────┘  └─────────────────────────────────┘                    ║
╚═════════╤═════════════════════════════════════════════════════════════════════════════════════╝
          │
          ▼
╔═══════════════════════════════════════════════════════════════════════════════════════════════╗
║                                ⑥ 服务层  (services/ + utils/)                                 ║
║                                                                                               ║
║  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────────┐  ║
║  │ services/api/    │  │ services/mcp/    │  │ services/oauth/  │  │ services/analytics/  │  ║
║  │ ・anthropic SDK  │  │ ・Transport抽象  │  │ ・OAuth flow     │  │ ・GrowthBook 特性开关│  ║
║  │ ・openai SDK     │  │   stdio/SSE/HTTP │  │ ・token 刷新     │  │ ・事件上报           │  ║
║  │ ・streaming      │  │   /WS/SDK        │  │ ・XAA Cross-App  │  │                      │  ║
║  │                  │  │ ・scope 6 层级   │  │                  │  │                      │  ║
║  └──────────────────┘  └──────────────────┘  └──────────────────┘  └──────────────────────┘  ║
║                                                                                               ║
║  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────────┐  ║
║  │ services/compact │  │ services/policy  │  │ services/Session │  │ services/extract     │  ║
║  │ 消息压缩         │  │ Limits 配额检查  │  │ Memory 动态内存  │  │ Memories 自动提取    │  ║
║  └──────────────────┘  └──────────────────┘  └──────────────────┘  └──────────────────────┘  ║
║                                                                                               ║
║  ┌─────────────────────────────────────────────────────────────────────────────────────────┐ ║
║  │  utils/  (31 子目录, 549 文件)  ── 应用层工具库                                         │ ║
║  │  git/ model/ auth/ permissions/ settings/ shell/ bash/ plugins/ hooks/ mcp/             │ ║
║  │  memory/ telemetry/ background/ todo/ task/ messages/ ...                               │ ║
║  └─────────────────────────────────────────────────────────────────────────────────────────┘ ║
╚═════════╤═════════════════════════════════════════════════════════════════════════════════════╝
          │
          ▼
╔═══════════════════════════════════════════════════════════════════════════════════════════════╗
║                       ⑦ 持久化与上下文层  (memdir/ + context.ts + state/)                     ║
║                                                                                               ║
║  ┌──────────────────────────────────┐  ┌──────────────────────────────────┐                  ║
║  │ memdir/  持久化记忆               │  │ context.ts  根级会话上下文        │                  ║
║  │ ・MEMORY.md 200 行 + 25KB 截断    │  │ ・getSystemContext (memoize)     │                  ║
║  │ ・individual / team / auto / index│  │ ・getUserContext                 │                  ║
║  │ ・~/.claude/memory ・.claude/mem  │  │ ・getGitStatus                   │                  ║
║  │ ・findRelevantMemories            │  │ ・注入系统提示                   │                  ║
║  └──────────────────────────────────┘  └──────────────────────────────────┘                  ║
║                                                                                               ║
║  ┌──────────────────────────────────┐  ┌──────────────────────────────────┐                  ║
║  │ state/  发布-订阅 Store           │  │ context/  React Context           │                  ║
║  │ ・AppState 单一容器               │  │ ・QueuedMessage / Modal /         │                  ║
║  │ ・onChangeAppState 副作用         │  │   PromptOverlay / Notifications/  │                  ║
║  │ ・useSyncExternalStore 订阅       │  │   Mailbox / Stats / FpsMetrics    │                  ║
║  └──────────────────────────────────┘  └──────────────────────────────────┘                  ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════╝

╔═══════════════════════════════════════════════════════════════════════════════════════════════╗
║                              ⑧ 远程通信层  (remote/ + cli/transports/)                        ║
║                                                                                               ║
║  ┌─────────────────────────────────┐  ┌─────────────────────────────────┐                    ║
║  │ remote/  WebSocket 远程会话      │  │ cli/transports/  Hybrid 传输    │                    ║
║  │ ・wss://api.anthropic.com/v1/    │  │ ・WebSocket (低延迟读)          │                    ║
║  │   sessions/ws/{sid}/subscribe   │  │ ・HTTP 批量上传 (可靠写)        │                    ║
║  │ ・分级 close code:               │  │ ・SSETransport                  │                    ║
║  │   4001 短重试 / 4003 永久放弃    │  │ ・SerialBatchEventUploader      │                    ║
║  │ ・30s ping 保活                  │  │                                 │                    ║
║  │ ・onPermissionRequest 异步回调   │  │                                 │                    ║
║  └─────────────────────────────────┘  └─────────────────────────────────┘                    ║
║                                                                                               ║
║  ┌─────────────────────────────────────────────────────────────────────────────────────────┐ ║
║  │ upstreamproxy/  企业 MITM 穿越                                                           │ ║
║  │ ・/run/ccr/session_token → prctl(PR_SET_DUMPABLE,0) → CA → CONNECT→WS 中继 → 删 token   │ ║
║  │ ・anthropic.com / github.com / npm / pypi / RFC1918 / IMDS  排除 MITM (NO_PROXY)        │ ║
║  └─────────────────────────────────────────────────────────────────────────────────────────┘ ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════╝

╔═══════════════════════════════════════════════════════════════════════════════════════════════╗
║                         ⑨ 基础设施层  (横切关注点 — 所有层都用)                                ║
║                                                                                               ║
║  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌──────────────────┐        ║
║  │ types/      │ │ schemas/    │ │ constants/  │ │ migrations/ │ │ native-ts/       │        ║
║  │ 公共类型     │ │ Zod 校验    │ │ 常量库       │ │ 11 配置迁移 │ │ 替代原生模块     │        ║
║  │ nominal Id  │ │ Hook/Perm   │ │ prompts.ts  │ │ Sonnet/Opus │ │ ・color-diff     │        ║
║  │ generated/  │ │ discrim     │ │ (54KB)      │ │ ・幂等       │ │ ・file-index     │        ║
║  │             │ │ Union       │ │             │ │ ・logEvent  │ │ ・yoga-layout    │        ║
║  └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └──────────────────┘        ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════╝


────────────────────────────────────────────────────────────────────────────────────────────────
                              横向数据流（一个完整轮次）
────────────────────────────────────────────────────────────────────────────────────────────────

用户输入                       LLM streaming                    工具执行                    持久化
   │                                │                                │                         │
   ▼                                ▼                                ▼                         ▼
┌──────┐  /command   ┌──────────┐  text/    ┌────────────┐  permit  ┌──────────┐  ToolResult ┌─────┐
│REPL  │────────────▶│Query     │──────────▶│ Streaming  │─────────▶│runTools  │────────────▶│ PG  │
│Input │             │Engine    │  delta /  │ToolExecutor│  check   │concurrent│             │ +   │
└──────┘             └──────────┘  tool_use └────────────┘          │/serial   │             │ FS  │
                          ▲                                          └──────────┘             └─────┘
                          │                                                │
                          │  回灌 history (TAOR Repeat)                    │
                          └────────────────────────────────────────────────┘

                         ▲                  ▲                ▲
                         │                  │                │
                    ┌────┴────┐        ┌────┴────┐      ┌────┴────┐
                    │ Skills  │        │ Hooks   │      │ Plugins │
                    │ frontmt │        │ Pre/Post│      │ container│
                    │ matcher │        │ if 规则 │      │          │
                    └─────────┘        └─────────┘      └──────────┘


────────────────────────────────────────────────────────────────────────────────────────────────
                                Sub-Agent 派发模式
────────────────────────────────────────────────────────────────────────────────────────────────

      Main QueryEngine                  Coordinator                  Sub QueryEngine
            │                                 │                              │
            │  Agent.spawn(prompt, type)      │                              │
            ├────────────────────────────────▶│                              │
            │                                 │  独立 history + 工具子集     │
            │                                 ├─────────────────────────────▶│
            │                                 │                              │ TAOR 子循环
            │                                 │                              │ (10k+ token)
            │                                 │                              │
            │                                 │◀─────────────────────────────┤ condensed (1-2k)
            │  注入主 history                 │                              │
            │◀────────────────────────────────┤                              │
            │                                 │                              │
            ▼                                 ▼                              ▼
      继续主 TAOR              ───────  Display Panel  ─────────       工件直推 (旁路)
                                        (artifact 持久化)
```

### 几个关键认知

1. **核心是一个文件**：`query.ts` (1729 行) 承载了 TAOR 主循环的全部逻辑——这是整个系统的心脏，其他都是周边
2. **所有扩展都收敛到 Tool**：Skills 经 SkillTool 包装；MCP 经 MCPTool 包装；Sub-agent 经 AgentTool 包装；命令本质是 prompt 模板。**Tool 是统一的扩展抽象**
3. **Hooks 是横切层**：在 4 个关键点（PreToolUse/PostToolUse/SessionStart/UserPromptSubmit）允许策略注入，**不需要改主循环代码**就能加权限/日志/审计
4. **流式是默认**：从 LLM streaming 到 Tool 流式执行（StreamingToolExecutor），整条链路都是 generator/AsyncIterator——设计上就为低延迟
5. **AppState 是唯一真实来源**：所有运行时状态（消息/任务/权限上下文/工件）都在 AppState；React Context 只是 view，不是 source of truth
6. **Memory 三层**：会话内（SessionMemory）→ 文件级（memdir）→ 自动提取（extractMemories），分别对应短/中/长记忆
7. **三种入口共享内核**：CLI / IDE Bridge / 远程 WebSocket 都走同一个 QueryEngine，差别只在传输层（cli/transports/）

### 我们 v0.1 架构的对应关系

| 我们 `00-architecture.md` 的 9 层 | Claude Code 对应模块 |
|---|---|
| L0 UI 层（三栏） | screens/REPL.tsx + components/ |
| L1 传输层（API + SSE） | bridge/ + remote/ + cli/transports/ |
| L2 QueryEngine 主循环 | **QueryEngine.ts + query.ts**（最直接对照） |
| L3 Tool Registry & Dispatcher | Tool.ts + tools/ + StreamingToolExecutor |
| L4 Skill Registry | skills/loadSkillsDir.ts |
| L5 Sub-Agent Coordinator | coordinator/ + tasks/LocalAgentTask |
| L6 Task Tracker | tasks/ + Task.ts |
| L7 Context / History | context.ts + memdir/ + services/compact |
| L8 权限 / 钩子 | hooks/ + ToolPermissionContext |
| L9 业务工具适配层 | tools/ + services/mcp/ |

**结论**：我们 v0.1 的 9 层结构与 Claude Code 几乎一一对应。最大差异是 **L9 业务工具适配层**——Claude Code 的 tools 直连本地 fs/shell，我们的 tools 直连 NestJS Service（业务规则单一来源）。这是 Web 多租户 vs 单用户本地的本质差异决定的。

---

## 一、内核与工具层

### 1. 主循环与引擎（根文件）

**职责**：驱动会话状态机，协调查询循环、消息流、权限控制与工具调度。

**关键文件**：
- `QueryEngine.ts` (1295 行) — 会话生命周期与 SDK 入口
- `query.ts` (1729 行) — 查询主循环与流式工具执行
- `Tool.ts` (792 行) — 工具接口规范与权限上下文
- `tools.ts` — 内置工具注册（条件编译 feature 网关）
- `context.ts` — 系统提示与 git 状态获取
- `commands.ts` — 斜杠命令与技能加载
- `Task.ts` / `tasks.ts` — 任务类型、状态模型与派发器
- `history.ts` — 会话历史管理
- `costHook.ts` / `cost-tracker.ts` — token/成本追踪
- `setup.ts` — 初始化流程
- `main.tsx` — CLI 入口

**核心数据结构**：

```typescript
// QueryEngine 配置与状态
type QueryEngineConfig = {
  cwd: string
  tools: Tools
  commands: Command[]
  mcpClients: MCPServerConnection[]
  agents: AgentDefinition[]
  canUseTool: CanUseToolFn
  getAppState: () => AppState
  setAppState: (f: (prev: AppState) => AppState) => void
  initialMessages?: Message[]
  readFileCache: FileStateCache
  customSystemPrompt?: string
  appendSystemPrompt?: string
  userSpecifiedModel?: string
  thinkingConfig?: ThinkingConfig
  maxTurns?: number
  maxBudgetUsd?: number
  taskBudget?: { total: number }
  jsonSchema?: Record<string, unknown>
}

class QueryEngine {
  private mutableMessages: Message[]
  private abortController: AbortController
  private permissionDenials: SDKPermissionDenial[]
  private totalUsage: NonNullableUsage
  private discoveredSkillNames = new Set<string>()

  async *submitMessage(
    prompt: string | ContentBlockParam[],
    options?: { uuid?: string; isMeta?: boolean },
  ): AsyncGenerator<SDKMessage, void, unknown>
}

// query.ts 循环状态
type State = {
  messages: Message[]
  toolUseContext: ToolUseContext
  autoCompactTracking: AutoCompactTrackingState | undefined
  maxOutputTokensRecoveryCount: number
  turnCount: number
  transition: Continue | undefined
}
```

**TAOR 主循环伪代码**：

```typescript
async function* queryLoop(params, consumedCommandUuids) {
  let state: State = { messages, toolUseContext, turnCount: 1, ... }
  const config = buildQueryConfig()  // 截快 feature/statsig 网关

  while (true) {
    yield { type: 'stream_request_start' }

    // A) 调用 API streaming
    for await (const message of deps.callModel({
      model: config.mainLoopModel,
      messages: normalizeMessagesForAPI(state.messages),
      system_prompt: systemPrompt,
      max_thinking_length: thinkingConfig.maxThinkingLength,
      stream: true,
      stop_sequences: [...],
      timeout_seconds: 300,
    })) {
      // 流式：text / content_block_start/delta/stop / message_delta(stop_reason) / message_stop
      if (message.type === 'content_block_start' && block.type === 'tool_use') {
        // 工具开始：记录 toolUseId
      }
      if (isAssistantMessage(message)) {
        yield message
      }
    }

    // B) 检查 stop_reason
    // - tool_use   → 执行工具
    // - end_turn   → 检查停止钩子
    // - max_tokens → 触发恢复（reactive_compact / auto_compact）

    if (assistantMessage.stop_reason === 'tool_use' && hasToolUses) {
      // O) OBSERVE: 提取 tool_use blocks
      const toolUseBlocks = assistantMessage.content
        .filter(c => c.type === 'tool_use') as ToolUseBlock[]

      // T) THINK: 权限检查（canUseTool hook）
      for (const block of toolUseBlocks) {
        const tool = findToolByName(tools, block.name)
        const permitted = await canUseTool(tool, block.input, ctx, assistantMessage, block.id)
        if (!permitted) permissionDenials.push({ tool_name, tool_use_id, ... })
      }

      // A) ACT: 执行工具（并发+互斥调度）
      if (config.gates.streamingToolExecution) {
        streamingToolExecutor = new StreamingToolExecutor(toolDefinitions, canUseTool, ctx)
        for await (const block of incomingToolUseBlocks) {
          streamingToolExecutor.addTool(block, assistantMessage)
        }
      } else {
        const updates = runTools(toolUseBlocks, [assistantMessage], canUseTool, ctx)
        for await (const { message, newContext } of updates) {
          yield message
          toolUseContext = newContext
        }
      }

      // R) REPEAT
      state.messages.push(...toolResultMessages)
      state.turnCount += 1
      continue
    }

    // 轮次结束（end_turn）
    if (executePostSamplingHooks(...)) continue
    break  // return { terminal: 'completed' }
  }
}
```

**工具调度并发控制**（toolOrchestration.ts）：

```typescript
async function* runTools(toolUseMessages, canUseTool, ctx) {
  let currentContext = ctx
  for (const batch of partitionToolCalls(toolUseMessages, currentContext)) {
    if (batch.isConcurrencySafe) {
      // 并发执行（读操作、无副作用）
      for await (const update of runToolsConcurrently(batch.blocks, ...)) {
        yield { message: update.message, newContext: currentContext }
      }
    } else {
      // 互斥执行（写操作）
      for await (const update of runToolsSerially(batch.blocks, ...)) {
        currentContext = update.newContext || currentContext
        yield { message: update.message, newContext: currentContext }
      }
    }
  }
}
```

**流式工具执行**（StreamingToolExecutor）：

```typescript
class StreamingToolExecutor {
  private tools: TrackedTool[] = []
  private siblingAbortController: AbortController

  addTool(block: ToolUseBlock, assistantMessage: AssistantMessage): void {
    const isConcurrencySafe = tool.isConcurrencySafe(block.input)
    const tracked: TrackedTool = {
      id: block.id,
      block,
      status: 'queued' | 'executing' | 'completed' | 'yielded',
      isConcurrencySafe,
      pendingProgress: [],
    }
    this.tools.push(tracked)
    // 条件允许立即启动，非并发工具等独占机会
  }

  async *getRemainingResults(): AsyncGenerator<Message> {
    // 按接收顺序 yield 完成的结果
    // Bash 错误 → siblingAbortController → 同级子进程死亡
  }
}
```

**可借鉴点**：
1. **TAOR 显式分离**：Think（权限）→ Act（执行）→ Observe（流）→ Repeat（推送），每个阶段独立便于插 hook
2. **流式+并发**：StreamingToolExecutor 管理 TrackedTool 队列，边流边执行，端到端延迟显著降低
3. **`isConcurrencySafe` 与 `isReadOnly` 解耦**：读操作可并行、写操作互斥；partitionToolCalls 提前判断
4. **生成器驱动架构**：`query()` 返回 `AsyncGenerator<SDKMessage>`，把 API 流式、工具并发、权限检查、紧凑等编织成统一状态机
5. **post_sampling 钩子**：在 assistant 消息到达后立即执行，支持继续/停止决策

---

### 2. Tool.ts 工具接口规范

```typescript
export type Tool<Input, Output, P> = {
  name: string
  aliases?: string[]
  searchHint?: string                          // ToolSearch 关键字（3-10 字）

  inputSchema: Input                           // Zod schema
  inputJSONSchema?: ToolInputJSONSchema        // MCP 原生 JSON Schema

  call(
    args: z.infer<Input>,
    context: ToolUseContext,
    canUseTool: CanUseToolFn,
    parentMessage: AssistantMessage,
    onProgress?: ToolCallProgress<P>,
  ): Promise<ToolResult<Output>>

  description(input, options): Promise<string>

  // 权限与并发
  isConcurrencySafe(input): boolean
  isReadOnly(input): boolean
  checkPermissions(input, ctx, canUseTool, msg, toolUseId, forceDecision?): Promise<PermissionResult>

  // UI 渲染
  renderToolUseMessage(input: Partial<z.infer<Input>>): React.ReactNode
  renderToolResultMessage?(result, input): React.ReactNode
  renderToolUseTag?(input): React.ReactNode
  renderToolUseProgressMessage?(progress: P): React.ReactNode
  renderToolUseQueuedMessage?(): React.ReactNode

  // 结果文本（紧凑/摘要用）
  getToolResultText?(result, input): string

  hideInToolSearch?: boolean
}

type ToolUseContext = {
  options: {
    tools: Tools
    commands: Command[]
    mainLoopModel: string
    thinkingConfig: ThinkingConfig
    mcpClients: MCPServerConnection[]
    maxBudgetUsd?: number
    customSystemPrompt?: string
    agentDefinitions: AgentDefinitionsResult
  }
  abortController: AbortController
  readFileState: FileStateCache
  getAppState(): AppState
  setAppState(f): void
  setAppStateForTasks?: (f) => void
  handleElicitation?: (serverName, params, signal) => Promise<ElicitResult>
  messages: Message[]
  contentReplacementState?: ContentReplacementState  // 工具结果预算
  renderedSystemPrompt?: SystemPrompt                // 缓存命中共享
}
```

**Tool 接口的四重契约**：
- **执行契约**：`call(input, context, canUseTool, parentMessage, onProgress)`
- **渲染契约**：`renderToolUseMessage`, `renderToolResultMessage`, `getToolResultText`
- **权限契约**：`isConcurrencySafe`, `isReadOnly`, `checkPermissions`
- **提示契约**：`inputSchema`, `description`, `searchHint`

单一 Tool 类型同时履行四个角色，避免横向扩散接口。

---

### 3. tools/ 43+ 内置工具

| 分类 | 工具 | 说明 |
|---|---|---|
| 文件操作 | FileReadTool / FileEditTool / FileWriteTool / GlobTool / NotebookEditTool | 读/编辑/写/glob/Jupyter |
| 命令执行 | BashTool / PowerShellTool / REPLTool | 默认并发安全，Bash 错误触发同级取消 |
| 信息检索 | WebFetchTool / WebSearchTool / GrepTool / ToolSearchTool / LSPTool / BriefTool | HTTP / 搜索 / 正则 / 工具发现 / LSP / 快速总结 |
| Agent 协调 | AgentTool / TeamCreateTool / TeamDeleteTool / SendMessageTool | 子代理派生、团队、Agent 间通信 |
| MCP | MCPTool / ListMcpResourcesTool / ReadMcpResourceTool / McpAuthTool | 动态生成、资源枚举/读取、认证 |
| 任务监控 | TaskStopTool / TaskOutputTool / MonitorTool / SleepTool | 杀任务、查输出、长进程监控、延迟 |
| 计划工作流 | EnterPlanModeTool / ExitPlanModeTool / TodoWriteTool / TaskCreateTool / TaskUpdateTool / TaskListTool | 计划模式、TODO、任务 CRUD |
| 其他 | SkillTool / ConfigTool / EnterWorktreeTool / ExitWorktreeTool / AskUserQuestionTool / TungstenTool | 技能调用、配置、worktree、用户交互、调试 |

---

### 4. query/ 查询配置与钩子

- `config.ts` — `QueryConfig` 快照（feature 网关、statsig 节流）
- `deps.ts` — 生产依赖注入（API 调用、工具编排）
- `stopHooks.ts` — post_sampling 钩子执行
- `tokenBudget.ts` — Token 预算追踪

```typescript
type QueryConfig = {
  sessionId: SessionId
  gates: {
    streamingToolExecution: boolean
    emitToolUseSummaries: boolean
    isAnt: boolean
    fastModeEnabled: boolean
  }
}
```

---

### 5. coordinator/ 多 agent 协调

Coordinator 模式下的 worker 代理约束与上下文注入。

```typescript
function isCoordinatorMode(): boolean {
  return feature('COORDINATOR_MODE')
      && isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)
}

function getCoordinatorUserContext(
  mcpClients: ReadonlyArray<{ name: string }>,
  scratchpadDir?: string,
): { [k: string]: string } {
  // 注入 worker 可用工具列表、MCP 服务名、scratchpad 路径等
  // 约束子代理权限
}

const INTERNAL_WORKER_TOOLS = [
  TEAM_CREATE_TOOL_NAME,
  TEAM_DELETE_TOOL_NAME,
  SEND_MESSAGE_TOOL_NAME,
  SYNTHETIC_OUTPUT_TOOL_NAME,
]
```

**可借鉴**：feature gate 编译时死代码消除；纯函数注入无状态修改；INTERNAL_WORKER_TOOLS 黑名单约束 worker 权限。

---

### 6. tasks/ 后台任务框架

**任务类型**：

```typescript
type TaskType =
  | 'local_bash'        // b
  | 'local_agent'       // a
  | 'remote_agent'      // r
  | 'in_process_teammate' // t
  | 'local_workflow'    // w
  | 'monitor_mcp'       // m
  | 'dream'             // d

type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'killed'

type TaskStateBase = {
  id: string  // prefix(1) + base36(randomBytes(8))
  type: TaskType
  status: TaskStatus
  description: string
  toolUseId?: string
  startTime: number
  endTime?: number
  totalPausedMs?: number
  outputFile: string    // 输出落盘
  outputOffset: number
  notified: boolean
}
```

**任务实现**（tasks/ 子目录）：
- `LocalShellTask` — Bash（监控输出、卡住检测、自杀通知）
- `LocalAgentTask` — 进程内子代理
- `RemoteAgentTask` — 远程 worker 池
- `DreamTask` — 后台推测（KAIROS）
- `InProcessTeammateTask` — 进程内 teammate（共享内存）
- `LocalWorkflowTask` — 脚本工作流（WORKFLOW_SCRIPTS）
- `MonitorMcpTask` — MCP 长监控

**卡住检测**（LocalShellTask）：

```typescript
// 45s 无输出 + tail 匹配交互提示 → 通知用户
function looksLikePrompt(tail: string): boolean {
  return PROMPT_PATTERNS.some(p => p.test(lastLine))  // (y/n), Press Enter, ...
}
function startStallWatchdog(taskId, description, kind, toolUseId?): () => void {
  // 周期轮询：检查输出增长 + 提示模式 → 发送任务通知
}
```

**可借鉴**：
- 任务状态存 AppState，outputFile 解耦内存
- Task ID 类型前缀识别（symlink 攻击防御）
- isTerminalTaskStatus 防止向死任务注入消息
- Watchdog 主动检测交互卡顿，把"agent 等输入"显化给用户

---

## 二、UI 与命令层

### 7. commands/ Slash 命令系统

**职责**：中央命令注册与分发；通过 feature gate 控制可见性；支持插件命令、技能命令、本地自定义命令的动态加载。

**规模**：内置 60+ 命令（部分 feature 门禁）+ 67 个目录命令 + 12 个根文件命令 + 插件命令 + 技能命令 + MCP 命令。

**命令类型**：

```typescript
type Command =
  | PromptCommand                  // 发送给 Claude 的指令
  | LocalJSXCommand                // 本地 JSX 渲染（不调 API）
  | LocalCommandResultDisplay      // 已获得结果，只显示
  | InteractiveCommand             // 交互式对话（权限确认等）
```

**收集流程**：

```typescript
getCommands(cwd)
  → builtInCommandNames                  // 内置清单
  → getSkillToolCommands                 // Anthropic SDK tools → 命令
  → getPluginCommands                    // ~/.claude/plugins/*/commands
  → getSkillDirCommands                  // ~/.claude/skills/*/
  → getMcpSkillCommands                  // MCP 暴露的 skill
```

**关键文件**：`commands.ts`、`config/index.ts`、`commit.ts`、`review.ts`、`compact/index.ts`、`context/index.ts`、`skills/index.ts`、`agents/index.ts`、`mcp/index.ts`、`help/index.ts`、`init.ts`、`brief.ts`、`assistant/index.ts`、`voice/index.ts`、`buddy/index.ts`

**完整命令清单（67 个目录）**：
add-dir, agents, ant-trace, autofix-pr, backfill-sessions, branch, break-cache, bridge, btw, bughunter, chrome, clear, color, compact, config, context, copy, cost, ctx_viz, debug-tool-call, desktop, diff, doctor, feedback, files, fork, good-claude, help, hooks, ide, init, init-verifiers, install-github-app, install-slack-app, issue, keybindings, login, logout, memory, mcp, mobile, model, on-boarding, output-style, perf-issue, permissions, plugin, plan, pr_comments, release-notes, remote-setup, rename, resume, review, sandbox-toggle, security-review, session, share, skills, statusline, stickers, summary, tag, tasks, teleport, terminalSetup, theme, thinkback, thinkback-play, usage, version, vim, workflows, remote-env, upgrade, extra-usage, rate-limit-options, fast, passes, privacy-settings, env, exit, export, oauth-refresh, reset-limits, stats, effort

**内部命令**（不暴露外部）：backfillSessions, breakCache, bughunter, commit, ctx_viz, goodClaude, issue, mockLimits, bridgeKick, version, resetLimits, teleport, antTrace, perfIssue, env

---

### 8. keybindings/ 快捷键系统

**职责**：多层快捷键引擎；默认绑定 + 用户 `~/.claude/keybindings.json` 覆盖；弦键支持（chord sequences）；上下文分离；热重载。

**关键文件**：
- `defaultBindings.ts` — 60+ 内置快捷键，平台特定（Windows VT 模式检测）
- `schema.ts` — Zod 验证、17 个 contexts、70+ actions
- `KeybindingProviderSetup.tsx` — React Provider、弦键超时 1000ms、热重载 watcher
- `resolver.ts` — 键位 → action 映射、弦键状态机（chord_started / chord_cancelled）
- `match.ts` — Ink Key → ParsedKeystroke 匹配
- `parser.ts` — 解析 `"ctrl+k ctrl+s"` → `Chord[]`
- `loadUserBindings.ts` — 文件 watcher、JSON 解析、验证报告
- `validate.ts` — 错误/警告收集、保留快捷键检查（ctrl+c/d 不可重绑）

**17 个 contexts**：Global、Chat、Autocomplete、Confirmation、Help、Transcript、HistorySearch、Task、ThemePicker、Settings、Tabs、Attachments、Footer、MessageSelector、DiffDialog、ModelPicker、Select、Plugin

**70+ Actions 分类**：
- `app:*` — interrupt / exit / toggleTodos / redraw / globalSearch / quickOpen
- `chat:*` — submit / cancel / cycleMode / modelPicker / fastMode / thinkingToggle / undo
- `history:*` — search / previous / next
- `autocomplete:*`, `confirm:*`, `tabs:*`, `transcript:*`, `task:*`, `voice:*`

**弦键状态机**：

```typescript
const CHORD_TIMEOUT_MS = 1000

resolveKeyWithChordState(input, key)
  → { type: 'none' }
  → { type: 'chord_started', pending: [...] }  // 启动 1s 超时
  → { type: 'match', action: 'xxx' }
  → { type: 'chord_cancelled' }
```

**默认快捷键示例**：

| 快捷键 | 上下文 | Action |
|---|---|---|
| ctrl+c | Global | app:interrupt（双按退出） |
| ctrl+d | Global | app:exit（双按确认） |
| ctrl+t | Global | app:toggleTodos |
| ctrl+r | Global | history:search |
| shift+tab | Chat | chat:cycleMode（Windows 用 meta+m） |
| enter | Chat | chat:submit |
| ctrl+\_ | Chat | chat:undo |
| ctrl+x ctrl+k | Chat | chat:killAgents（弦键） |

---

### 9. components/ TUI 组件库

346 个 TSX 文件，按子目录分组：

| 目录 | 组件数 | 职责 |
|---|---|---|
| design-system/ | ~15 | ThemedBox/Text、color palette、主题 provider |
| messages/ | ~8 | 消息行、diff 渲染、工具使用反馈 |
| Settings/ | ~12 | 配置 UI、字段表单、验证 |
| PromptInput/ | ~6 | 聊天输入框、文件附件、图片粘贴 |
| tasks/ | ~8 | 任务列表、代理进度、后台任务指示器 |
| permissions/ | ~8 | 权限弹窗、MCP 服务器审批 |
| agents/ | ~10 | agent 状态、快照对话、团队成员预览 |
| diff/ | ~6 | 结构化 diff 渲染、文件编辑预览 |
| mcp/ | ~6 | MCP 服务器对话框、多选、导入 |
| HelpV2/、wizard/ | ~10 | 帮助菜单、向导流程 |
| Spinner/、LogoV2/ | ~4 | 加载动画、品牌图标 |

---

### 10. screens/ 大屏模式

3 个 TSX 文件：

- **`REPL.tsx`** (5005 行) — 主交互循环：消息列表、输入框、快捷键、工具 use、权限对话、成本追踪、空闲返回、打字动画
- `ResumeConversation.tsx` — 会话恢复选择器
- `Doctor.tsx` — 诊断工具（配置验证、性能分析、日志导出）

**REPL 核心流**：

```
REPL({ client, initialState, stats, getFpsMetrics, resumeEntrypoint, commandLine })
  ↓
  VirtualMessageList (5000+ 消息虚拟滚动)
    + PromptInput
    + StatusLine (token 预算 / 模式指示器)
    + CostThresholdDialog
    + IdleReturnDialog (空闲 20min 返回)
    + 权限弹窗、确认框
  ↓
  useInput hook (shift+tab → cycleMode / enter → submit / ctrl+x ctrl+k → kill)
  ↓
  工具 use 确认 (Bash / npm / 编辑器)
  ↓
  流式响应 → append → re-render
```

---

### 11. ink/ TUI 渲染引擎

35 个核心文件，自定义 Ink 实现：

| 模块 | 文件 | 职责 |
|---|---|---|
| 核心渲染 | render-to-screen.ts、root.ts、renderer.ts | React → 终端输出、unmount 回收、增量更新 |
| 事件 | events/ | input-event、click-event、terminal-focus-event |
| DOM | dom.ts、instances.ts | 虚拟 DOM 节点、组件实例缓存 |
| 布局 | layout/ | 文本宽度、换行、tabstop |
| 焦点 | focus.ts | FocusManager、focus trap、keyboard 导航 |
| 优化 | optimizer.ts、line-width-cache.ts | 渲染优化、缓存策略 |
| Hook | hooks/use-*.ts | useInput、useStdin、useTerminalFocus、useTabStatus |
| 工具 | stringWidth.ts、wrapAnsi.ts、colorize.ts | 字符宽度、ANSI 处理 |

**核心 Hook**：`useInput(handler, options)`, `useStdin()`, `useTerminalFocus()`, `useTabStatus()`, `useTerminalNotification()`, `useSelection()`

---

### 12. buddy/ AI 伴侣

5 个文件，装饰性 AI 精灵：用户 ID 哈希生成持久精灵（物种、眼睛、帽子、属性），消息流中显示，支持触发提示与互动反馈。

```typescript
const companion = getCompanion(userId)
  → { species: 'duck'|'cat'|..., eyes: 'o_o'|..., stats: { 智力/魅力/运气/耐力 } }

findBuddyTriggerPositions(text)  // 用户消息中的关键词 → 显示气泡

<CompanionSprite companion={c} theme={theme}>
  {/* IDLE_SEQUENCE: 0,0,0,0,1,0,0,0,-1,0,0,2,0... (眨眼帧) */}
  {/* PET_HEARTS: 心形浮动 5 ticks (~2.5s) */}
</CompanionSprite>

feature('BUDDY') ? buddy : null
```

---

### 13. voice/ 语音交互

2 个文件，推送发话（push-to-talk）：

```typescript
isVoiceModeEnabled()  // 完整检查
  = hasVoiceAuth() && isVoiceGrowthBookEnabled()

hasVoiceAuth()  // React render 路径
  = isAnthropicAuthEnabled() && Boolean(tokens?.accessToken)

isVoiceGrowthBookEnabled()  // GrowthBook kill switch
  = !getFeatureValue('tengu_amber_quartz_disabled', false)

loadAudioNapi()  // 首次按键时延迟加载（1-8s 冷启）
```

音频采集：macOS CoreAudio / Linux ALSA-SoX / Windows WaveIn；16kHz 单声道；silence detection（2s + 3% 阈值）。

---

### 14. 根文件：dialogLaunchers / interactiveHelpers / replLauncher / ink.ts

- **`dialogLaunchers.tsx`** — 动态导入并启动一次性对话 UI（snapshot 合并、配置错误、Bridge 会话选择、安装向导）
- **`interactiveHelpers.tsx`** — `showDialog<T>`, `showSetupDialog<T>`, `exitWithError`, `exitWithMessage`, `renderAndRun`, `completeOnboarding`
- **`replLauncher.tsx`** — 启动 REPL：`App(FpsMetrics + Stats + AppState) → REPL(messages, input, hotkeys)`
- **`ink.ts`** — Ink 公共 API：`render(node, options)`、`createRoot(options)`、导出 `Box/Text/Button/Link/Spacer` 与 Hooks

---

## 三、扩展性与集成层

### 15. skills/ 技能系统

**核心文件**：
- `loadSkillsDir.ts` (34KB) — 加载器：遍历 skills/，解析 Frontmatter，去重，钩子验证，路径匹配
- `bundledSkills.ts` (7KB) — 编译到 CLI 二进制的内置技能
- `mcpSkillBuilders.ts` (1.6KB) — MCP 工具 → Skill Command 适配
- `bundled/` — 预置技能源码（如 setup-project）

**Command 对象**：

```typescript
type PromptCommand = {
  type: 'prompt'
  name: string
  description: string
  whenToUse?: string                   // 何时调用提示词（参与 LLM 自主匹配）
  contentLength: number                // token 估算
  argumentHint?: string
  argumentNames: string[]
  allowedTools?: string[]
  source: 'skills' | 'bundled' | 'mcp' | 'plugin'
  loadedFrom: 'skills' | 'bundled' | 'managed' | 'plugin' | 'mcp'
  paths?: string[]                     // 仅在触及匹配文件时可见
  hooks?: HooksSettings                // 技能级钩子
  context?: 'inline' | 'fork'          // 执行上下文
  agent?: string                       // fork 时的 agent 类型
  effort?: EffortValue                 // 工作量提示
  getPromptForCommand(args, ctx): Promise<ContentBlockParam[]>
}
```

**Frontmatter 解析字段**：

```typescript
{
  displayName?: string
  description: string
  hasUserSpecifiedDescription: boolean
  whenToUse?: string
  allowedTools: string[]
  argumentNames: string[]
  model?: 'claude-opus' | 'inherit' | undefined
  disableModelInvocation: boolean
  userInvocable: boolean
  hooks?: HooksSettings
  executionContext: 'fork' | undefined
  agent?: string
  effort?: EffortValue
  shell?: { type: 'bash' | 'powershell', ... }
}
```

**加载流程**：
1. 启动时 `loadSkillsDir()` 遍历 `~/.claude/skills/`、`.claude/skills/`、托管路径
2. Frontmatter 解析（YAML 头块）
3. `getFileIdentity()` → `realpath()` 跟踪 symlink 去重
4. `parseHooksFromFrontmatter()` 验证 HooksSchema
5. Token 估算仅针对 Frontmatter 字段，content 延后
6. MCP 集成：`registerMCPSkillBuilders()` 将 MCP 工具列表转换为 PromptCommand

**可借鉴**：
- **渐进式元数据加载**：调用时再加载完整内容，启动期只看 Frontmatter
- **声明式 Frontmatter**：YAML 头块标准化，IDE 工具链可集成
- **路径匹配过滤**：ignore 库实现 glob，技能按 cwd 动态可见
- **realpath 去重**：处理 symlink 而非 inode（虚拟文件系统兼容）

---

### 16. plugins/ 插件系统

**关键文件**：
- `builtinPlugins.ts` (4.9KB) — 内置插件注册表
- `bundled/` — 内置插件实现
- `services/plugins/pluginOperations.ts` (35KB) — Git clone / 安装 / 更新 / 清理
- `services/plugins/PluginInstallationManager.ts` (6KB) — 并发下载、缓存、原子替换
- `services/plugins/pluginCliCommands.ts` (10KB) — `/plugin install/list/remove`

**数据结构**：

```typescript
type BuiltinPluginDefinition = {
  name: string
  description: string
  version?: string
  skills?: BundledSkillDefinition[]
  hooks?: HooksSettings
  mcpServers?: Record<string, McpServerConfig>
  lspServers?: Record<string, LspServerConfig>
  isAvailable?: () => boolean
  defaultEnabled?: boolean
}

type LoadedPlugin = {
  name: string
  manifest: PluginManifest
  path: string
  source: string                       // 'name@builtin' | 'name@marketplace'
  repository: string
  enabled?: boolean
  isBuiltin?: boolean
  skillsPaths?: string[]
  commandsPaths?: string[]
  hooksConfig?: HooksSettings
  mcpServers?: Record<string, McpServerConfig>
  lspServers?: Record<string, LspServerConfig>
  settings?: Record<string, unknown>
}
```

**启用策略**：用户设置 > `defaultEnabled` > 默认 true。

**可借鉴**：
- **分层启用管理**：内置可 toggle，marketplace 完全独立版本
- **组件容器**：单个插件聚合 skills/hooks/mcp/lsp
- **可用性守卫**：`isAvailable()` 预约系统特性开关

---

### 17. hooks/ 钩子系统

**事件类型**：

```typescript
type HookEvent =
  | 'PreToolUse'              // 工具调用前：可修改输入、阻止执行
  | 'PostToolUse'             // 工具调用后
  | 'PostToolUseFailure'      // 工具执行失败
  | 'SessionStart'            // 会话开始：初始化观察路径
  | 'UserPromptSubmit'        // 用户消息提交前
  | 'Setup'                   // CLI 首次配置
  | 'SubagentStart'           // Fork 会话启动
  | 'PermissionDenied'        // 权限被拒后
  | 'FileChanged'             // 文件变化（SessionStart watchPaths）
  | 'Notification'            // 通知
```

**钩子命令**（4 种类型）：

```typescript
type HookCommand =
  | {
      type: 'command'
      command: string
      if?: string                    // Permission 规则：'Bash(git *)', 'Read(*.ts)'
      shell?: 'bash' | 'powershell'
      timeout?: number
      statusMessage?: string
      once?: boolean
      async?: boolean                // 后台运行
      asyncRewake?: boolean          // exit code=2 时唤醒模型
    }
  | { type: 'prompt'; prompt: string; if?: string; model?: string; timeout?: number; ... }
  | { type: 'http'; url: string; if?: string; timeout?: number; ... }
  | { type: 'agent'; workload: string; model?: string; timeout?: number }
```

**Sync Hook 响应**：

```typescript
type SyncHookResponse = {
  continue?: boolean             // false 时停止执行
  suppressOutput?: boolean
  stopReason?: string
  decision?: 'approve' | 'block'
  hookSpecificOutput?: {
    PreToolUse: {
      permissionDecision?: 'allow' | 'deny'
      updatedInput?: Record<string, unknown>
      additionalContext?: string
    }
    PostToolUse: {
      updatedMCPToolOutput?: unknown
      additionalContext?: string
    }
    SessionStart: {
      watchPaths?: string[]      // 注册 FileChanged 观察
      initialUserMessage?: string
    }
    // ...其他 event
  }
}
```

**关键流程**：
1. 注册来源合并：skill Frontmatter + 插件 manifest + 全局 settings
2. `if` 条件匹配：Permission 规则语法过滤
3. 串联执行：同 event 多条钩子按注册序，`continue=false` 早退
4. 权限决策：PreToolUse 钩子返回 `permissionDecision` 可短路权限提示
5. 模型调用：`type='prompt'` 使用小模型评估
6. 异步：`async=true` 不阻塞；`asyncRewake=true` 在 exit code=2 时唤醒模型

**可借鉴**：
- 事件覆盖完整（Pre/Post/Failure/Setup/Permission 闭环）
- Permission 规则复用作为 hook gate
- 4 种实现方式（Command/Prompt/HTTP/Agent）灵活
- asyncRewake 支持事件驱动重新评估
- SessionStart 返回 watchPaths 注册 FileChanged，形成动态观察

---

### 18. assistant/ 会话历史

仅 `sessionHistory.ts` (88 行)：CCR 远程会话历史分页。

```typescript
type HistoryPage = {
  events: SDKMessage[]
  firstId: string | null
  hasMore: boolean
}

type HistoryAuthCtx = {
  baseUrl: string
  headers: Record<string, string>  // OAuth + org UUID + beta header
}

fetchLatestEvents(limit, anchor_to_latest=true)  // 最后 N 条
fetchOlderEvents(beforeId)                       // cursor 翻页
```

**可借鉴**：anchor_to_latest 实现流式追溯；失败返回 null 不 throw。

---

### 19. remote/ WebSocket 远程会话

**关键文件**：
- `RemoteSessionManager.ts` — 权限请求回调、消息分发、断连恢复
- `SessionsWebSocket.ts` — 连接/重连、ping 保活、close code 处理
- `sdkMessageAdapter.ts` — SDK 消息与控制协议适配
- `remotePermissionBridge.ts` — 权限响应代理

```typescript
type RemoteSessionConfig = {
  sessionId: string
  getAccessToken: () => string
  orgUuid: string
  hasInitialPrompt?: boolean
  viewerOnly?: boolean
}

type RemoteSessionCallbacks = {
  onMessage: (message: SDKMessage) => void
  onPermissionRequest: (request: SDKControlPermissionRequest, requestId: string) => void
  onPermissionCancelled?: (requestId: string, toolUseId?: string) => void
  onConnected?: () => void
  onDisconnected?: () => void
}

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

**关键流程**：
1. 连接 `wss://api.anthropic.com/v1/sessions/ws/{sessionId}/subscribe?organization_uuid=...`
2. 发 `{ type: 'auth', credential: { type: 'oauth', token: '...' } }`
3. 接收 SDKMessage 流
4. **重连**：断连 2s 重试，最多 5 次（MAX_RECONNECT_ATTEMPTS）
   - 4001（会话未找到）独立处理，最多 3 次（可能 compaction 中）
   - 4003（未授权）立即放弃
5. **保活**：30s ping
6. **权限**：control_request → `onPermissionRequest` → 客户端返回 RemotePermissionResponse

**可借鉴**：分级 close code 处理；通用 session protocol（auth → message stream）；权限请求异步化支持客户端本地决策。

---

### 20. server/ 与 bridge/ IDE 桥接

**关键文件**：
- `bridge/bridgeApi.ts` (18KB) — Bridge API：工作轮询、权限响应、错误重试
- `bridge/replBridge.ts` (100KB) — REPL 网桥：会话创建、消息路由、交互管理
- `bridge/bridgeMain.ts` (115KB) — 主循环：工作分发、工具执行、状态管理
- `bridge/remoteBridgeCore.ts` (39KB) — 远程会话核心：权限流、权限缓存
- `bridge/sessionRunner.ts` (18KB) — 会话执行器
- `bridge/types.ts` (10KB) — 协议类型
- `server/directConnectManager.ts` (5.9KB) — IDE SSE 直连会话

```typescript
type BridgeApiClient = {
  pollWork(sessionId, sequenceId): Promise<WorkResponse>
  completeWork(sessionId, workId, result): Promise<void>
  respondToPermission(sessionId, response): Promise<void>
}

type WorkResponse = {
  work_id?: string
  sequence_id: number
  command_type: 'run_tool' | 'get_status' | 'get_info'
  tool_name?: string
  tool_use_id?: string
  tool_input?: Record<string, unknown>
}

type PermissionResponseEvent = {
  permission_request_id: string
  decision: 'approve' | 'deny'
  reasoning?: string
}
```

**可借鉴**：轮询模式（避免 WebSocket 常连，权限隔离友好）；permission request 可在 IDE 一端本地 policy 决策；work_id 自包含上下文支持失连重试。

---

### 21. services/ 服务层

| 子目录 | 核心文件 | 作用 |
|---|---|---|
| analytics/ | index.ts、growthbook.ts | 事件上报、特性开关 |
| api/ | openai.ts、anthropic.ts | 模型 API 包装 |
| mcp/ | client.ts、config.ts、types.ts | MCP 客户端、OAuth/XAA 认证 |
| plugins/ | pluginOperations.ts、PluginInstallationManager.ts | 插件安装/更新 |
| SessionMemory/ | sessionMemory.ts | 会话动态内存 |
| compact/ | compact.ts | 消息压缩与精简 |
| oauth/ | oauth.ts | OAuth + token 管理 |
| policyLimits/ | — | 企业策略配额检查 |
| extractMemories/ | — | 从会话自动提取学习点 |

**MCP 服务器配置**：

```typescript
type McpServerConfig =
  | { type: 'stdio'; command: string; args?: string[]; env?: Record<string, string> }
  | { type: 'sse'; url: string; headers?: Record<string, string> }
  | { type: 'http'; url: string; headers?: Record<string, string> }
  | { type: 'ws'; url: string }
  | { type: 'sdk'; /* 内置 SDK 实现 */ }

type ScopedMcpServerConfig = McpServerConfig & {
  scope?: 'local' | 'user' | 'project' | 'dynamic' | 'enterprise' | 'claudeai' | 'managed'
}

type McpOAuthConfig = {
  clientId?: string
  authServerMetadataUrl?: string
  callbackPort?: number
  xaa?: boolean                        // Cross-App Access
}
```

**可借鉴**：Transport 抽象（stdio/SSE/HTTP/WS）易于扩展；OAuth 与 XAA 分离；范围化配置按优先级合并；PluginInstallationManager 原子化安装。

---

### 22. memdir/ 持久化记忆

**关键文件**：
- `memdir.ts` (21KB) — MEMORY.md 截断、加载、提示词构建
- `memoryTypes.ts` (22KB) — Individual / Team / Auto / Index
- `paths.ts` (10KB) — 路径解析
- `findRelevantMemories.ts` (5.3KB) — 相关性检索
- `memoryScan.ts` (3.1KB) — 目录扫描与索引
- `teamMemPaths.ts` (11KB) — 团队记忆路径（TEAMMEM flag）

```typescript
export const MAX_ENTRYPOINT_LINES = 200
export const MAX_ENTRYPOINT_BYTES = 25_000

type EntrypointTruncation = {
  content: string
  lineCount: number
  byteCount: number
  wasLineTruncated: boolean
  wasByteTruncated: boolean
}

type MemoryType = 'individual' | 'team' | 'auto' | 'index'
```

**加载优先级**：
- 首读 MEMORY.md，超过 200 行或 25KB 截断（保留前 200 行 + 按字节截到最后完整行）
- 个人：`~/.claude/memory/`（全局）
- 项目：`.claude/memory/`（项目作用域）
- 团队：`memory/`（共享，TEAMMEM flag）

**可借鉴**：行数+字节双重截断（处理长行病态）；等级化作用域；启用门控（flag + settings 双控）。

---

### 23. upstreamproxy/ 上游代理

CCR 容器内 MITM 代理穿越企业防火墙。

**启动顺序**：
1. 读 `/run/ccr/session_token`（容器内只读）
2. `prctl(PR_SET_DUMPABLE, 0)` 阻止 ptrace 倾倒堆
3. 下载 upstreamproxy CA 证书，追加到系统 bundle
4. 启动本地 CONNECT → WebSocket 中继
5. 删除 token 文件（token 已在堆内，中继确认启动后销毁）

**绕过列表（NO_PROXY）**：anthropic.com（主 API 不 MITM）、github.com、registry.npmjs.org、pypi.org、RFC1918 私网、localhost、IMDS（169.254.x.x）。

**可借鉴**：Fail-open 设计（任何步骤失败仅 warning）；token 内存安全（文件→堆→文件删除限时间窗）；选择性 MITM（信任源排除）。

---

## 四、基础设施与杂项

### 24. cli/ CLI 输出与 I/O 转发

**关键文件**：
- `print.ts` (212KB) — ANSI/NDJSON 格式化、进度条、React Ink 输出
- `structuredIO.ts` (28KB) — 结构化 I/O 协议
- `remoteIO.ts` (9KB) — 远程会话 I/O 适配器
- `ndjsonSafeStringify.ts` — NDJSON 安全序列化
- `exit.ts` — 优雅退出
- `update.ts` (14KB) — CLI 版本更新
- `handlers/` — auth、agents、autoMode、mcp、plugins 等子命令
- `transports/` — HybridTransport（WS + HTTP）、WebSocketTransport、SSETransport、SerialBatchEventUploader

**可借鉴**：分离 CLI 转发（remoteIO）与本地输出（print）；HybridTransport 双通道（读用 WS 低延迟、写用 HTTP 可靠）；NDJSON 避免换行转义、流式无需缓冲整个响应。

---

### 25. entrypoints/ 程序入口

3 种运行模式：

- **`cli.tsx`** (39KB) — 主 CLI 启动点：环境检测、模块加载、Ink 渲染器初始化
- **`init.ts`** (13KB) — `claude init` 项目初始化
- **`mcp.ts`** (6KB) — MCP Server 模式入口，stdio 转发
- **`agentSdkTypes.ts`** (13KB) — Hook、Permission、SDK 通信协议类型
- **`sandboxTypes.ts`** (5.7KB) — 沙箱隔离类型
- `sdk/` — Agent SDK 适配器

**启动判定**：
- 常规：REPL.tsx + ink
- 远程（CCR）：HybridTransport + 远程指令队列
- 沙箱/MCP：`mcp.ts`

**可借鉴**：entrypoints 与 bootstrap 分离（程序启动 vs 全局状态初始化）；三种模式共享同套类型协议；init 延迟加载避免常规会话开销。

---

### 26. bootstrap/state.ts 全局初始化

唯一文件 `state.ts` (1758 行)：

```typescript
type State = {
  projectRoot: string
  totalCostUSD: number
  totalAPIDuration: number
  modelUsage: { [modelName: string]: ModelUsage }
  meter: Meter | null                  // OpenTelemetry
  sessionCounter: AttributedCounter | null
  lastAPIRequest: Omit<BetaMessageStreamParams, 'messages'> | null
  cachedClaudeMdContent: string | null
  agentColorMap: Map<string, AgentColorName>
  // ... 140+ 个字段
}

type ModelUsage = {
  inputTokens: number
  outputTokens: number
  cacheCreationInputTokens?: number
  cacheReadInputTokens?: number
}
```

**初始化顺序**：
1. 读 `.claude/config.json`、`settings.json`
2. 预连接 Anthropic API（socket）
3. 加载 OAuth token / API key
4. 初始化 Meter / Logger（OpenTelemetry）
5. 读 CLAUDE.md 缓存

**可借鉴**：单一真实来源（避免多处冲突）；Getter 封装支持后续缓存优化；ModelUsage 字段支持新 token 类型（cache creation/read）向前兼容；Meter 延迟初始化避免 ~400KB OTel 冷加载。

---

### 27. context/ React Context 与会话上下文

- `QueuedMessageContext.tsx` — 待处理消息队列（防竞态）
- `modalContext.tsx` — 模态框栈管理
- `promptOverlayContext.tsx` — 提示词覆盖层
- `overlayContext.tsx` — 通用覆盖层
- `notifications.tsx` — 通知（Toast）
- `voice.tsx`（Ant-only） — 语音识别/合成状态
- `mailbox.tsx` — Agent 间消息邮箱
- `stats.tsx` — 性能统计
- `fpsMetrics.tsx` — 帧率监控

**可借鉴**：Context 细粒度拆分避免单点 re-render 全树；Mailbox 模式异步通信；FPS 监控集成。

---

### 28. state/ 状态存储

```typescript
// store.ts 极简
type Store<T> = {
  getState: () => T
  setState: (updater: (prev: T) => T) => void
  subscribe: (listener: Listener) => () => void
}

type AppState = {
  messages: Message[]
  toolJSX: ReactNode
  toolPermissionContext: ToolPermissionContext
  speculative?: SpeculationState
  // ... 20+ 主要字段
}
```

**可借鉴**：手写发布-订阅（无外部库依赖）；setState 接收 updater 函数；onChangeAppState 副作用上层控制。

---

### 29. schemas/ Zod 校验

```typescript
const HookCommandSchema = z.discriminatedUnion('type', [
  z.object({ type: z.literal('command'), command: z.string(), if?: string, ... }),
  z.object({ type: z.literal('prompt'), prompt: z.string(), model?: string, ... }),
  z.object({ type: z.literal('agent'), prompt: z.string(), timeout?: number, ... }),
  z.object({ type: z.literal('http'), url: z.string().url(), headers?: ... }),
])

const HooksSettings = z.partialRecord(
  z.enum(HOOK_EVENTS),
  z.array(HookMatcherSchema)
)
```

**可借鉴**：单一 Zod 文件避免 cyclic import；`z.discriminatedUnion` 代替多个 schema；IfConditionSchema 复用权限规则语法；lazySchema 包裹返回函数支持循环引用。

---

### 30. types/ 公共类型

- `hooks.ts` (9KB) — HookEvent / HookCallbackMatcher
- `permissions.ts` (13KB) — 权限规则、PermissionResult、审计日志
- `plugin.ts` (11KB) — Plugin / PluginHook 元数据
- `command.ts` (7.7KB) — Command CLI 结构
- `logs.ts` (11KB) — 日志等级、诊断事件
- `textInputTypes.ts` (11KB) — 文本输入队列、QueuedCommand
- `ids.ts` (1.3KB) — 品牌 UUID 类型（SessionId / ToolId 等）
- `generated/` — codegen 生成的 Anthropic SDK 类型

**可借鉴**：细粒度文件划分（按功能域）；`ids.ts` 用 nominal type 防 id 混淆；Generated/ 子目录隔离自动生成 types。

---

### 31. constants/ 常量库

- `prompts.ts` (54KB) — **最大文件**：系统提示词模板、工具描述文本
- `apiLimits.ts` — RPM/TPM、token 上限
- `toolLimits.ts` — 各工具输入/输出限制
- `system.ts` — 系统配置（临时目录、缓存）
- `outputStyles.ts` — ANSI 颜色码、表格样式
- `product.ts` — 产品名、版本、URL
- `oauth.ts` — OAuth 提供商 ID、回调
- `betas.ts` — 测试特性 ID
- `figures.ts` — 图形符号（√ ✗ →）
- `cyberRiskInstruction.ts` — 安全风险提示
- `systemPromptSections.ts` — 提示词组件化 ID
- `xml.ts` — XML 标签（结构化输出）
- `errorIds.ts` — 错误代码枚举

**可借鉴**：Prompts.ts 按 section 子目录划分便于定位；APILimits 嵌套（provider → model → limits）支持多家 API；敏感字符串不硬编码（从 env / config 读）。

---

### 32. migrations/ 配置升级迁移

11 个迁移：
- `migrateSonnet45ToSonnet46` — Sonnet 4.5 → 4.6
- `migrateSonnet1mToSonnet45` — 1m context 升级
- `migrateOpusToOpus1m` — Opus 标准 → Opus 1m
- `migrateLegacyOpusToCurrent` — 旧 API model ID 映射
- `migrateFennecToOpus` — 内部代号（Fennec） → 正式版
- `migrateBypassPermissionsAcceptedToSettings`
- `migrateAutoUpdatesToSettings`
- `migrateEnableAllProjectMcpServersToSettings`
- `migrateReplBridgeEnabledToRemoteControlAtStartup`
- `resetProToOpusDefault`
- `resetAutoModeOptInForDefaultOffer`

```typescript
function migrateSonnet45ToSonnet46(): void {
  const config = getGlobalConfig()
  if (config.model === 'claude-sonnet-4-5-20241022') {
    saveGlobalConfig({ ...config, model: 'claude-sonnet-4-6-20250514' })
    logEvent('migration_sonnet45_to_sonnet46')
  }
}
```

**可借鉴**：每个迁移独立文件（便于 review / 定位）；迁移与业务逻辑分离；logEvent 上报迁移成功率；默认值设定优于强制迁移（尊重用户选择）；幂等设计（重跑无害）。

---

### 33. context.ts 根级会话上下文

与 `context/` 目录（React Context）**不同**。

```typescript
const getGitStatus = memoize(async () => { /* branch、status、最近 5 条 commit */ })
const getUserContext = memoize(async () => { /* 用户偏好、终端、cwd */ })
const getSystemContext = memoize(async () => { /* git + CLAUDE.md + 内存 + 诊断 */ })
```

**作用链路**：API 请求前注入系统提示；`getSystemContext()` 被 `constants/prompts.ts` 调用；Git 信息走 `utils/git.ts` 然后本地 memoize；CLAUDE.md 由 `utils/claudemd.ts` 读，缓存在 `bootstrap/state.ts` 的 `cachedClaudeMdContent`。

**可借鉴**：Memoize 会话期间一次性 git/fs；异步上下文生成与同步系统提示分离；MAX_STATUS_CHARS 截断防超大 git diff；诊断日志追踪上下文生成耗时。

---

### 34. utils/ 工具函数库

31 个子目录、549 个文件。按 domain 分组：

| 目录 | 核心 | 作用 |
|---|---|---|
| git/ | git.ts | 分支/status/commit |
| model/ | model.ts、modelStrings.ts、providers.ts | 模型选择 |
| auth/ | auth.ts、authFileDescriptor.ts | OAuth / API key |
| permissions/ | PermissionRule.ts、PermissionResult.ts、denialTracking.ts | 权限管理 |
| settings/ | settings.ts、settingsCache.ts、applySettingsChange.ts | 配置读写 |
| shell/ | shellProvider.ts、executeCommand.ts | bash/zsh/pwsh 抽象 |
| bash/ | parseShellScript.ts、bashAutoComplete.ts | Bash 特定 |
| plugins/ | loadPluginsDir.ts、pluginLoad.ts、validatePlugin.ts | 插件系统 |
| hooks/ | hookMatcher.ts、sessionHooks.ts、postSamplingHooks.ts | Hook 执行 |
| mcp/ | mcpSocket.ts、mcpServer.ts、mcpRegistry.ts | MCP 协议 |
| memory/ | memoryIndex.ts、vectorSearch.ts | 记忆系统 |
| telemetry/ | metrics.ts、telemetryAttributes.ts | 遥测 |
| background/ | backgroundQueue.ts、taskRunner.ts | 后台任务 |
| todo/ | todo.ts、todoParser.ts | TODO |
| task/ | Task.ts、taskQueue.ts | 任务状态 |
| messages/ | messageCompaction.ts、messageFormatting.ts | 消息处理 |

**单体大文件**：
- `api.ts` (26KB) — Anthropic SDK 包装、message streaming、token 计算
- `auth.ts` (65KB) — OAuth 授权码、令牌刷新、缓存
- `attachments.ts` (127KB) — 文件上传、多媒体、MIME
- `analyzeContext.ts` (42KB) — 上下文分析、文件选择算法
- `ansiToPng.ts` (214KB) — ANSI 转 PNG（分享截图）
- `autoUpdater.ts` (18KB) — 版本检查与自动升级

**可借鉴**：31 个子目录按 domain 分组；单一导出文件原则；长文件保留（避免过度拆分）；background/ 与 task/ 任务队列支持并发与取消。

---

### 35. moreright/ UI 增强（内部特性）

Ant 内部 "More Right" 面板交互控制。Stub 版本对外构建：

```typescript
function useMoreRight(args): {
  onBeforeQuery: (input, all, n) => Promise<boolean>   // 提交前钩子
  onTurnComplete: (all, aborted) => Promise<void>       // 轮次完成
  render: () => null                                    // Stub 返回 null，内部返回 React 组件
}
```

**可借鉴**：Feature stub 模式（同一代码库支持内部/外部构建，无条件编译 ifdef）；Hook 形式返回回调集成度高于 component injection；Promise<boolean> 异步决策。

---

### 36. native-ts/ 原生模块 TS 转译

TypeScript 实现原生模块，降依赖、提跨平台兼容：

- `color-diff/index.ts` (30KB) — 语法高亮 diff，替代 Rust 实现，使用 highlight.js + diff 包做 word-level
- `file-index/index.ts` (12KB) — 模糊文件搜索，替代 Rust nucleo，nucleo-style 评分（SCORE_MATCH / BONUS_BOUNDARY）+ 测试文件降权（1.05x）
- `yoga-layout/index.ts` (83KB) — 完整 Yoga 算法（flexbox 计算）
- `yoga-layout/enums.ts` (2.8KB) — YogaValue/YogaEdge/FlexDirection

**可借鉴**：TS port 保持原生 API 接口（调用端无感知）；评分算法用 const 避免 magic number；Yoga 完整实现支持 offline layout；测试文件降权体现 domain knowledge。

---

### 37. projectOnboardingState.ts 项目引导

```typescript
type Step = {
  key: string                  // 'workspace' | 'claudemd'
  text: string
  isComplete: boolean
  isCompletable: boolean       // 不是 optional
  isEnabled: boolean
}

// 步骤：
// 1. workspace: 目录为空 → 创建新 app / 克隆 repo
// 2. claudemd: 存在 CLAUDE.md → 运行 /init 创建指令文件
```

**核心函数**：`getSteps()`, `isProjectOnboardingComplete()`, `shouldShowProjectOnboarding()`, `maybeMarkProjectOnboardingComplete()`, `incrementProjectOnboardingSeenCount()`

**可借鉴**：步骤动态生成（不硬编码）；见面上限 `seenCount >= 4` 防骚扰；缓存短路（`projectConfig.hasCompletedProjectOnboarding`）；前置条件检查（`isWorkspaceDirEmpty`）。

---

## 附录：对自研 Agent 内核的关键参考点（汇总）

### A1. 主循环架构

1. **生成器驱动**：`async *submitMessage()` 返回 `AsyncGenerator<SDKMessage>`，把 API 流式 / 工具并发 / 权限 / 紧凑编织成统一状态机
2. **TAOR 显式分离**：每阶段独立便于插 hook、错误恢复、日志
3. **State 对象**：承载循环不变量（messages / toolUseContext / turnCount / transition）
4. **stop_reason 驱动**：`tool_use` → 执行后回灌；`end_turn` → post_sampling 钩子决定继续/停止；`max_tokens` → 触发 reactive_compact

### A2. 工具执行

5. **isConcurrencySafe + isReadOnly 解耦**：读并行、写互斥
6. **StreamingToolExecutor**：边流边执行，TrackedTool 状态机（queued / executing / completed / yielded）
7. **partitionToolCalls**：提前分批，runTools 编排
8. **Tool 接口四重契约**：执行 / 渲染 / 权限 / 提示——单一 Tool 类型同时履行四个角色
9. **siblingAbortController**：Bash 错误触发同级取消，避免脏数据扩散

### A3. 权限与钩子

10. **canUseTool hook 包装**：跟踪拒绝供 SDK 报告
11. **PreToolUse 钩子返回 permissionDecision**：短路权限提示，加速决策
12. **post_sampling 钩子**：assistant 消息到达后执行，支持继续/停止决策
13. **`if` 条件用 Permission 规则语法**：复用 DSL，避免无谓 hook 执行
14. **4 种钩子实现**：Command / Prompt / HTTP / Agent；asyncRewake 支持事件驱动重评估

### A4. 任务与子代理

15. **Task ID 类型前缀**：单字母识别（b=bash, a=agent, r=remote...），便于 symlink 攻击防御
16. **任务状态存 AppState + outputFile**：解耦内存
17. **Sub-agent 独立 QueryEngine + 工具子集**：避免递归套娃和越权
18. **Watchdog 卡住检测**：45s 无输出 + 提示模式 → 通知用户

### A5. 上下文管理

19. **Compaction 多层**：文件读取去重 / 工具结果摘要 / 旧轮次摘要 / 系统消息收敛 / 硬截断
20. **contentReplacementState**：工具结果预算支持选择性文本替换
21. **不删 PG**：被剔除内容仍可拉到（前端"查看完整历史"）
22. **memdir 双重截断**：200 行 + 25KB，处理长行病态
23. **Memoize 上下文生成**：会话期间一次性 git / fs

### A6. 扩展性

24. **Skills 渐进式加载**：Frontmatter 启动加载、content 延后
25. **Skills 路径匹配**：按 cwd 动态可见
26. **realpath 去重**：处理 symlink
27. **Plugin 容器**：聚合 skills / hooks / mcp / lsp
28. **范围化配置**：local / user / project / managed 按优先级合并
29. **MCP Transport 抽象**：stdio / SSE / HTTP / WS / SDK 易扩展

### A7. UI 与交互

30. **17 个 keybinding contexts**：避免全局快捷键冲突
31. **弦键状态机**：1s 超时，chord_started / chord_cancelled / match / none
32. **VirtualMessageList**：5000+ 消息虚拟滚动
33. **dialogLaunchers**：一次性 UI 与主 loop 分离
34. **Mailbox**：Agent 间异步通信，避免 provider hell

### A8. 工程实践

35. **bootstrap/state.ts 单一真实来源**：getter 封装，向前兼容
36. **migrations/ 一文件一迁移**：独立 review、logEvent 上报、幂等
37. **Stub 模式**：同一代码库支持多构建（内部/外部），无 ifdef
38. **types/ 与 schemas/ 分离**：避免循环依赖
39. **Constants prompts.ts 集中**：避免 magic string 散落
40. **WebSocket 分级 close code**：4001 短重试、4003 永久放弃、其他指数退避
41. **HybridTransport 双通道**：读 WS（低延迟）+ 写 HTTP（可靠）
42. **NDJSON 序列化**：避免换行转义，流式无需缓冲整个响应
43. **Fail-open 设计**（upstreamproxy 等）：任何步骤失败仅 warning，不中断会话

---

## 与我们 `00-architecture.md` v0.1 的对照清单

| 我们 v0.1 决策 | Claude Code 对应实现 | 是否吻合 | 差异点 |
|---|---|---|---|
| Q1 `/agent` 单独路由 | TUI 单一 REPL，无路由概念 | N/A | 我们是 Web，多页路由必要 |
| Q2 左栏会话归项目 | 单会话 REPL，无项目分组 | N/A | 我们多会话+项目分组 |
| Q3 工件用户维度持久化 | 无独立工件层（输出在消息流） | 改进 | 我们引入 Display Panel + ArtifactStore |
| Q4 只接 Codex | 主接 Anthropic + OpenAI provider 抽象 | 类比 | services/api/ 双 provider 抽象可借鉴 |
| Q5 ai-assistant 收编 | 无遗留模块 | N/A | 我们 Q5 实施时参考 services/api 抽象层 |
| Q6 Skill 双源 | 文件系统 + bundled + plugin + MCP 四源 | 扩展 | 我们 v1 先做文件 + DB 双源，未来引入 plugin / MCP |
| L2 QueryEngine TAOR | QueryEngine + query.ts 主循环 | ✅ | 直接对照实现 |
| L3 Tool Registry 并发控制 | runTools + StreamingToolExecutor | ✅ | 直接对照 |
| L4 Skill Frontmatter | skills/loadSkillsDir.ts | ✅ | 直接对照 |
| L5 Sub-Agent Coordinator | coordinator/ + Agent.spawn tool | ✅ | 直接对照 |
| L6 Task Tracker | tasks/ + Task.ts | ✅ | 直接对照 |
| L7 Compaction | utils/messages/messageCompaction.ts | ✅ | 多层策略可借鉴 |
| L8 权限/钩子 | hooks/ + ToolPermissionContext | ✅ | PreToolUse 短路设计可借鉴 |
| L9 业务工具适配层 | tools/ + MCP | ✅ | 我们走 NestJS Service 而非本地 fs |

---

> **下一步建议**：
> 1. PR1 三栏 UI 骨架时参考 components/PromptInput + components/messages 的分离方式
> 2. PR3 QueryEngine MVP 时直接对照 query.ts 的 TAOR + State 对象
> 3. PR4 Tool Registry 时复用 Tool 接口四重契约 + StreamingToolExecutor 模式
> 4. PR5 Skill Registry 时按 loadSkillsDir.ts 的 Frontmatter 解析 + 双源合并实现
> 5. 后续 Sub-Agent 时参考 coordinator/ 的工具子集机制，强制 sub-agent 工具集 ⊂ main agent 工具集
