各章节详细大纲

本文档是系列各章的内容提纲,用于把握每章要讲什么、要实现什么,以及和 Claude Code 源码的对应关系。


第 1 章:进程与标准 I/O

对应源码src/main.tsxsrc/bootstrap/state.tssrc/entrypoints/

核心问题:一个 Coding Agent 首先需要一个可以运行的进程——它从哪里读输入,往哪里写输出?

原理讲解

  • Node.js 进程模型:事件循环、process.stdin / process.stdout
  • TypeScript 在 Node.js 上的运行方式(tsxts-node
  • 进程退出码、信号处理(SIGINTSIGTERM
  • 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.tssrc/replLauncher.tsxsrc/components/TextInput.tsxsrc/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) vs claude run "..." vs claude --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.tssrc/tools.tssrc/tools/bash.tssrc/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.tssrc/services/api/promptCacheBreakDetection.tssrc/query/src/utils/thinking.ts

核心问题:怎么和 Claude 对话?怎么处理流式响应?怎么让 LLM "深度思考"?怎么用缓存把成本降低 90%?

原理讲解

  • Anthropic Messages API 的消息格式:rolecontentmodel
  • 流式 SSE 响应:message_startcontent_block_startcontent_block_deltastop
  • tool_use 块的流式重组:delta 累积 → JSON.parse
  • Token 计数与成本估算(input_tokens × $X / 1M)
  • 错误处理:限速、超时、网络错误的重试策略

特性 A:Prompt Caching(提示词缓存)

对应源码src/services/api/claude.tsgetPromptCachingEnabled)、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.tssrc/assistant/sessionHistory.tssrc/services/compact/

核心问题:多轮对话如何维护上下文?消息历史应该怎么存储和裁剪?上下文快满时怎么办?

原理讲解

  • Anthropic API 的 messages 数组:每轮都要带全历史
  • 消息类型:userassistant(含 texttool_use/tool_result 子块)
  • 上下文窗口限制:token 预算管理
  • 会话内 vs 会话间历史的区别

特性:对话压缩(Compaction)

对应源码src/services/compact/compact.tsmicroCompact.tsautoCompact.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.tssrc/query.ts

核心问题:怎么让 LLM 反复调用工具,直到任务完成?

原理讲解

  • Agentic Loop 的状态机:text → tool_use → tool_result → text → ...
  • stop_reason: "tool_use" vs "end_turn" 的处理逻辑
  • 并行工具调用:同一轮 LLM 响应可能包含多个 tool_use
  • 循环终止条件:end_turnmax_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.tssrc/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.tssrc/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.tssrc/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.tssrc/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.tssrc/skills/bundledSkills.tssrc/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 Skillsrc/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.tssrc/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.tssrc/services/MagicDocs/src/services/awaySummary.tssrc/services/PromptSuggestion/speculation.tssrc/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.tsflushGate.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.tssrc/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.mdAPI.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.tsspeculation.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 Syncfeature('UPLOAD_USER_SETTINGS') / 'DOWNLOAD_USER_SETTINGS'):

  • 交互 CLI:将本地 settings 增量上传(只上传变更的 key)到 Anthropic API
  • CCR(Cloud Code Runner)下载:在插件安装前先拉取远程 settings

Team Memory Syncfeature('TEAMMEM')):

  • 按 git remote URL 哈希识别仓库,同一组织成员共享该仓库的 team-memory/
  • Delta 上传:比对 serverChecksums,只传内容已变更的 key
  • 拉取语义:服务端内容覆盖本地(server wins);本地删除文件不会同步到服务端
  • Secret ScannerteamMemSecretGuard.ts):上传前用 gitleaks 高置信度规则扫描:Anthropic API key、AWS access token、GitHub PAT、GCP service account key、Slack token 等,发现密钥则拒绝上传并提示

Watcherwatcher.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 的诊断信息
  • LSPToolsrc/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.tsh/j/k/lw/b/e0/$ 等光标移动
  • operators.tsd(删除)、c(修改)、y(复制)等操作符
  • textObjects.tsiw(单词内)、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.tssrc/utils/autoUpdater.ts

  • 启动时检查 npm registry 最新版本
  • 可配置自动安装或仅提示
  • 支持跳过特定版本

M. Plan Mode V2(结构化规划)

源码src/utils/planModeV2.tssrc/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 编码,规避构建检查): duckgoosecatdragonoctopusowlpenguinturtle
snailghostaxolotlcapybaracactusrobotrabbit
mushroomchonkblob

5 种稀有度(RARITY_WEIGHTS 控制概率): common > uncommon > rare > epic > legendary

5 个属性(基于 species + rarity 的 stat 侧重): DEBUGGINGPATIENCECHAOSWISDOMSNARK

外观系统

  • 多帧 ASCII Art 动画,idle 时循环播放
  • 帽子槽(wizard hat / beanie / tiny duck 等)
  • 眼睛样式(· / / × / / @ / °

交互机制

  • 伴侣渲染在输入框旁边,有独立对话气泡
  • System prompt 告知 Claude 伴侣的名字和人格;当用户叫到伴侣名字时,Claude 给出一行 in-character 回应
  • useBuddyNotification.tsx 监听消息,判断是否需要伴侣说话

O. Effort Level(努力程度控制)

源码src/utils/effort.tssrc/commands/effort/,命令 /effort

细粒度控制每次请求中 Claude 的"思考深度":

4 个级别lowmediumhighmax(也可传入 0–1 数字)

优先级链(高优先级覆盖低优先级): CLAUDE_CODE_EFFORT_LEVEL 环境变量 → AppState.effortValue → 模型默认值

  • max 等价于开启 Ultrathink(扩展思考上限)
  • 通过 API thinking.budget_tokens 参数实现
  • 不支持 effort 的模型自动忽略该参数
  • 组织可通过 preference 策略禁用高 effort 档位

P. Fast Mode(快速模式)

源码src/utils/fastMode.tssrc/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 播放器回放录制内容

V. 终端截图与导出

源码src/utils/ansiToPng.tssrc/utils/screenshotClipboard.tssrc/utils/ansiToSvg.ts,命令 /export

多种将终端内容外化的工具:

  • ansiToPng:将 ANSI 转义序列渲染为 PNG 图片,直接写入系统剪贴板
  • ansiToSvg:同上,但输出 SVG 格式,可在浏览器中完美缩放
  • screenshotClipboard:截取当前终端可见区域,调用系统剪贴板 API 存储
  • /exportsrc/commands/export/):将整条对话导出为纯文本或 Markdown 文件

W. Claude in Chrome(浏览器扩展集成)

源码src/utils/claudeInChrome/src/commands/chrome/,命令 /chrome

将 Claude Code 与 Claude.ai Chrome 扩展打通,实现"在浏览器中调用终端 Agent":

  • MCP Server 名称:claude-in-chromeCLAUDE_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 体验串联:

/mobilemobile.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.tssrc/commands/ant-trace/

一批面向开发者和内部人员的深度调试工具:

/heapdump:触发 V8 堆转储(performHeapDump()),输出 .heapsnapshot 和诊断报告路径

/doctorDoctor.tsx 屏幕):系统健康检查大屏,一次显示:

  • MCP 解析警告 + Keybinding 冲突
  • 模型上下文 Token 上限与当前使用量
  • 插件加载错误列表
  • 沙箱状态与违规历史(SandboxDoctorSection
  • PID 锁文件信息与过期锁清理
  • npm/GCS 分发标签(dist-tags)对比,检查是否有更新
  • 设置配置校验错误

Headless Profilersrc/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 超时),超时则使用本地缓存
  • 按版本格式化输出,每条变更前缀 ·

/statsStats 组件)

  • 展示本次会话的 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=antFORCE_VCR=1
  • Key 生成:对请求输入做 SHA1 hash,以 fixtures/<name>.<hash>.json 存储
  • 流式支持:可录制 SSE 流(存储为 event 数组),回放时模拟 async generator
  • 不满足录制条件时 withFixture() 直接透传,零开销

VII-B. Tips 系统(上下文提示)

源码src/services/tips/tipRegistry.tstipScheduler.tstipHistory.ts

在 thinking spinner(等待响应)期间展示上下文相关的使用技巧:

  • tipRegistry.ts:注册所有提示条目,每个 Tip 有 idcontentcooldownSessions(冷却会话数)和显示条件回调
  • tipScheduler.tsgetTipToShowOnSpinner() 筛选当前上下文可用的 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.tssrc/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)的方式组合,保持每章独立可运行。