# 各章节详细大纲
本文档是系列各章的**内容提纲**,用于把握每章要讲什么、要实现什么,以及和 Claude Code 源码的对应关系。
---
## 第 1 章:进程与标准 I/O
**对应源码**:`src/main.tsx`、`src/bootstrap/state.ts`、`src/entrypoints/`
**核心问题**:一个 Coding Agent 首先需要一个可以运行的进程——它从哪里读输入,往哪里写输出?
### 原理讲解
- Node.js 进程模型:事件循环、`process.stdin` / `process.stdout`
- TypeScript 在 Node.js 上的运行方式(`tsx`、`ts-node`)
- 进程退出码、信号处理(`SIGINT`、`SIGTERM`)
- Claude Code 的`bootstrap/state.ts`:全局单例,保存进程级配置(pid、session id、工作目录)
### 关键 Claude Code 代码段
```typescript
// src/bootstrap/state.ts —— 全局单例
interface State {
sessionId: string
pid: number
cwd: string
startTime: number
}
```
### 最小化产出物
`chapters/01/src/main.ts`:
```
功能:
- 读取命令行参数(--cwd, --debug)
- 初始化全局 state(sessionId / pid / 启动时间)
- 从 stdin 读一行文字并回显到 stdout
- 处理 Ctrl-C 优雅退出
验收命令:
echo "hello agent" | npx tsx src/main.ts
→ 输出:You said: hello agent
```
---
## 第 2 章:终端 UI 外壳(Ink + React)
**对应源码**:`src/ink.ts`、`src/replLauncher.tsx`、`src/components/TextInput.tsx`、`src/screens/`
**核心问题**:终端不是 Web 浏览器,但我们能在终端里用 React 吗?
### 原理讲解
- ANSI 转义码:颜色、光标移动、清屏
- Ink 的工作原理:React 组件树 → Yoga(Flexbox 布局引擎)→ 终端控制序列
- `useInput`:捕获原始键盘事件
- `useStdout`:直接写入终端输出流
- Ink 与普通 React 的区别:`<Text>`、`<Box>`、`<Static>` 等原语
### 关键 Claude Code 代码段
```typescript
// src/ink.ts —— 启动 Ink 应用
export function renderApp(component: ReactElement): Instance {
return render(component, { exitOnCtrlC: false })
}
```
### 最小化产出物
`chapters/02/src/main.tsx`:
```
功能:
- 渲染带颜色 Banner("Mini Agent")
- 底部固定输入框,支持编辑 + Enter 提交
- 提交后在历史区域追加显示(类似聊天泡泡)
- Ctrl-C / /exit 退出
验收命令:
npx tsx src/main.tsx
→ 出现交互式终端 UI,可输入文字并显示历史
```
---
## 第 3 章:CLI 命令路由
**对应源码**:`src/main.tsx`(Commander 部分)、`src/cli/`、`src/commands/version.ts`
**核心问题**:一个专业工具都支持 `--help`、子命令和参数解析,怎么做?
### 原理讲解
- Commander.js 的核心抽象:`program.command().option().action()`
- 子命令 vs 全局选项
- Claude Code 的启动模式:`claude`(REPL) vs `claude run "..."` vs `claude --print`
- 版本信息管理:从 `package.json` 读取
### 关键 Claude Code 代码段
```typescript
// src/main.tsx —— Commander 路由
const program = new Command()
program
.name('claude')
.version(VERSION)
.argument('[prompt]', 'Run with initial prompt')
.option('--print, -p', 'Print output to stdout')
.option('--cwd <dir>', 'Working directory')
.action(async (prompt, opts) => { ... })
```
### 最小化产出物
`chapters/03/src/main.ts`:
```
功能:
- claude --version → 打印版本
- claude --help → 打印帮助
- claude run "..." → 执行一次性任务(无 UI,打印到 stdout)
- claude → 无参数时启动第 2 章的交互 UI
验收命令:
npx tsx src/main.ts --version
npx tsx src/main.ts --help
npx tsx src/main.ts run "echo hello"
```
---
## 第 4 章:工具抽象与执行引擎
**对应源码**:`src/Tool.ts`、`src/tools.ts`、`src/tools/bash.ts`、`src/tools/read.ts`
**核心问题**:Agent 怎么执行真实操作?定义一套工具接口,让 LLM 能"调用"它们。
### 原理讲解
- 工具调用(Function Calling)的 JSON 协议概述
- Zod schema 作为运行时类型守卫的用法
- 工具接口的三个核心要素:名称、输入 schema、`call()` 函数
- 同步 vs 异步工具、流式工具输出
- 错误封装:工具执行失败应返回结构化错误,而不是抛出异常
### 关键 Claude Code 代码段
```typescript
// src/Tool.ts —— 工具接口(简化)
export interface Tool<Input = unknown, Output = unknown> {
name: string
description: string
input_schema: ZodSchema<Input>
call(input: Input, ctx: ToolContext): Promise<Output>
}
```
### 最小化产出物
`chapters/04/src/main.ts`:
```
功能:
实现 3 个工具并注册到工具注册表:
- BashTool:用 child_process.execSync 执行 Shell 命令
- ReadFileTool:读取文件内容
- WriteFileTool:写入文件内容
提供 callTool(name, input) 函数统一调用
验收命令:
npx tsx src/main.ts
→ 演示调用 BashTool("ls -la") 并打印结果
→ 演示调用 ReadFileTool("./src/main.ts") 并打印内容
```
---
## 第 5 章:LLM API 客户端(流式)
**对应源码**:`src/services/api/claude.ts`、`src/services/api/promptCacheBreakDetection.ts`、`src/query/`、`src/utils/thinking.ts`
**核心问题**:怎么和 Claude 对话?怎么处理流式响应?怎么让 LLM "深度思考"?怎么用缓存把成本降低 90%?
### 原理讲解
- Anthropic Messages API 的消息格式:`role`、`content`、`model`
- 流式 SSE 响应:`message_start` → `content_block_start` → `content_block_delta` → `stop`
- `tool_use` 块的流式重组:delta 累积 → JSON.parse
- Token 计数与成本估算(input_tokens × $X / 1M)
- 错误处理:限速、超时、网络错误的重试策略
### 特性 A:Prompt Caching(提示词缓存)
**对应源码**:`src/services/api/claude.ts`(`getPromptCachingEnabled`)、`src/services/api/promptCacheBreakDetection.ts`
- **原理**:对 System Prompt 和工具列表末尾注入 `cache_control: { type: "ephemeral" }` 标记,让 Anthropic 服务端缓存这部分 token。后续请求中命中缓存的 token 费率降低约 90%。
- **两种 TTL**:5 分钟(默认)和 1 小时(`ENABLE_PROMPT_CACHING_1H`)
- **两种缓存策略**:
- `tool_based`:在工具列表最后一个工具处插入 breakpoint(工具多时用)
- `system_prompt`:在 System Prompt 末尾插入 breakpoint(工具少时用)
- **缓存破坏检测**(700+ 行独立模块):逐 turn 对比 system hash / tool hash / model / betas,检测到不必要的缓存 break 时写入诊断日志
```typescript
// 在 system prompt 末尾注入 cache_control
const systemBlocks = [
{ type: 'text', text: systemPrompt,
cache_control: { type: 'ephemeral' } } // ← 缓存断点
]
```
### 特性 B:扩展思考(Extended Thinking / Ultrathink)
**对应源码**:`src/utils/thinking.ts`
- 在 API 请求中加入 `thinking: { type: 'enabled', budget_tokens: N }` 参数,让模型生成内部推理 token(CoT),提高复杂任务的回答质量
- 用户输入中含 `ultrathink` 关键词时自动启用最大 thinking budget
- 三种配置:`adaptive`(模型自决)、`enabled`(固定 budget)、`disabled`
```typescript
// src/utils/thinking.ts
type ThinkingConfig =
| { type: 'adaptive' }
| { type: 'enabled'; budgetTokens: number }
| { type: 'disabled' }
```
### 关键 Claude Code 代码段
```typescript
// src/services/api/claude.ts —— 流式调用(含 caching + thinking)
const stream = client.messages.stream({
model: 'claude-opus-4-5',
max_tokens: 4096,
messages,
tools: toolSchemas,
system: systemBlocksWithCacheControl, // 带 cache_control
thinking: thinkingConfig, // 扩展思考
})
for await (const event of stream) {
// event.type: 'content_block_delta' | 'message_stop' | …
}
```
### 最小化产出物
`chapters/05/src/main.ts`:
```
功能:
- 接收一条用户消息
- 调用 Claude API(需要 ANTHROPIC_API_KEY 环境变量)
- 实时将 token 打印到 stdout(流式)
- 对 system prompt 注入 cache_control,第二次调用展示缓存节省
- 消息中含 "ultrathink" 时启用 extended thinking
- 打印本次调用的 token 消耗(含 cache_read_input_tokens)和美元成本
验收命令:
ANTHROPIC_API_KEY=sk-... npx tsx src/main.ts "写一首关于代码的短诗"
→ 流式打印诗歌,结尾打印 "tokens: 123 (cache_read: 89) / cost: $0.0001"
(第二次调用时 cache_read 数字变大,cost 下降)
```
---
## 第 6 章:消息循环与对话管理
**对应源码**:`src/history.ts`、`src/assistant/sessionHistory.ts`、`src/services/compact/`
**核心问题**:多轮对话如何维护上下文?消息历史应该怎么存储和裁剪?上下文快满时怎么办?
### 原理讲解
- Anthropic API 的 `messages` 数组:每轮都要带全历史
- 消息类型:`user`、`assistant`(含 `text` 和 `tool_use`/`tool_result` 子块)
- 上下文窗口限制:token 预算管理
- 会话内 vs 会话间历史的区别
### 特性:对话压缩(Compaction)
**对应源码**:`src/services/compact/compact.ts`、`microCompact.ts`、`autoCompact.ts`
Claude Code 使用**三种压缩策略**,而不是简单的滑动窗口截断:
| 策略 | 触发方式 | 实现原理 |
|------|---------|---------|
| **Full Compaction** | 手动 `/compact` 或临近 token 上限 | 启动 forked sub-agent 生成整段摘要,替换全部旧历史 |
| **Micro Compaction** | 自动(FileRead 缓存桩检测) | 原地删除 FileRead "文件未变化" 占位消息,无需 LLM |
| **Auto Compaction** | 接近 token 上限时自动 | 后台触发 Full Compaction,主对话继续不中断 |
关键细节:
- 压缩由 **forked sub-agent** 完成(独立的 Agentic Loop,不消耗主 agent 上下文)
- 压缩会破坏 Prompt Cache → 通过 `notifyCompaction()` 通知缓存模块重置 hash 基线
- Pre/Post Compact Hooks 可拦截压缩过程(第 8 章 Hooks)
```typescript
// src/services/compact/compact.ts —— 压缩触发
async function runCompaction(messages: Message[]): Promise<Message[]> {
await executePreCompactHooks() // 钩子
const summary = await runForkedAgent(COMPACT_PROMPT, messages)
notifyCompaction() // 重置缓存基线
return [createSummaryMessage(summary)]
}
```
### 关键 Claude Code 代码段
```typescript
// src/assistant/sessionHistory.ts
type Message = {
role: 'user' | 'assistant'
content: ContentBlock[]
}
// ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock
```
### 最小化产出物
`chapters/06/src/main.ts`:
```
功能:
- 维护一个 messages[] 数组,支持多轮对话
- 实现简化版 Full Compaction:当历史超过阈值时,调用 LLM 生成摘要替换旧历史
- /compact 命令手动触发压缩
- /clear 命令清空历史重新开始
验收命令:
npx tsx src/main.ts
→ 可进行多轮对话,输入 /compact 后历史被摘要压缩,但 Claude 仍记得核心内容
```
---
## 第 7 章:工具调用循环(Agentic Loop)
**对应源码**:`src/QueryEngine.ts`、`src/query.ts`
**核心问题**:怎么让 LLM 反复调用工具,直到任务完成?
### 原理讲解
- Agentic Loop 的状态机:`text → tool_use → tool_result → text → ...`
- `stop_reason: "tool_use"` vs `"end_turn"` 的处理逻辑
- 并行工具调用:同一轮 LLM 响应可能包含多个 `tool_use`
- 循环终止条件:`end_turn`、`max_iterations`、特定信号字符串
- 错误恢复:工具失败时如何向 LLM 反馈
### 关键 Claude Code 代码段
```typescript
// src/QueryEngine.ts —— 核心循环(简化)
while (true) {
const response = await callLLM(messages, tools)
messages.push({ role: 'assistant', content: response.content })
if (response.stop_reason === 'end_turn') break
if (response.stop_reason === 'tool_use') {
const results = await executeTools(response.content)
messages.push({ role: 'user', content: results })
}
}
```
### 最小化产出物
`chapters/07/src/main.ts`:
```
功能:
将第 4、5、6 章产出物组合:
- 给 LLM 注册 BashTool、ReadFileTool、WriteFileTool
- 实现完整 Agentic Loop
- 当 LLM 想调用工具时执行它,并将结果反馈
- 循环直到 LLM 完成任务(stop_reason = end_turn)
验收命令:
npx tsx src/main.ts "列出当前目录下的所有 .ts 文件"
→ Claude 自主调用 BashTool("find . -name '*.ts'") 并给出结果
```
---
## 第 8 章:权限与安全仲裁
**对应源码**:`src/types/permissions.ts`、`src/utils/permissions/`、`src/utils/hooks/`、`src/utils/hooks.ts`
**核心问题**:Agent 有了"手",如何防止它做危险操作?如何让用户在每个节点插入自定义逻辑?
### 原理讲解(权限模式)
- 为什么需要权限系统:Agent 能执行 Shell,意味着能删库、能 `rm -rf /`
- Claude Code 的 7 种权限模式:
- `default`:不确定时询问用户
- `acceptEdits`:自动批准文件编辑
- `bypassPermissions`:跳过所有检查(仅 CI 环境)
- `plan`:只分析,不执行
- `auto`:自动批准安全操作
- `dontAsk`:永远不询问(危险)
- `bubble`:将权限决策转发给父级
- 规则来源优先级:CLI > 会话规则 > 企业策略 > 项目规则 > 用户偏好 > 默认
- 白名单/黑名单:允许的命令前缀列表
### 特性:Hooks 系统(生命周期钩子)
**对应源码**:`src/utils/hooks/`、`src/entrypoints/sdk/coreTypes.ts`
**Hooks 是 Claude Code 最强大的扩展点**:在 Agent 执行的任意节点注入自定义 Shell 命令或 HTTP 请求。
**27 个生命周期事件**(部分):
| 事件 | 触发时机 | 是否可阻塞 |
|------|---------|-----------|
| `PreToolUse` | 工具执行前 | ✅ 可拒绝工具调用 |
| `PostToolUse` | 工具执行后 | ❌ |
| `PostToolUseFailure` | 工具执行失败后 | ❌ |
| `UserPromptSubmit` | 用户提交消息时 | ✅ 可修改/拦截 |
| `Stop` / `SubagentStop` | Agent 完成时 | ❌ |
| `PreCompact` / `PostCompact` | 对话压缩前后 | ✅ / ❌ |
| `SessionStart` / `SessionEnd` | 会话开始/结束 | ❌ |
| `WorktreeCreate` / `WorktreeRemove` | Git worktree 操作时 | ❌ |
| `PermissionRequest` / `PermissionDenied` | 权限决策时 | ❌ |
| `InstructionsLoaded` | CLAUDE.md 加载后 | ❌ |
| `CwdChanged` / `FileChanged` | 目录/文件变化时 | ❌ |
**配置方式**(`~/.claude/settings.json`):
```json
{
"hooks": {
"PreToolUse": [{
"matcher": { "tool_name": "Bash" },
"hooks": [{ "type": "command", "command": "./audit-log.sh" }]
}],
"Stop": [{
"hooks": [{ "type": "command", "command": "notify-send 'Agent done'" }]
}]
}
}
```
**三种 hook 类型**:
- `command`:执行 Shell 命令(stdout 可反馈给 Agent)
- `http`:POST 到 HTTP 端点(含 SSRF 防护,`src/utils/hooks/ssrfGuard.ts`)
- `function`:程序内注册的回调(SDK 使用)
### 关键 Claude Code 代码段
```typescript
// src/types/permissions.ts
type PermissionMode =
| 'default' | 'acceptEdits' | 'bypassPermissions'
| 'plan' | 'auto' | 'dontAsk' | 'bubble'
type PermissionResult =
| { behavior: 'allow' }
| { behavior: 'deny', reason: string }
| { behavior: 'ask', message: string }
// src/entrypoints/sdk/coreTypes.ts
export const HOOK_EVENTS = [
'PreToolUse', 'PostToolUse', 'PostToolUseFailure',
'UserPromptSubmit', 'Stop', 'SubagentStop',
'PreCompact', 'PostCompact', 'SessionStart', 'SessionEnd',
// … 共 27 个
] as const
```
### 最小化产出物
`chapters/08/src/main.ts`:
```
功能:
在第 7 章 Agentic Loop 中插入权限检查 + hooks:
- 读取操作(ReadFile):自动允许
- 写入操作(WriteFile):询问用户 [y/n]
- Shell 执行(Bash):
- 安全白名单(ls/cat/echo):自动允许
- 危险命令(rm/sudo/curl):要求用户确认
- --auto 标志:跳过所有询问
- Hooks:从 .mini-agent/settings.json 读取 hooks 配置,
在工具执行前后调用配置的 shell 命令(PreToolUse / Stop)
验收命令:
npx tsx src/main.ts "删除 /tmp/test.txt"
→ 提示 "Run: rm /tmp/test.txt ? [y/n]" 等待确认
(配置 PreToolUse hook 后,每次工具调用前先运行指定脚本)
```
---
## 第 9 章:上下文注入(System Prompt)
**对应源码**:`src/context.ts`、`src/context/`、`src/setup.ts`
**核心问题**:LLM 默认不了解你的项目,如何让它感知当前代码库?
### 原理讲解
- System Prompt 的作用:给 LLM 一个持久的"角色设定"和背景知识
- `CLAUDE.md`:项目级别的持久化上下文文件
- 动态上下文构建:工作目录、git branch/log、文件树摘要
- 上下文 Token 预算:System Prompt 越长,留给对话的空间越少
- Claude Code 的多层上下文:用户级 `~/.claude/CLAUDE.md` + 项目级 `./CLAUDE.md`
### 关键 Claude Code 代码段
```typescript
// src/context.ts —— system prompt 构建
async function buildSystemPrompt(cwd: string): Promise<string> {
const claudeMd = await readClaudeMd(cwd)
const gitContext = await getGitContext(cwd)
const fileTree = await getFileTree(cwd, { depth: 2 })
return [AGENT_IDENTITY, claudeMd, gitContext, fileTree].join('\n\n')
}
```
### 最小化产出物
`chapters/09/src/main.ts`:
```
功能:
构建动态 System Prompt:
- 读取 ./CLAUDE.md(不存在则忽略)
- 读取 git log --oneline -10(不在 git 仓库内则跳过)
- 读取目录树(深度 2,过滤 node_modules/.git)
- 将以上内容构成 system prompt 传入对话
验收命令:
echo "# CLAUDE.md\n这是一个 TypeScript 电商系统" > CLAUDE.md
npx tsx src/main.ts "这个项目是做什么的?"
→ Claude 准确回答"这是一个 TypeScript 电商系统",而不是"我不知道项目详情"
```
---
## 第 10 章:记忆系统与文件历史
**对应源码**:`src/memdir/`、`src/services/extractMemories/`、`src/services/autoDream/`、`src/utils/fileHistory.ts`
**核心问题**:对话结束后知识就消失了?文件改错了想还原?Agent 需要跨会话记忆能力和文件级时光机。
### 原理讲解(记忆系统)
- 记忆 vs 历史:历史是完整对话记录(JSONL),记忆是 Agent 主动提炼的**结构化知识摘要**
- 三层记忆结构:个人记忆(`~/.claude/MEMORY.md`) → 项目记忆(`.claude/MEMORY.md`) → 团队记忆(`.claude/team-memory/`)
- 显式写入:Agent 调用 `save_memory` 工具主动记录
- 自动提炼(`extractMemories.ts`):每轮对话结束时,fork 子 Agent 检查本轮是否有值得记忆的新知识,有则写入
### 特性:autoDream(后台记忆整合)
**对应源码**:`src/services/autoDream/`
类似 cron 的后台任务,满足两个门控后自动触发,将分散的会话记忆整合去重:
```
条件判断(从便宜到昂贵):
1. 时间门:距上次整合 >= minHours?
2. 会话计数门:新会话数 >= minSessions?
3. 锁门:无其他进程正在整合?
→ 全部通过才启动 forked sub-agent 运行 /dream 提示词
```
### 特性:文件历史检查点(File History Checkpointing)
**对应源码**:`src/utils/fileHistory.ts`
每条用户消息发送前,自动为所有被追踪文件创建快照——**默认对所有用户开启**:
- 使用**硬链接**(`link()`)节省磁盘空间,最多保留 100 个快照(FIFO 淘汰)
- 每个快照与 `messageId: UUID` 绑定
- `--rewind-files <uuid>`:将工作区还原到该消息时刻的磁盘状态
```
~/.claude/projects/<hash>/<session>/
file-history/
1.main.ts 2.main.ts … ← 每个版本一个硬链接备份
checkpoints.json ← 快照索引(messageId → version)
```
> **与 `/rewind` 命令的区别**:`/rewind` 截断**对话历史**(消息分支),`--rewind-files` 还原**磁盘文件内容**,两者互补。
### 关键 Claude Code 代码段
```typescript
// src/memdir/memdir.ts
export const ENTRYPOINT_NAME = 'MEMORY.md'
// src/utils/fileHistory.ts
export function fileHistoryEnabled(): boolean {
return getGlobalConfig().fileCheckpointingEnabled !== false
&& !isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_FILE_CHECKPOINTING)
}
```
### 最小化产出物
`chapters/10/src/main.ts`:
```
功能(两个子功能):
A. 跨会话记忆:
- 工具注册表中加入 save_memory(content) 工具
- Agent 调用时追加写入 ./MEMORY.md
- 每次启动将 MEMORY.md 注入 System Prompt
B. 文件历史检查点:
- 每轮用户消息到来前,对项目目录做 snapshot(复制改动文件)
- 记录 snapshot 索引文件 .checkpoints.json
- 命令行加 --rewind <snapshot-id> 可还原文件
验收命令:
npx tsx src/main.ts "记住:我们项目使用 4 空格缩进"
→ Claude 调用 save_memory,写入 MEMORY.md
npx tsx src/main.ts "我们的缩进规范是什么?" # 全新会话
→ Claude 读取 MEMORY.md,正确回答"4 空格缩进"
npx tsx src/main.ts "把 main.ts 第 1 行改为 // hello"
→ Agent 修改文件,记录 checkpoint
npx tsx src/main.ts --rewind <checkpoint-id>
→ main.ts 第 1 行恢复原样
```
---
## 第 11 章:会话持久化与历史回放
**对应源码**:`src/projectOnboardingState.ts`、`src/history.ts`、`~/.claude/projects/`
**核心问题**:每次关闭终端就丢失对话?会话应该能保存和恢复。
### 原理讲解
- 会话 ID(UUID):每个会话的唯一标识
- 存储格式:JSONL(每行一个消息对象),便于追加写入
- 恢复策略:最近 K 条消息 vs 完整历史
- Claude Code 的存储路径:`~/.claude/projects/<project-hash>/<session-id>.jsonl`
- 会话元数据:创建时间、最后活跃、工作目录、消息数
### 关键 Claude Code 代码段
```typescript
// 存储路径构造
const sessionPath = path.join(
os.homedir(), '.claude', 'projects',
hashPath(cwd),
`${sessionId}.jsonl`
)
// 每次新消息追加写入
fs.appendFileSync(sessionPath, JSON.stringify(message) + '\n')
```
### 最小化产出物
`chapters/11/src/main.ts`:
```
功能:
- 每次启动新建 session ID,消息实时追加到 ~/.mini-agent/<id>.jsonl
- --resume <id>:加载历史消息,继续上次对话
- --list:列出所有历史会话(id、时间、第一条消息摘要)
验收命令:
npx tsx src/main.ts # 开始新对话,记住打印的 session ID
npx tsx src/main.ts --resume <id> # 恢复上次对话,Claude 记得上次说的话
```
---
## 第 12 章:斜杠命令与 Skills 系统
**对应源码**:`src/commands.ts`、`src/commands/` 目录、`src/skills/`、`src/skills/loadSkillsDir.ts`
**核心问题**:用户需要控制 Agent 行为;高级用户需要用 Markdown 文件定义可复用的自定义命令,而不用写 TypeScript。
### 原理讲解(斜杠命令)
- 斜杠命令 vs 普通消息:输入以 `/` 开头时触发内部命令,不发给 LLM
- 命令注册表模式:每个命令是 `{ name, description, handler }` 对象
- 参数解析:`/compact 10` → name=compact, args=["10"]
- 内置命令举例:`/help`、`/clear`、`/cost`、`/compact`、`/exit`
### 特性:Skills 系统(Markdown 驱动的自定义命令)
**对应源码**:`src/skills/loadSkillsDir.ts`、`src/skills/bundledSkills.ts`、`src/tools/SkillTool/`
用户在 `~/.claude/skills/` 或 `.claude/skills/` 放置 Markdown 文件,自动加载为 `/skill-name` 命令。
**Skill 文件格式**(YAML frontmatter + Markdown 正文):
```markdown
---
name: review-pr
description: 审查当前分支的 PR 改动,给出评审意见
whenToUse: 当用户要求 code review 时
tools: [Bash, FileRead, GrepTool]
effort: high
---
请按以下步骤审查 PR:
1. 运行 `git diff main` 获取改动
2. 逐文件分析改动的正确性和可读性
3. 用中文给出具体的评审意见
```
**加载优先级**(低 → 高,高优先级可覆盖同名命令):
```
bundled(内置)< user(~/.claude/skills/)< project(.claude/skills/)< plugin < managed
```
**MCP Skill**(`src/skills/mcpSkillBuilders.ts`):MCP Server 也可以注册 Skill,动态扩展命令列表。
### 关键 Claude Code 代码段
```typescript
// src/commands.ts —— 命令注册
const COMMANDS: Command[] = [
{
name: 'clear',
description: 'Clear conversation history',
handler: async (args, ctx) => { ctx.clearHistory(); return 'History cleared.' }
},
]
// src/skills/loadSkillsDir.ts —— Skill 来源类型
export type LoadedFrom =
| 'bundled' | 'skills' | 'plugin' | 'managed' | 'mcp'
```
### 最小化产出物
`chapters/12/src/main.ts`:
```
功能:
斜杠命令:/help /clear /cost /resume <id> /exit
Skills 加载:
- 扫描 ./.mini-agent/skills/ 目录下的 .md 文件
- 解析 frontmatter(name/description/whenToUse)
- 将 skill 注册为 /skill-name 命令
- 调用时将 Markdown 正文插入为临时 system prompt(附加到基础 prompt 后)
验收命令:
# 创建 .mini-agent/skills/greet.md(含 name: greet 的 frontmatter)
npx tsx src/main.ts
输入 /help → 列表中出现 /greet(来自 Skill 文件)
输入 /greet → Claude 按 skill 文件中的指令执行
```
---
## 第 13 章:多 Agent 与任务调度
**对应源码**:`src/Task.ts`、`src/tasks/`、`src/coordinator/`、`src/tools/agent.ts`
**核心问题**:一个 Agent 不够用?怎么让父 Agent 分派子 Agent 并行完成子任务?
### 原理讲解
- 任务抽象:每个 `Task` 有 id、类型、状态(pending/running/done/failed)、结果
- Agent as Tool:`AgentTool` 是一个特殊工具,调用后会启动一个新的 Agentic Loop
- 父子 Agent 通信:父 Agent 通过工具调用传入"任务描述",通过 `tool_result` 接收子 Agent 的结果
- 并行 vs 串行:多个 `tool_use` 在同一个 LLM 响应中 → 并行执行
- 循环检测:防止 Agent 无限递归调用
### 关键 Claude Code 代码段
```typescript
// src/Task.ts —— 任务状态机
type TaskStatus = 'pending' | 'running' | 'done' | 'failed' | 'cancelled'
interface Task {
id: string
type: 'local_bash' | 'local_agent' | 'remote_agent'
status: TaskStatus
input: unknown
result?: unknown
}
```
### 最小化产出物
`chapters/13/src/main.ts`:
```
功能:
实现 AgentTool,使父 Agent 可以派生子 Agent:
- 父 Agent 收到复杂任务时,调用 AgentTool(task_description)
- AgentTool 启动一个独立的 Agentic Loop(带自己的 messages[])
- 子 Agent 完成后将结果字符串返回给父 Agent
- 父 Agent 基于子结果继续工作
验收命令:
npx tsx src/main.ts "将 src/ 目录下所有 .ts 文件分类,并为每类写一句描述"
→ 父 Agent 派生多个子 Agent 分别分析不同文件,汇总结果
```
---
## 第 14 章:插件与 MCP 集成
**对应源码**:`src/plugins/`、`src/services/`(MCP 相关)
**核心问题**:内置工具有限,如何让用户扩展 Agent 的能力?
### 原理讲解
- MCP(Model Context Protocol):Anthropic 定义的标准工具服务协议
- MCP Server:一个独立进程,通过 stdio 或 HTTP 暴露工具接口
- MCP Client:Agent 端,通过协议发现并调用 MCP Server 暴露的工具
- 插件加载:从配置文件(`~/.claude/settings.json`)读取 MCP server 列表,启动并连接
- 工具名称空间:MCP 工具以 `server_name__tool_name` 为前缀,避免冲突
### 关键 Claude Code 代码段
```typescript
// 配置文件格式(~/.claude/settings.json)
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "..." }
}
}
}
```
### 最小化产出物
`chapters/14/src/main.ts`:
```
功能:
- 读取 ~/.mini-agent/settings.json 中的 mcpServers 配置
- 启动配置的 MCP server 子进程
- 通过 MCP 协议(stdio)发现其暴露的工具列表
- 将 MCP 工具注册到工具注册表,可被 LLM 调用
验收命令:
配置一个本地 MCP test server 后:
npx tsx src/main.ts "用 echo_tool 说 hello"
→ LLM 调用 mcp_test__echo_tool 并返回结果
```
---
## 第 15 章:完整 Coding Agent 集成
**对应源码**:贯穿全部
**核心问题**:把所有层组合在一起,得到一个真正可用的 Coding Agent。
### 原理讲解
- 启动顺序:配置加载 → 插件初始化 → 上下文构建 → UI 启动
- 错误边界:任何层的错误都不能崩溃整个 Agent
- 优雅退出:Ctrl-C → 停止所有子进程 → 写入会话档案 → 退出
- 一次性模式(`--print`)vs 交互模式(REPL)
### 最小化产出物
`chapters/15/src/main.ts`:
```
功能(整合第 1-14 章所有产出物):
- 完整的 Ink 终端 UI(第 2 章)
- Commander CLI 路由(第 3 章)
- 工具注册表(第 4 章 + 第 14 章 MCP 工具)
- 流式 LLM 客户端(第 5 章)
- 多轮对话管理(第 6 章)
- 完整 Agentic Loop(第 7 章)
- 权限仲裁层(第 8 章)
- 动态上下文注入(第 9 章)
- 记忆系统 + 文件历史(第 10 章)
- 会话持久化(第 11 章)
- 斜杠命令系统(第 12 章)
- 多 Agent 调度(第 13 章)
验收任务:
cd /some/real/project
npx tsx src/main.ts "找出项目中所有 TODO 注释,为每个 TODO 创建一个 issue 描述文件"
→ Agent 自主完成整个任务,期间调用多个工具,最终输出结果文件
```
---
## 第 16 章:后台智能框架(forked Agent 模式)
**对应源码**:`src/utils/forkedAgent.ts`、`src/services/MagicDocs/`、`src/services/awaySummary.ts`、`src/services/PromptSuggestion/speculation.ts`、`src/services/autoDream/`
**核心问题**:Agent 能否在用户等待时主动做有益的事?如何让主对话不被后台任务阻塞?
### 原理讲解
所有后台智能特性共享同一个设计模式——**forked Agent**:
```
主对话完成一轮
↓
postSamplingHook 触发
↓
runForkedAgent(cacheSafeParams) ← 共享父 Agent 的 prompt cache
↓ (异步、不阻塞主线程)
子 Agent 执行后台任务
↓
修改状态/文件(不通过工具反馈给用户)
```
**Cache 共享的关键**:`createCacheSafeParams()` 将 messages + tools 序列化为与父 Agent 完全相同的格式,子 Agent 的首次 API 请求命中父 Agent 已缓存的 prompt prefix,**zero cold-start 成本**。
### Claude Code 中的四个实例
| 系统 | 触发条件 | 后台任务 |
|------|----------|---------|
| **extractMemories** | 每轮最终响应后 | 检测本轮是否有值得记忆的内容,有则写入 MEMORY.md |
| **autoDream** | 时间门 + 会话数门(后台定期检查) | 整合最近 N 个会话的记忆,去重后写入 MEMORY.md |
| **Magic Docs** | FileReadTool 读取含 `# MAGIC DOC:` 头的文件后 | fork 子 Agent 根据当前对话更新该文档内容 |
| **Speculation** | 主 Agent 响应完毕,用户开始输入时 | 根据预测输入提前执行只读工具(Glob/Grep/LSP),命中则节省 TTFT |
### Away Summary(返回摘要)
用户离开再回来时,用小模型生成 1-3 句"离开时的进展",不消耗主对话 Token:
```typescript
// src/services/awaySummary.ts
const recent = messages.slice(-RECENT_MESSAGE_WINDOW) // 最近 30 条
recent.push(createUserMessage({ content: buildAwaySummaryPrompt(memory) }))
await queryModelWithoutStreaming({ model: getSmallFastModel(), ... })
```
### 关键 Claude Code 代码段
```typescript
// src/utils/forkedAgent.ts —— 核心入口
export async function runForkedAgent(
params: CacheSafeParams,
userMessage: string,
options: { canUseTool: CanUseToolFn; signal: AbortSignal },
): Promise<void>
// src/utils/hooks/postSamplingHooks.ts
export function registerPostSamplingHook(
fn: (ctx: REPLHookContext) => Promise<void>
): void
```
### 最小化产出物
`chapters/16/src/main.ts`:
```
功能:
实现 forked Agent 框架,演示两个使用场景:
场景 A —— 对话后提炼记忆:
- 每轮对话结束后,fork 子 Agent
- 子 Agent 判断主对话中是否出现新的"应记住的事实"
- 有则追加写入 MEMORY.md(父 Agent 下轮自动注入)
场景 B —— Magic Doc 自动更新:
- 创建 ARCHITECTURE.md,首行写 # MAGIC DOC: Architecture
- Agent 读取该文件后自动触发 fork
- 子 Agent 根据最近对话上下文更新文档内容
验收命令:
# 场景 A
npx tsx src/main.ts "我们项目采用六边形架构,数据库用 PostgreSQL"
cat MEMORY.md → 自动写入了架构约定
# 场景 B
npx tsx src/main.ts "解释一下我们的认证流程"
cat ARCHITECTURE.md → 文件内容已根据对话内容自动更新
```
> **第 16 章是"进阶选修"**:主线路 15 章已经构建出完整的 Coding Agent;第 16 章展示如何让 Agent 从"使用工具"进化到"后台持续学习"。
---
## 附录章:Claude Code 功能全景(不在主线课程中)
> 以下特性在 Claude Code 源码中真实存在,但属于**进阶/专项功能**,超出"从零构建基础 Coding Agent"的主线范围。
> 每项均列出源码位置,供感兴趣的读者自行探索。
---
### 附录分组概览
| 组别 | 条目 | 主题 |
|------|------|------|
| **I. 智能分层基础设施** | A–D | Bridge/IDE远控、Computer Use、Git Worktree、多Agent树 |
| **II. 后台智能与持续学习** | II-A–II-E | Magic Docs、Away摘要、Speculation预测、Settings/Team Memory同步、Commit Attribution |
| **III. 运行时安全与治理** | E–J | LSP实时诊断、OAuth、MDM企业策略 |
| **IV. 自动化与调度** | F–M(原序)| Cron调度、Todo跟踪、Plan Mode V2、ultraplan关键词 |
| **V. 工作区扩展** | J–V(原序)| Sandbox隔离、Teleport云端、Rewind回溯、Effort/Fast模式 |
| **VI. 用户体验与彩蛋** | N–Z | Buddy虚拟伴侣、Voice/Vim、截图导出、Mobile/Chrome集成、彩蛋命令 |
| **VII. 测试基础设施与内部机制** | VII-A–VII-E | VCR录制回放、Tips系统、Grove数据治理、Referral邀请、Agent进度摘要 |
---
**── I. 智能分层基础设施 ──**
### A. Bridge / IDE 远程控制
**源码**:`src/bridge/`(40+ 文件)
Claude Code 可被 IDE(如 VS Code、JetBrains)以 WebSocket 协议远程控制:
- IDE 发送命令 → Claude Code 执行 → 实时回传消息流和权限请求
- 双向认证(JWT + work secret)
- 消息缓冲与重连机制(`replBridgeTransport.ts`、`flushGate.ts`)
- 权限代理:IDE 代替终端展示权限确认对话框(`bridgePermissionCallbacks.ts`)
### B. Computer Use(桌面自动化)
**源码**:`src/utils/computerUse/`
通过截图 + 模拟鼠标/键盘事件控制桌面应用:
- 截图工具(macOS 原生)、点击/拖拽/输入模拟
- 与 MCP Server 集成(`computerUse/mcpServer.ts`)
- 需要辅助功能权限,有专门的"Computer Use Lock"防止并发
### C. Git Worktree 并行分支
**源码**:`src/utils/worktree.ts`、`src/tools/EnterWorktreeTool/`、`src/tools/ExitWorktreeTool/`
允许 Agent 在不同 git worktree 中并行工作:
- `EnterWorktreeTool`:创建新 worktree,切换到隔离分支
- `ExitWorktreeTool`:完成工作后合并回主分支
- Worktree 生命周期 Hooks(`WorktreeCreate` / `WorktreeRemove`)
### D. Team / Swarm 模式(多 Agent 树)
**源码**:`src/utils/swarm/`、`src/tools/TeamCreateTool/`、`src/tools/SendMessageTool/`
多个 Claude 实例组成树形结构协同工作:
- Leader Agent 创建 Agent 团队(`TeamCreateTool`)
- 通过 `SendMessageTool` 在 Agent 之间传递消息
- 权限同步:子 Agent 的权限从 Leader 同步(`leaderPermissionBridge.ts`)
- 布局管理:多个 Agent 的输出分区显示(`teammateLayoutManager.ts`)
**Coordinator Mode**(独立协调者,与 Swarm 不同):
`CLAUDE_CODE_COORDINATOR_MODE=1` 启用——主模型**只**使用 `TeamCreateTool`/`TeamDeleteTool`/`SendMessageTool` 等管理工具,本身不直接执行文件操作;功能分离比 Swarm 更严格。
---
**── II. 后台智能与持续学习 ──**
### II-A. Magic Docs(自动维护文档)
**源码**:`src/services/MagicDocs/magicDocs.ts`
在 Markdown 文件首行写 `# MAGIC DOC: [标题]` 即可让该文件成为"自我更新文档":
**触发机制**:
- `FileReadTool` 读取文件时,`registerFileReadListener` 检测 MAGIC DOC 头
- 每次主循环产生最终响应(无工具调用)后,`registerPostSamplingHook` 触发后台检查
- 满足条件则用 `runForkedAgent()` 派生 subagent 执行更新任务
**更新规则**:
- subagent 拥有读/写权限(`FILE_EDIT_TOOL_NAME` + `FileReadTool`)
- 用 `buildMagicDocsUpdatePrompt()` 构建提示词,内容包含当前对话上下文
- 每个文件用 `sequential()` 串行更新,防止并发冲突
**典型用途**:维护 `ARCHITECTURE.md`、`API.md` 等随开发同步更新的活文档。
### II-B. Away Summary(离开摘要)
**源码**:`src/services/awaySummary.ts`
用户回来时(如重新聚焦终端),展示 1-3 句"您离开时的进展"卡片:
- 使用 `getSmallFastModel()`(Haiku 级)生成,避免阻塞
- 输入:最近 `RECENT_MESSAGE_WINDOW = 30` 条消息 + Session Memory 内容
- Prompt 要求:**高层任务描述**(在做什么)+ **具体下一步**;禁止状态报告和 commit 摘要
- 离开超过阈值时间后首次输入时触发
### II-C. Prompt Suggestion + Speculation(预测执行)
**源码**:`src/services/PromptSuggestion/promptSuggestion.ts`、`speculation.ts`
两层"预测"机制,在用户等待响应时提前计算下一步:
**Prompt Suggestion**:
- 主 Agent 响应后,立即用 forked agent 预测"用户下一条消息"
- 预测结果作为输入框建议显示(`tengu_chomp_inflection` 特性门控)
- 若用户实际输入与预测高度相似,则直接使用预计算的上下文
**Speculation(推测执行)**:
- 在用户**实际发送**前,根据预测输入提前运行只读工具(`SAFE_READ_ONLY_TOOLS`:Read/Glob/Grep/LSP/TaskList)
- 结果写入临时 overlay 目录(`getOverlayPath(id)`)
- 用户确认发送后,将 overlay 中的文件读取结果合并到真实 messages——**节省 TTFT**
- 若预测失败(实际输入不匹配),丢弃 overlay 重新执行(`safeRemoveOverlay`)
- 最多 `MAX_SPECULATION_TURNS = 20` 轮、`MAX_SPECULATION_MESSAGES = 100` 条
### II-D. Settings Sync + Team Memory Sync(设置与团队记忆同步)
**源码**:`src/services/settingsSync/`、`src/services/teamMemorySync/`
**Settings Sync**(`feature('UPLOAD_USER_SETTINGS')` / `'DOWNLOAD_USER_SETTINGS'`):
- 交互 CLI:将本地 settings 增量上传(只上传变更的 key)到 Anthropic API
- CCR(Cloud Code Runner)下载:在插件安装前先拉取远程 settings
**Team Memory Sync**(`feature('TEAMMEM')`):
- 按 git remote URL 哈希识别仓库,同一组织成员共享该仓库的 `team-memory/`
- **Delta 上传**:比对 `serverChecksums`,只传内容已变更的 key
- **拉取语义**:服务端内容覆盖本地(server wins);本地删除文件不会同步到服务端
- **Secret Scanner**(`teamMemSecretGuard.ts`):上传前用 gitleaks 高置信度规则扫描:Anthropic API key、AWS access token、GitHub PAT、GCP service account key、Slack token 等,发现密钥则拒绝上传并提示
**Watcher**:`watcher.ts` 监听 `team-memory/` 目录文件变化,自动触发上传(带防抖)
### II-E. Commit Attribution(提交归因)
**源码**:`src/utils/commitAttribution.ts`,由 `feature('COMMIT_ATTRIBUTION')` 门控
追踪哪些 git 提交中的哪些行是由 Claude Code 生成的:
- 每次工具调用修改/创建文件后,记录 `AttributionSnapshot`(文件 → 行范围 → session ID)
- `git commit` 时在 commit message 尾部添加 trailer:
```
Claude-Code-Session: <session-id>
```
- **内部仓库**(`INTERNAL_MODEL_REPOS` allowlist 中的私有 Anthropic 仓库)额外记录模型名:
```
Claude-Code-Model: <internal-codename>
```
- 公开仓库(如 `anthropics/claude-code` 本身)保持"undercover 模式",不暴露内部代号
- `calculateCommitAttribution()` 计算归因分数(AI 生成比例)
---
**── III. 运行时安全与治理 ──**
### E. LSP 集成(实时代码诊断)
**源码**:`src/services/lsp/`
与 Language Server Protocol 集成,获取实时代码诊断:
- `LSPServerManager`:管理多个语言服务器实例(TypeScript、Python 等)
- `LSPDiagnosticRegistry`:缓存并合并各 LSP 的诊断信息
- `LSPTool`(`src/tools/LSPTool/`):让 LLM 查询特定文件的类型错误 / warnings
- 被动反馈(`passiveFeedback.ts`):文件保存后自动推送诊断给 Agent
---
**── IV. 自动化与调度 ──**
### F. Cron 调度工具
**源码**:`src/tools/ScheduleCronTool/`、`src/utils/cron*.ts`
Agent 可以创建定时任务,按计划自动执行:
- `ScheduleCronTool`:LLM 调用此工具创建 cron 表达式定义的定时任务
- 任务持久化到本地,Claude Code 重启后恢复
- 与 Task 系统集成,定时任务触发时创建新 Task
### G. Todo 跟踪
**源码**:`src/tools/TodoWriteTool/`、`src/utils/todo/types.ts`
Agent 维护一个结构化的任务清单:
- `TodoWriteTool`:LLM 调用此工具写入/更新 todo 列表(与本辅助工具同名)
- Todo 状态:`not-started` / `in-progress` / `completed`
- 在 UI 中实时展示 Agent 的任务进度
### H. Voice 模式
**源码**:`src/voice/`、`src/services/voiceStreamSTT.ts`
语音输入支持:
- 语音关键词检测(`src/services/voiceKeyterms.ts`)
- 流式语音转文字(`voiceStreamSTT.ts`)
- 由 `voiceModeEnabled.ts` 控制开关
### I. Vim 键位模式
**源码**:`src/vim/`
输入框支持 Vim 操作模式:
- `motions.ts`:`h/j/k/l`、`w/b/e`、`0/$` 等光标移动
- `operators.ts`:`d`(删除)、`c`(修改)、`y`(复制)等操作符
- `textObjects.ts`:`iw`(单词内)、`i"`(引号内)等文本对象
- `transitions.ts`:Normal / Insert / Visual 模式转换状态机
---
**── V. 工作区扩展与运行模式 ──**
### J. OAuth 认证流程
**源码**:`src/services/oauth/`、`src/utils/auth*.ts`
完整的 OAuth 2.0 + PKCE 认证流,支持 Claude.ai 账号登录:
- 本地临时 HTTP 服务器接收回调
- 安全 token 存储(系统 Keychain / 加密文件)
- Token 刷新与 session 管理
### K. 企业策略管理(MDM)
**源码**:`src/services/remoteManagedSettings/`、`src/utils/managedEnv.ts`
企业 IT 通过 MDM 推送的策略文件覆盖用户配置:
- 禁止某些工具、限制允许的目录、强制启用日志
- 优先级高于用户设置,低于 CLI 参数
### L. 自动更新
**源码**:`src/cli/update.ts`、`src/utils/autoUpdater.ts`
- 启动时检查 npm registry 最新版本
- 可配置自动安装或仅提示
- 支持跳过特定版本
### M. Plan Mode V2(结构化规划)
**源码**:`src/utils/planModeV2.ts`、`src/tools/EnterPlanModeTool/`
权限模式 `plan` 的增强版本:
- 多 Agent 并行探索方案(`getPlanModeV2AgentCount()`)
- 面试阶段(`isPlanModeInterviewPhaseEnabled`):先与用户澄清需求,再开始执行
- `EnterPlanModeTool` / `ExitPlanModeTool`:LLM 主动进入/退出规划模式
---
**── VI. 用户体验、工具与彩蛋 ──**
### N. Buddy / 虚拟伴侣系统(彩蛋)
**源码**:`src/buddy/`,由 `feature('BUDDY')` 门控,命令 `/buddy`
完整的随机生成虚拟小动物系统,伴随用户使用 Claude Code:
**确定性生成算法**
- 使用 mulberry32 seeded PRNG,seed = 用户 userId 的 djb2 哈希
- 相同的 `userId` 永远生成同一只伴侣(`CompanionBones`)
- `CompanionSoul`(名字 + 人格描述)由 LLM 异步生成,写入缓存后不再更改
**18 种物种**(species names 以十六进制 charCode 编码,规避构建检查):
`duck`、`goose`、`cat`、`dragon`、`octopus`、`owl`、`penguin`、`turtle`、
`snail`、`ghost`、`axolotl`、`capybara`、`cactus`、`robot`、`rabbit`、
`mushroom`、`chonk`、`blob`
**5 种稀有度**(RARITY_WEIGHTS 控制概率):
`common > uncommon > rare > epic > legendary`
**5 个属性**(基于 species + rarity 的 stat 侧重):
`DEBUGGING`、`PATIENCE`、`CHAOS`、`WISDOM`、`SNARK`
**外观系统**
- 多帧 ASCII Art 动画,idle 时循环播放
- 帽子槽(wizard hat / beanie / tiny duck 等)
- 眼睛样式(`·` / `✦` / `×` / `◉` / `@` / `°`)
**交互机制**
- 伴侣渲染在输入框旁边,有独立对话气泡
- System prompt 告知 Claude 伴侣的名字和人格;当用户叫到伴侣名字时,Claude 给出一行 in-character 回应
- `useBuddyNotification.tsx` 监听消息,判断是否需要伴侣说话
---
### O. Effort Level(努力程度控制)
**源码**:`src/utils/effort.ts`、`src/commands/effort/`,命令 `/effort`
细粒度控制每次请求中 Claude 的"思考深度":
**4 个级别**:`low` → `medium` → `high` → `max`(也可传入 0–1 数字)
**优先级链**(高优先级覆盖低优先级):
`CLAUDE_CODE_EFFORT_LEVEL` 环境变量 → AppState.effortValue → 模型默认值
- `max` 等价于开启 Ultrathink(扩展思考上限)
- 通过 API `thinking.budget_tokens` 参数实现
- 不支持 effort 的模型自动忽略该参数
- 组织可通过 `preference` 策略禁用高 effort 档位
---
### P. Fast Mode(快速模式)
**源码**:`src/utils/fastMode.ts`、`src/commands/fast/`,命令 `/fast`
内部代号 **"penguins"**(特性门控 `tengu_penguins_off`),使用轻量级模型替换主循环模型以大幅提升响应速度:
- 切换至 `FAST_MODE_MODEL_DISPLAY` 所指向的速度优化模型
- 需要付费订阅(Pro/Max);免费账户提示需升级
- `CLAUDE_CODE_DISABLE_FAST_MODE=1` 可在环境级别禁用
- 速率限制冷却期间(cooldown)不可用,`clearFastModeCooldown()` 可手动恢复
- 通过 Statsig `tengu_penguins_off` 特性标志远程开关
---
### Q. Sandbox 沙箱隔离运行时
**源码**:`src/utils/sandbox/`、`@anthropic-ai/sandbox-runtime`,命令 `/sandbox-toggle`
为 AI 生成的代码执行提供文件系统和网络层面的隔离:
- **FS 白名单/黑名单**:指定可读/可写目录,违规访问被拦截
- **网络主机 Pattern 限制**:配置允许访问的主机列表(Glob 匹配)
- **违规事件记录**:`SandboxViolationStore` 收集所有违规请求,供 `/doctor` 展示
- `SandboxDoctorSection` 在 `/doctor` 输出中展示沙箱当前状态与违规历史
- `/sandbox-toggle` 命令在运行时切换沙箱开关
---
### R. 会话回溯(Rewind)
**源码**:`src/commands/rewind/`,命令 `/rewind`
类似 git checkout 的消息级会话分支:
- 打开 **消息选择器 UI**,列出当前对话的所有轮次
- 选中某条历史消息后,截断该消息之后的所有内容,以该消息作为"分支点"重新开始
- 本质上是在内存中修剪 `messages` 数组,实现非破坏性的会话回滚
- `/thinkback-play` 为 Thinkback 插件安装后的配套命令,可"回放"之前的思考过程
---
### S. ultraplan 关键词触发
**源码**:`src/utils/ultraplan/`
输入中出现 `ultraplan` 时,自动激活 Plan Mode V2 多 Agent 规划:
- 复杂边界检测:文件路径中的 `ultraplan`、`/rename` 等命令参数中的 `ultraplan` **不触发**
- 将关键词替换为 `plan` 后转发给 LLM,保持语义连贯
- 与 `/plan` 命令等效,但更隐蔽——属于"魔法词"设计
---
### T. Teleport(代码库传送到云端)
**源码**:`src/utils/teleport/`、`src/commands/teleport/`
将本地 git 仓库"传送"到远程云端环境运行 Agent:
**3 种云端环境类型**:
- `anthropic_cloud`:Anthropic 托管的云端计算资源
- `byoc`(Bring Your Own Cloud):用户自备云基础设施
- `bridge`:通过 Bridge 协议连接的远程会话
**工作流程**
1. `git bundle` 打包当前仓库
2. 调用 API 在云端创建新 Session
3. 上传代码包并触发云端 Agent 执行
4. 通过 SSE/WebSocket 流式回传结果
---
### U. Asciicast 会话录制
**源码**:`src/utils/asciicast.ts`
将终端输出录制为标准 `.cast` 文件(asciicast v2 格式):
- 仅对 `USER_TYPE=ant` 的内部用户可用,且需要 `CLAUDE_CODE_TERMINAL_RECORDING=1`
- 录制文件保存在 `~/.claude/recordings/` 目录
- 会话恢复(`--resume`)时自动将录制文件重命名以匹配新 Session ID
- 可使用 [asciinema](https://asciinema.org/) 播放器回放录制内容
---
### V. 终端截图与导出
**源码**:`src/utils/ansiToPng.ts`、`src/utils/screenshotClipboard.ts`、`src/utils/ansiToSvg.ts`,命令 `/export`
多种将终端内容外化的工具:
- **`ansiToPng`**:将 ANSI 转义序列渲染为 PNG 图片,直接写入系统剪贴板
- **`ansiToSvg`**:同上,但输出 SVG 格式,可在浏览器中完美缩放
- **`screenshotClipboard`**:截取当前终端可见区域,调用系统剪贴板 API 存储
- **`/export`**(`src/commands/export/`):将整条对话导出为纯文本或 Markdown 文件
---
### W. Claude in Chrome(浏览器扩展集成)
**源码**:`src/utils/claudeInChrome/`、`src/commands/chrome/`,命令 `/chrome`
将 Claude Code 与 Claude.ai Chrome 扩展打通,实现"在浏览器中调用终端 Agent":
- MCP Server 名称:`claude-in-chrome`(`CLAUDE_IN_CHROME_MCP_SERVER_NAME`)
- 通过 **Native Messaging Host** 与 Chrome 扩展通信(`chromeNativeHost.ts`)
- 支持多种 Chromium 内核浏览器:Chrome、Chromium、Edge、Brave、Arc 等
- 菜单选项:安装扩展(`https://claude.ai/chrome`)、重新连接、管理权限、设为默认
- `isChromeExtensionInstalled()` 探测本地扩展安装状态
- WSL 环境下有专属的 Portable 安装路径(`setupPortable.ts`)
---
### X. Mobile & Slack 集成入口
**源码**:`src/commands/mobile/`、`src/commands/install-slack-app/`,命令 `/mobile`、`/install-slack-app`
将移动 App 和 Slack 与 Claude Code 体验串联:
**`/mobile`(`mobile.tsx`)**
- 在终端内渲染 **ASCII QR 码**(使用 `qrcode` 包)
- 支持切换 iOS(App Store)/ Android(Google Play)两个平台的下载链接
- App Store ID:`6473753684`,Play Store:`com.anthropic.claude`
**`/install-slack-app`**
- 打开 Slack Marketplace 页面(`A08SF47R6P4-claude`)
- 全局配置中累计记录安装点击次数(`slackAppInstallCount`)
---
### Y. 诊断与内部调试工具(彩蛋/内部)
**源码**:`src/commands/heapdump/`、`src/commands/doctor/`、`src/utils/headlessProfiler.ts`、`src/commands/ant-trace/`
一批面向开发者和内部人员的深度调试工具:
**`/heapdump`**:触发 V8 堆转储(`performHeapDump()`),输出 `.heapsnapshot` 和诊断报告路径
**`/doctor`(`Doctor.tsx` 屏幕)**:系统健康检查大屏,一次显示:
- MCP 解析警告 + Keybinding 冲突
- 模型上下文 Token 上限与当前使用量
- 插件加载错误列表
- 沙箱状态与违规历史(`SandboxDoctorSection`)
- PID 锁文件信息与过期锁清理
- npm/GCS 分发标签(dist-tags)对比,检查是否有更新
- 设置配置校验错误
**Headless Profiler**(`src/utils/headlessProfiler.ts`):
- 在 `-p`(print)无交互模式下记录每轮延迟
- 追踪三个关键时间点:系统消息输出、query 开始、首个 API chunk(TTFT)
- 内部用户 100% 采样,外部用户 5% 采样
- `CLAUDE_CODE_PROFILE_STARTUP=1` 开启详细日志
**`/ant-trace`**(仅内部构建):触发内部分布式追踪标注,用于性能回归分析
---
### Z. Release Notes、Stats 与其他用户命令
**源码**:`src/commands/release-notes/`、`src/commands/stats/`、`src/commands/feedback/`、`src/commands/stickers/`、`src/commands/btw/`
**`/release-notes`**
- 从 `CHANGELOG_URL` 拉取最新变更日志(500ms 超时),超时则使用本地缓存
- 按版本格式化输出,每条变更前缀 `·`
**`/stats`(`Stats` 组件)**
- 展示本次会话的 Token 使用统计、命令调用次数、工具调用分布等
**`/feedback`**
- 内嵌反馈表单(`Feedback` 组件),可附带当前对话上下文和后台任务信息提交
**`/stickers`(彩蛋)**
- 打开 `https://stickermule.com/claudecode` 领取官方贴纸
**`/btw`(By The Way,旁白功能)**
- 在主对话旁显示 LLM 生成的"顺带一提"旁白
- 用于展示不影响主流程的补充信息或小提示
---
**── VII. 测试基础设施与内部机制 ──**
### VII-A. VCR(API 请求录制/回放)
**源码**:`src/services/vcr.ts`
测试专用的录制-回放框架,确保单元测试不依赖真实 API 请求:
- **录制条件**:`NODE_ENV=test` 或(`USER_TYPE=ant` 且 `FORCE_VCR=1`)
- **Key 生成**:对请求输入做 SHA1 hash,以 `fixtures/<name>.<hash>.json` 存储
- **流式支持**:可录制 SSE 流(存储为 event 数组),回放时模拟 async generator
- 不满足录制条件时 `withFixture()` 直接透传,零开销
### VII-B. Tips 系统(上下文提示)
**源码**:`src/services/tips/tipRegistry.ts`、`tipScheduler.ts`、`tipHistory.ts`
在 thinking spinner(等待响应)期间展示上下文相关的使用技巧:
- `tipRegistry.ts`:注册所有提示条目,每个 Tip 有 `id`、`content`、`cooldownSessions`(冷却会话数)和显示条件回调
- `tipScheduler.ts`:`getTipToShowOnSpinner()` 筛选当前上下文可用的 tips,优先选择**最久没出现过的**(`getSessionsSinceLastShown()` 最大值)
- `tipHistory.ts`:持久化记录每个 tip 最近在哪次 session 展示过
- 可用 `spinnerTipsEnabled: false` 设置关闭
### VII-C. Grove(数据治理)
**源码**:`src/services/api/grove.ts`
Anthropic 的数据使用同意管理系统,仅影响 Consumer 订阅用户的非交互会话(headless `-p` 模式):
- `AccountSettings.grove_enabled`:用户账号分的启用状态
- `GroveConfig.domain_excluded`:当前环境是否被排除在外
- `GroveConfig.notice_is_grace_period`:是否在宽限期(宽限期内不强制要求)
- `isQualifiedForGrove()`:只对 Consumer OAuth 用户 + 非交互模式 + 非纯隐私模式的情况检查
- `checkGroveForNonInteractive()`:在 `runHeadless()` 开始时调用,不满足则中止并提示用户在 claude.ai 配置偏好
### VII-D. Referral / Guest Passes(推荐邀请)
**源码**:`src/services/api/referral.ts`、`src/commands/passes/`,命令 `/passes`
订阅者可向朋友发放 Claude Code 免费试用 passes:
- `fetchReferralEligibility(campaign)` / `fetchReferralRedemptions()`:查询邀请资格和兑换情况
- Campaign 标识:`claude_code_guest_pass`
- `/passes` 命令打开 `Passes` 组件展示剩余 passes 数量,记录 `hasVisitedPasses` 标志
- `passesLastSeenRemaining`:用于判断剩余量是否下降,以决定是否在启动时展示 upsell
### VII-E. Agent Summary(子 Agent 进度摘要)
**源码**:`src/services/AgentSummary/agentSummary.ts`
仅在 Coordinator / Swarm 模式下活跃,每 30 秒用 forked agent 为每个运行中的子 Agent 生成 3-5 个词的进度摘要:
- Prompt 要求**现在时态**、**具体文件名**,禁止:过去式、branch 名称、含糊描述
```
好例子: "Reading runAgent.ts" / "Fixing null check in validate.ts"
坏例子: "Analyzed the branch diff" / "Investigating the issue"
```
- 使用与父 Agent 相同的 `CacheSafeParams`,共享 prompt cache 降低成本
- 工具调用被 `canUseTool` 回调全部拒绝(只用于摘要生成,不执行操作)
- 摘要更新到 `AgentProgress.summary`,在多 Agent 面板实时展示
---
## 各章产出物文件结构
每章产出物统一遵循以下目录结构:
```
chapters/
└── <N>-<name>/
├── package.json # 最小依赖声明
├── tsconfig.json # TypeScript 配置
├── src/
│ ├── main.ts(x) # 入口文件
│ └── ... # 其他模块
└── README.md # 本章说明 + 验收命令
```
章节间的依赖通过 **复制 + 引用**(不是 npm link)的方式组合,保持每章独立可运行。