diff --git "a/docs/04-\351\205\215\347\275\256\350\277\201\347\247\273\345\215\263\344\273\243\347\240\201.md" "b/docs/04-\351\205\215\347\275\256\350\277\201\347\247\273\345\215\263\344\273\243\347\240\201.md"
index f75670d..fed31c3 100644
--- "a/docs/04-\351\205\215\347\275\256\350\277\201\347\247\273\345\215\263\344\273\243\347\240\201.md"
+++ "b/docs/04-\351\205\215\347\275\256\350\277\201\347\247\273\345\215\263\344\273\243\347\240\201.md"
@@ -52,6 +52,30 @@ resetProToOpusDefault.ts
---
+## 全景图:11 个迁移函数与 main.tsx 的关系
+
+```mermaid
+graph TB
+ Boot["main.tsx 启动"] --> Check{"migrationVersion === 11?"}
+ Check -- "是" --> Skip["整段跳过"]
+ Check -- "否" --> Sync["sync 流水线(顺序写死)"]
+
+ Sync --> Field["搬家 3 个
autoUpdates / claudeMd / replBridge→remoteControl"]
+ Sync --> Model["模型字符串 6 个
fennec→opus, opus→opus1m,
sonnet1m→45→46, legacyOpus→current,
resetProToOpus"]
+ Sync --> Cond["条件分支 2 个
TRANSCRIPT_CLASSIFIER / 'external'==='ant'"]
+
+ Field --> Bump["saveGlobalConfig: migrationVersion = 11"]
+ Model --> Bump
+ Cond --> Bump
+
+ Boot --> Async["migrateChangelogFromConfig
(fire-and-forget,不参与版本号)"]
+
+ style Sync fill:#e1f5fe
+ style Async fill:#fff3e0
+```
+
+---
+
## 一、流水线:一个版本号守护的串行入口
所有 11 个迁移并不是各自找时机各自跑的,它们被集中在 `main.tsx` 的一个内部函数里,由一个叫 `migrationVersion` 的小数字守护。下面这段就是流水线的全貌(`main.tsx:323-352`):
diff --git "a/docs/12-\346\226\207\344\273\266-\344\273\243\347\240\201-\344\270\216-LSP-\345\215\217\344\275\234\346\227\217.md" "b/docs/12-\346\226\207\344\273\266-\344\273\243\347\240\201-\344\270\216-LSP-\345\215\217\344\275\234\346\227\217.md"
index 5e9cb12..e1624dd 100644
--- "a/docs/12-\346\226\207\344\273\266-\344\273\243\347\240\201-\344\270\216-LSP-\345\215\217\344\275\234\346\227\217.md"
+++ "b/docs/12-\346\226\207\344\273\266-\344\273\243\347\240\201-\344\270\216-LSP-\345\215\217\344\275\234\346\227\217.md"
@@ -12,6 +12,38 @@
---
+## 全景图:八工具 + LSP/REPL 服务的协作关系
+
+```mermaid
+graph TB
+ Model["AI Agent"] --> Read["FileReadTool"]
+ Model --> Write["FileWriteTool"]
+ Model --> Edit["FileEditTool"]
+ Model --> NB["NotebookEditTool"]
+ Model --> Glob["GlobTool"]
+ Model --> Grep["GrepTool"]
+ Model --> LSPTool["LSPTool"]
+ Model --> REPL["REPLTool"]
+
+ Read --> ReadState[("readFileState
读过没有 / 读完之后改没改")]
+ Write --> ReadState
+ Edit --> ReadState
+ NB --> ReadState
+
+ Glob --> RipGrep[("ripgrep")]
+ Grep --> RipGrep
+
+ LSPTool --> LSPSvc[("services/lsp/
LSPClient / LSPDiagnosticRegistry /
LSPServerManager")]
+
+ REPL --> Hidden["8 个 deferred 工具
(写文件/REPL/Glob/Grep/LSP)"]
+
+ style ReadState fill:#fff3e0
+ style RipGrep fill:#e1f5fe
+ style LSPSvc fill:#e1f5fe
+```
+
+---
+
## 一、读:FileReadTool 与"先读后写"这条暗规
`tools/FileReadTool/FileReadTool.ts:1-1183` 是这一族里最长的一个文件 —— 不是因为它要做什么复杂的事,而是因为读文件这件事在 Claude Code 里有太多形态:纯文本、二进制图片、PDF、Jupyter notebook、超长日志,每一种都要在同一个工具里走完"路径解析 → 编码探测 → 截断 → 回执"的全套流程。
diff --git "a/docs/13-\351\200\232\344\277\241\350\260\203\345\272\246\351\227\256\350\257\242\344\270\216\345\220\210\346\210\220\345\267\245\345\205\267.md" "b/docs/13-\351\200\232\344\277\241\350\260\203\345\272\246\351\227\256\350\257\242\344\270\216\345\220\210\346\210\220\345\267\245\345\205\267.md"
index 7d9cf36..875a0da 100644
--- "a/docs/13-\351\200\232\344\277\241\350\260\203\345\272\246\351\227\256\350\257\242\344\270\216\345\220\210\346\210\220\345\267\245\345\205\267.md"
+++ "b/docs/13-\351\200\232\344\277\241\350\260\203\345\272\246\351\227\256\350\257\242\344\270\216\345\220\210\346\210\220\345\267\245\345\205\267.md"
@@ -21,6 +21,58 @@
---
+## 全景图:十把工具按"通道方向"分四组
+
+```mermaid
+graph LR
+ Agent["AI Agent"]
+
+ subgraph G1["往外抓事实"]
+ WebFetch["WebFetchTool"]
+ WebSearch["WebSearchTool"]
+ end
+
+ subgraph G2["挂到时间/外触发"]
+ Cron["ScheduleCronTool"]
+ RTrig["RemoteTriggerTool"]
+ Sleep["SleepTool"]
+ end
+
+ subgraph G3["与人对话(低带宽)"]
+ Ask["AskUserQuestionTool"]
+ Brief["BriefTool"]
+ Config["ConfigTool"]
+ end
+
+ subgraph G4["与同伴 Agent(高频)"]
+ Send["SendMessageTool"]
+ end
+
+ subgraph G5["结构化退出"]
+ Synth["SyntheticOutputTool"]
+ end
+
+ Agent --> G1
+ Agent --> G2
+ Agent --> G3
+ Agent --> G4
+ Agent --> G5
+
+ G1 -.-> Net[("外网 / API")]
+ G2 -.-> Sched[("scheduler / 消息队列")]
+ G3 -.-> User[("用户 UI")]
+ G4 -.-> Peer[("teammate 收件箱")]
+ G5 -.-> Schema[("Ajv schema 校验")]
+
+ style G1 fill:#e1f5fe
+ style G2 fill:#fff3e0
+ style G3 fill:#f3e5f5
+ style G4 fill:#e8f5e9
+ style G5 fill:#fce4ec
+```
+
+---
+
## 一、往外抓一段事实:WebFetch 与 WebSearch
### 1.1 WebFetch:URL 背后那条比想象中长的链
diff --git "a/docs/17-Coordinator-Cron-\344\270\216\345\256\232\346\227\266\350\260\203\345\272\246.md" "b/docs/17-Coordinator-Cron-\344\270\216\345\256\232\346\227\266\350\260\203\345\272\246.md"
index fdef6a4..8abde3c 100644
--- "a/docs/17-Coordinator-Cron-\344\270\216\345\256\232\346\227\266\350\260\203\345\272\246.md"
+++ "b/docs/17-Coordinator-Cron-\344\270\216\345\256\232\346\227\266\350\260\203\345\272\246.md"
@@ -11,6 +11,37 @@
---
+## 全景图:Coordinator 与 Cron 两条线汇到同一入口
+
+```mermaid
+graph TB
+ subgraph Spatial["空间维度:Coordinator"]
+ Main["主会话
(项目经理 system prompt)"]
+ Main --> Worker1["Worker Agent 1"]
+ Main --> Worker2["Worker Agent 2"]
+ Worker1 --> WorkerDone["Worker 完成"]
+ Worker2 --> WorkerDone
+ end
+
+ subgraph Temporal["时间维度:Cron"]
+ CronCreate["CronCreateTool"]
+ CronCreate --> Disk[("cron.json")]
+ Tick["scheduler: setInterval(1000)"]
+ Tick --> Disk
+ Disk --> Trigger["到点触发:读出 prompt"]
+ end
+
+ WorkerDone --> Enqueue["enqueuePendingNotification()"]
+ Trigger --> Enqueue
+ Enqueue --> Queue[("messageQueueManager
'later' 优先级")]
+ Queue --> QueryLoop["主线程 query loop
继续转"]
+
+ style Enqueue fill:#fff3e0
+ style Queue fill:#e1f5fe
+```
+
+---
+
## 一、为什么放在同一章?
> 本节先解释合章动机;具体源码位置见 §二(`coordinator/coordinatorMode.ts`)与 §三、§四(`tools/ScheduleCronTool/`、`utils/cronScheduler.ts`、`hooks/useScheduledTasks.ts`)。
diff --git "a/docs/21-Skill-Plugin-OutputStyle\344\270\211\346\211\251\345\261\225\347\202\271.md" "b/docs/21-Skill-Plugin-OutputStyle\344\270\211\346\211\251\345\261\225\347\202\271.md"
index 47e8720..2845c18 100644
--- "a/docs/21-Skill-Plugin-OutputStyle\344\270\211\346\211\251\345\261\225\347\202\271.md"
+++ "b/docs/21-Skill-Plugin-OutputStyle\344\270\211\346\211\251\345\261\225\347\202\271.md"
@@ -25,6 +25,35 @@ Hook 脚本 → Skill 文件 → Agent 定义 → Plugin 包
> **章内导读**:§一 自定义 Skill → §二 自定义 Agent → §三 Plugin 系统架构 → §四 Hook 脚本 → §五 MCP Skill 桥接 → §六 Output Style 作为第三条扩展路径 → §七 实战示例 → §八 可迁移模式。本章按「扩展点从轻量到重量」组织:Skill → Agent → Plugin → Hook → MCP → Output Style。读完前六节后 §七 是一份可直接照抄的 walkthrough。
+## 全景图:四档扩展机制 + Output Style 第三条路径
+
+```mermaid
+graph TB
+ User["扩展开发者"]
+
+ User --> Hook["Hook 脚本
(最轻:shell 命令钩子)"]
+ User --> Skill["Skill
(一份 markdown:prompt + 行为约束)"]
+ User --> Agent["Agent
(独立 AI 角色:prompt + 工具集 + 模型)"]
+ User --> Plugin["Plugin
(最重:目录包,可携带上述三种 + MCP + Output Style)"]
+
+ User --> OS["Output Style
(体验层第三条路径:
system prompt 末尾的可替换 tail)"]
+
+ Hook -.触发于.-> Events["27 个 HOOK_EVENTS"]
+ Skill -.被模型自主调用.-> SkillTool["SkillTool 桥接"]
+ Agent -.spawn 时加载.-> AgentRuntime["runAgent()"]
+ Plugin -.聚合.-> Hook
+ Plugin -.聚合.-> Skill
+ Plugin -.聚合.-> Agent
+ Plugin -.聚合.-> OS
+
+ OS -.注入.-> Prompt[("constants/prompts.ts
getOutputStyleSection()")]
+
+ style Plugin fill:#e1f5fe
+ style OS fill:#fff3e0
+```
+
+---
+
## 一、自定义 Skill 编写
### 1.1 目录结构与发现机制
diff --git "a/docs/24-Bridge-IPC-\344\270\216\350\277\234\347\250\213\344\274\232\350\257\235.md" "b/docs/24-Bridge-IPC-\344\270\216\350\277\234\347\250\213\344\274\232\350\257\235.md"
index 7fb03b2..ff38792 100644
--- "a/docs/24-Bridge-IPC-\344\270\216\350\277\234\347\250\213\344\274\232\350\257\235.md"
+++ "b/docs/24-Bridge-IPC-\344\270\216\350\277\234\347\250\213\344\274\232\350\257\235.md"
@@ -19,6 +19,42 @@
---
+## 全景图:本地 CLI 与远端控制器之间的两层架构
+
+```mermaid
+graph TB
+ subgraph LocalMachine["你的笔记本"]
+ CLI["本地 Claude Code 进程"]
+ Bridge["bridge/
environment + session 两层"]
+ Sub["sessionRunner 子进程"]
+ CLI -.内部 IPC.-> Bridge
+ Bridge --> Sub
+ end
+
+ subgraph Cloud["服务端"]
+ Reg["register / poll / work secret 端点"]
+ WS[("SessionsWebSocket")]
+ end
+
+ subgraph Remote["手机 / Web / Desktop"]
+ Phone["浏览器 / App"]
+ end
+
+ Bridge -- "握手 + 心跳" --> Reg
+ Bridge <-- "对话帧 / 控制帧 / 取消" --> WS
+ Phone -- "登录会话" --> WS
+ Sub -- "stdout JSON 流" --> Bridge
+
+ Sub -.activity 事件.-> Phone
+ Phone -.control_request 权限询问.-> Bridge
+ Bridge -.control_response.-> Phone
+
+ style Bridge fill:#e1f5fe
+ style WS fill:#fff3e0
+```
+
+---
+
## 一、为什么需要 Bridge?
在拆代码之前先把场景描清楚。手机上点一下「Claude」图标,看到的是一条对话窗,但模型不在手机上跑——本地的 `claude` 进程还得动磁盘、读你的项目、跑测试。中间需要一条管道,把对面的输入翻译成本地 REPL 的「下一条用户消息」,再把本地的回答、工具调用、权限请求一路反向送出去。
diff --git "a/docs/25-DirectConnect-\344\270\216\344\270\212\346\270\270\344\273\243\347\220\206.md" "b/docs/25-DirectConnect-\344\270\216\344\270\212\346\270\270\344\273\243\347\220\206.md"
index 6bbff93..515c3cf 100644
--- "a/docs/25-DirectConnect-\344\270\216\344\270\212\346\270\270\344\273\243\347\220\206.md"
+++ "b/docs/25-DirectConnect-\344\270\216\344\270\212\346\270\270\344\273\243\347\220\206.md"
@@ -13,6 +13,38 @@
3. **这两条线为什么放在一章?** — 它们在工程范式上是一对镜像
4. **能从中学到哪些可复用模式?** — 握手与长连分离、单 WS 双向 RPC、fail open、贴近 surface 的状态注入
+## 全景图:server/ 与 upstreamproxy/ 两段对称的"直连"
+
+```mermaid
+graph TB
+ subgraph LocalCLI["本地 Claude Code 进程"]
+ REPL["REPL / query loop"]
+ end
+
+ subgraph DirectConnect["server/ — DirectConnect"]
+ DCM["directConnectManager.ts"]
+ DCSession["createDirectConnectSession"]
+ DCM --> DCSession
+ end
+
+ subgraph UpstreamProxy["upstreamproxy/ — CCR MITM"]
+ Relay["relay.ts"]
+ Proxy["upstreamproxy.ts"]
+ Relay --> Proxy
+ end
+
+ REPL -- "本地 REPL → 远端 session
(接管者视角)" --> DCM
+ DCSession -. WS 双向 RPC .-> RemoteSrv[("远端服务端")]
+
+ REPL -- "出网 API 流量" --> Relay
+ Proxy -. "注入企业头 / 走企业代理" .-> Upstream[("Anthropic API / 企业 LLM")]
+
+ style DCM fill:#e1f5fe
+ style Relay fill:#fff3e0
+```
+
+---
+
## 一、两条「直连」线,一个 CLI
打开 `claude-code-cli` 的目录,你会看到两个名字里都带「直」「连」「代理」气息的目录:
diff --git "a/docs/27-\347\273\204\344\273\266\344\270\216\350\256\276\350\256\241\347\263\273\347\273\237.md" "b/docs/27-\347\273\204\344\273\266\344\270\216\350\256\276\350\256\241\347\263\273\347\273\237.md"
index bf29780..1bfaf1c 100644
--- "a/docs/27-\347\273\204\344\273\266\344\270\216\350\256\276\350\256\241\347\263\273\347\273\237.md"
+++ "b/docs/27-\347\273\204\344\273\266\344\270\216\350\256\276\350\256\241\347\263\273\347\273\237.md"
@@ -17,6 +17,28 @@ Claude Code 面对的正是这样的复杂度。它的 UI 不是静态的信息
---
+## 全景图:从 token 到工具 UI 的五层
+
+```mermaid
+graph TB
+ Token["主题 token
80+ 语义化颜色"] --> Provider["ThemeProvider
(React Context)"]
+ Provider --> Base["基础组件
ThemedText / ThemedBox"]
+ Base --> Layout["布局组件
Pane / Divider / Dialog"]
+ Base --> Inter["交互组件
Tabs / ProgressBar / FuzzyPicker"]
+ Layout --> ToolUI["工具 UI 协议
Tool 接口的 10 个 Render/查询方法"]
+ Inter --> ToolUI
+
+ ToolUI --> Bash[("BashTool UI")]
+ ToolUI --> Edit[("FileEdit UI")]
+ ToolUI --> Other[("…其他工具 UI")]
+
+ style Token fill:#fff3e0
+ style Provider fill:#e1f5fe
+ style ToolUI fill:#f3e5f5
+```
+
+---
+
## 一、主题系统:80+ 语义化颜色 token
### 1.1 Theme 类型:颜色的语义化契约
diff --git "a/docs/28-Keybindings-Vim\344\270\216Voice\350\276\223\345\205\245.md" "b/docs/28-Keybindings-Vim\344\270\216Voice\350\276\223\345\205\245.md"
index 1e98369..db544ca 100644
--- "a/docs/28-Keybindings-Vim\344\270\216Voice\350\276\223\345\205\245.md"
+++ "b/docs/28-Keybindings-Vim\344\270\216Voice\350\276\223\345\205\245.md"
@@ -26,6 +26,34 @@ voice/, services/voice*, hooks/useVoice* # 按住一个键 → 一段 PCM 流
---
+## 全景图:同一条按键流被三套子系统分别解释
+
+```mermaid
+graph TB
+ Ink["Ink useInput
(按下了哪个键)"]
+
+ Ink --> KB["keybindings/
按键 → 动作 ID"]
+ Ink --> Vim["vim/
按键序列 → 一次 vim 命令"]
+ Ink --> Voice["voice/ + services/voice*
按住一个键 → PCM 流"]
+
+ KB --> Action["dispatch 到 action handler"]
+ Vim --> Buffer["编辑 buffer / 运动 / 操作符"]
+ Voice --> Native["原生录音模块"]
+ Native --> WS[("Deepgram WebSocket")]
+ WS --> Text["转写文本回灌到 PromptInput"]
+
+ Action -.高优先级.-> Result["上层意图"]
+ Buffer -.中优先级.-> Result
+ Text -.低优先级.-> Result
+
+ style Ink fill:#fff3e0
+ style KB fill:#e1f5fe
+ style Vim fill:#f3e5f5
+ style Voice fill:#e8f5e9
+```
+
+---
+
## 一、Keybindings:一套带优先级的按键解析器
### 1.1 为什么这件事值得做成一个子系统?
diff --git "a/docs/29-Buddy\345\256\240\347\211\251.md" "b/docs/29-Buddy\345\256\240\347\211\251.md"
index 8e47cff..9fcbd32 100644
--- "a/docs/29-Buddy\345\256\240\347\211\251.md"
+++ "b/docs/29-Buddy\345\256\240\347\211\251.md"
@@ -27,6 +27,36 @@ Claude Code 的答案可以一句话概括:**把"骨"和"魂"切开存,把
---
+## 全景图:六个文件如何挂进五个子系统
+
+```mermaid
+graph TB
+ subgraph BuddyFiles["buddy/ 6 个源码文件"]
+ Types["types.ts
物种与稀有度词典"]
+ Comp["companion.ts
骨与魂的拆分"]
+ Sprites["sprites.ts
18 个像素画"]
+ Sprite["CompanionSprite.tsx
帧动画与气泡"]
+ Prompt["prompt.ts
第三人称介绍"]
+ Notif["useBuddyNotification.tsx
彩虹色入口提示"]
+ end
+
+ Comp -.companion 字段.-> Config[("配置:companion / companionMuted")]
+ Sprite -.嵌入.-> PromptInput[("PromptInput UI")]
+ Prompt -.注入.-> SP[("System Prompt")]
+ Comp -.attach.-> Att[("Attachment 消息流")]
+ Notif -.feature('BUDDY').-> Cmd[("commands/buddy/")]
+
+ Types -.被引用.-> Comp
+ Types -.被引用.-> Sprites
+ Sprites -.被引用.-> Sprite
+
+ style BuddyFiles fill:#fff3e0
+ style Config fill:#e1f5fe
+ style SP fill:#f3e5f5
+```
+
+---
+
## 一、骨与魂:一半算出来,一半存下来
打开 `buddy/types.ts:100-124`,能看到 `Companion` 这个类型被一刀切成两半:
diff --git "a/docs/30-Doctor\345\261\217\344\270\216OutputStyle\344\275\223\351\252\214.md" "b/docs/30-Doctor\345\261\217\344\270\216OutputStyle\344\275\223\351\252\214.md"
index 54aa9ed..9d42e03 100644
--- "a/docs/30-Doctor\345\261\217\344\270\216OutputStyle\344\275\223\351\252\214.md"
+++ "b/docs/30-Doctor\345\261\217\344\270\216OutputStyle\344\275\223\351\252\214.md"
@@ -12,6 +12,33 @@
---
+## 全景图:screens/ 三屏 + outputStyles 的体验入口
+
+```mermaid
+graph TB
+ User["用户"]
+
+ User --> Doctor["screens/Doctor.tsx
自检仪表盘(574 行)"]
+ User --> Resume["screens/ResumeConversation.tsx
会话拣选器"]
+ User --> OS["/output-style 命令
+ .claude/output-styles/*.md"]
+
+ Doctor --> Diag["getDoctorDiagnostic()"]
+ Diag --> Items["安装 / 冲突 / 自动更新 /
MCP token / 权限规则 / hooks ..."]
+
+ Resume --> Local["本地 session 文件"]
+ Resume --> Remote["远端 session API"]
+
+ OS --> Loader["outputStyles/loadOutputStylesDir.ts"]
+ Loader --> Const["constants/outputStyles.ts
getOutputStyleConfig()"]
+ Const --> SP[("system prompt 末尾
getOutputStyleSection()")]
+
+ style Doctor fill:#e1f5fe
+ style Resume fill:#fff3e0
+ style OS fill:#f3e5f5
+```
+
+---
+
## 一、Doctor 屏:把诊断结果摆在一屏上
### 1.1 命令入口薄到只剩门面