本文档是系列各章的内容提纲,用于把握每章要讲什么、要实现什么,以及和 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 代码段
// 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 代码段
// 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) vsclaude run "..."vsclaude --print - 版本信息管理:从
package.json读取
关键 Claude Code 代码段
// 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 代码段
// 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 时写入诊断日志
// 在 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
// src/utils/thinking.ts
type ThinkingConfig =
| { type: 'adaptive' }
| { type: 'enabled'; budgetTokens: number }
| { type: 'disabled' }
关键 Claude Code 代码段
// 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)
// 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 代码段
// 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 代码段
// 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):
{
"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 代码段
// 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 代码段
// 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 代码段
// 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 代码段
// 存储路径构造
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 正文):
---
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 代码段
// 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 代码段
// 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 代码段
// 配置文件格式(~/.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:
// src/services/awaySummary.ts
const recent = messages.slice(-RECENT_MESSAGE_WINDOW) // 最近 30 条
recent.push(createUserMessage({ content: buildAwaySummaryPrompt(memory) }))
await queryModelWithoutStreaming({ model: getSmallFastModel(), ... })
关键 Claude Code 代码段
// 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_REPOSallowlist 中的私有 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 协议连接的远程会话
工作流程
git bundle打包当前仓库- 调用 API 在云端创建新 Session
- 上传代码包并触发云端 Agent 执行
- 通过 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 播放器回放录制内容
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)的方式组合,保持每章独立可运行。