Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions docs/04-配置迁移即代码.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 个<br/>autoUpdates / claudeMd / replBridge→remoteControl"]
Sync --> Model["模型字符串 6 个<br/>fennec→opus, opus→opus1m,<br/>sonnet1m→45→46, legacyOpus→current,<br/>resetProToOpus"]
Sync --> Cond["条件分支 2 个<br/>TRANSCRIPT_CLASSIFIER / 'external'==='ant'"]

Field --> Bump["saveGlobalConfig: migrationVersion = 11"]
Model --> Bump
Cond --> Bump

Boot --> Async["migrateChangelogFromConfig<br/>(fire-and-forget,不参与版本号)"]

style Sync fill:#e1f5fe
style Async fill:#fff3e0
```

---

## 一、流水线:一个版本号守护的串行入口

所有 11 个迁移并不是各自找时机各自跑的,它们被集中在 `main.tsx` 的一个内部函数里,由一个叫 `migrationVersion` 的小数字守护。下面这段就是流水线的全貌(`main.tsx:323-352`):
Expand Down
32 changes: 32 additions & 0 deletions docs/12-文件-代码-与-LSP-协作族.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<br/>读过没有 / 读完之后改没改")]
Write --> ReadState
Edit --> ReadState
NB --> ReadState

Glob --> RipGrep[("ripgrep")]
Grep --> RipGrep

LSPTool --> LSPSvc[("services/lsp/<br/>LSPClient / LSPDiagnosticRegistry /<br/>LSPServerManager")]

REPL --> Hidden["8 个 deferred 工具<br/>(写文件/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、超长日志,每一种都要在同一个工具里走完"路径解析 → 编码探测 → 截断 → 回执"的全套流程。
Expand Down
52 changes: 52 additions & 0 deletions docs/13-通信调度问询与合成工具.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 背后那条比想象中长的链
Expand Down
31 changes: 31 additions & 0 deletions docs/17-Coordinator-Cron-与定时调度.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,37 @@

---

## 全景图:Coordinator 与 Cron 两条线汇到同一入口

```mermaid
graph TB
subgraph Spatial["空间维度:Coordinator"]
Main["主会话<br/>(项目经理 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<br/>'later' 优先级")]
Queue --> QueryLoop["主线程 query loop<br/>继续转"]

style Enqueue fill:#fff3e0
style Queue fill:#e1f5fe
```

---

## 一、为什么放在同一章?

> 本节先解释合章动机;具体源码位置见 §二(`coordinator/coordinatorMode.ts`)与 §三、§四(`tools/ScheduleCronTool/`、`utils/cronScheduler.ts`、`hooks/useScheduledTasks.ts`)。
Expand Down
29 changes: 29 additions & 0 deletions docs/21-Skill-Plugin-OutputStyle三扩展点.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 脚本<br/>(最轻:shell 命令钩子)"]
User --> Skill["Skill<br/>(一份 markdown:prompt + 行为约束)"]
User --> Agent["Agent<br/>(独立 AI 角色:prompt + 工具集 + 模型)"]
User --> Plugin["Plugin<br/>(最重:目录包,可携带上述三种 + MCP + Output Style)"]

User --> OS["Output Style<br/>(体验层第三条路径:<br/>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<br/>getOutputStyleSection()")]

style Plugin fill:#e1f5fe
style OS fill:#fff3e0
```

---

## 一、自定义 Skill 编写

### 1.1 目录结构与发现机制
Expand Down
36 changes: 36 additions & 0 deletions docs/24-Bridge-IPC-与远程会话.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,42 @@

---

## 全景图:本地 CLI 与远端控制器之间的两层架构

```mermaid
graph TB
subgraph LocalMachine["你的笔记本"]
CLI["本地 Claude Code 进程"]
Bridge["bridge/<br/>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 的「下一条用户消息」,再把本地的回答、工具调用、权限请求一路反向送出去。
Expand Down
32 changes: 32 additions & 0 deletions docs/25-DirectConnect-与上游代理.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<br/>(接管者视角)" --> 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` 的目录,你会看到两个名字里都带「直」「连」「代理」气息的目录:
Expand Down
22 changes: 22 additions & 0 deletions docs/27-组件与设计系统.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,28 @@ Claude Code 面对的正是这样的复杂度。它的 UI 不是静态的信息

---

## 全景图:从 token 到工具 UI 的五层

```mermaid
graph TB
Token["主题 token<br/>80+ 语义化颜色"] --> Provider["ThemeProvider<br/>(React Context)"]
Provider --> Base["基础组件<br/>ThemedText / ThemedBox"]
Base --> Layout["布局组件<br/>Pane / Divider / Dialog"]
Base --> Inter["交互组件<br/>Tabs / ProgressBar / FuzzyPicker"]
Layout --> ToolUI["工具 UI 协议<br/>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 类型:颜色的语义化契约
Expand Down
28 changes: 28 additions & 0 deletions docs/28-Keybindings-Vim与Voice输入.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,34 @@ voice/, services/voice*, hooks/useVoice* # 按住一个键 → 一段 PCM 流

---

## 全景图:同一条按键流被三套子系统分别解释

```mermaid
graph TB
Ink["Ink useInput<br/>(按下了哪个键)"]

Ink --> KB["keybindings/<br/>按键 → 动作 ID"]
Ink --> Vim["vim/<br/>按键序列 → 一次 vim 命令"]
Ink --> Voice["voice/ + services/voice*<br/>按住一个键 → 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 为什么这件事值得做成一个子系统?
Expand Down
30 changes: 30 additions & 0 deletions docs/29-Buddy宠物.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,36 @@ Claude Code 的答案可以一句话概括:**把"骨"和"魂"切开存,把

---

## 全景图:六个文件如何挂进五个子系统

```mermaid
graph TB
subgraph BuddyFiles["buddy/ 6 个源码文件"]
Types["types.ts<br/>物种与稀有度词典"]
Comp["companion.ts<br/>骨与魂的拆分"]
Sprites["sprites.ts<br/>18 个像素画"]
Sprite["CompanionSprite.tsx<br/>帧动画与气泡"]
Prompt["prompt.ts<br/>第三人称介绍"]
Notif["useBuddyNotification.tsx<br/>彩虹色入口提示"]
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` 这个类型被一刀切成两半:
Expand Down
Loading
Loading