Day 01 / 共 20 天 · 第 1 周 建立心智

项目全景与模块地图

今天不写代码。目标:搞清"这是个什么项目、用什么造的、代码分成哪几大块",在脑子里建立一张地图。今天是第 1 周(建立心智)的起点,为明天 Day 02 追启动链打地基。

📍 你在整门课的位置(这条链贯穿 20 天,每天开头点亮你所在的格子)· 第 1 周 建立心智
D01 全景地图 D02 启动链 D03 Agent 循环 D04 Ink UI D05 完整旅程· W2 核心引擎…
💡 用一个类比先兜住今天(本课会一直沿用这套"公司实习生"世界观) 把这个 CLI 想成你新招的一名编程实习生大脑(会思考的大模型)+ 一双手(能读写文件、跑命令的工具)+ 一张脸(终端里跟你对话的界面)+ 一套不停转的干活循环(想一步→动手→看结果→再想)。今天我们就是先带你逛一圈这位实习生的"身体构造图"——脑在哪、手在哪、脸在哪。后面每天钻进一个器官细看。
L01

它到底是什么

我们要读的仓库叫 claude-code-best(简称 CCB)。package.json 第 2-3 行写得很清楚:

"name": "claude-code-best",
"version": "2.8.3",
"description": "Reverse-engineered Anthropic Claude Code CLI — interactive AI coding assistant in the terminal"

翻译过来:它是 Anthropic 官方 Claude Code CLI(那个在终端里跟你结对编程的 AI 助手)的逆向工程 / 反编译后完整重写的 TypeScript 版本CLAUDE.md:7 也明说 "This is a reverse-engineered / decompiled version of Anthropic's official Claude Code CLI tool."

🎯 一句话:它是跑在终端里的 AI 编程 Agent——你用自然语言下命令,它自己调用工具(读写文件、跑命令、搜代码…)把编程任务干完。我们要逐层读懂"这样一个 Agent 内部怎么运转"。

它甚至比官方版功能更多:README(README.md:19-37)列出它额外实现了 Goal 持续驱动、Artifacts HTML 托管、Ultracode 多 Agent 编排、Remote Control 远程控制、Voice 语音、Web Search 等——而且"关闭了外部封控点"、完全兼容官方配置文件。

合规提醒:README 声明本项目仅供学习研究,Claude Code 的权利归 Anthropic 所有。我们读它是为了学习 Agent 工程,不用于其它用途。
L02

逆向 ≠ 薄封装

很多人以为"复刻一个 CLI"就是包一层调官方的包。CCB 完全不是。它没有运行时依赖官方 @anthropic-ai/claude-code 包,而是自己从头重实现了每一个子系统:agent 循环、工具系统、终端 UI、MCP、skills、hooks、workflow 引擎……

官方的 @anthropic-ai/claude-agent-sdk 只作为 devDependencypackage.json:85)存在——只用来对齐类型/协议定义,运行时一点不依赖它。

为什么这对学习是好事? 因为它把官方那个压缩混淆的产物,重写成了可读的、模块清晰的 TypeScript 源码。你能看到每个决策的真实实现,而不是一坨 minified 代码。这是学习"一个成熟 Agent CLI 到底怎么工程化"的绝佳标本。
L03

先建立"一个 AI Agent"的直觉

零基础最需要先有的一个直觉——Agent 不是"聊天机器人",它会"动手"。区别在于:

  • 聊天机器人:你问,它答(只输出文字)。
  • Agent:你给个目标,它自己反复调用工具(读文件、改代码、跑测试),观察结果,再决定下一步,直到把事办完。

所以这个 CLI 的灵魂是一个循环(就是总目录页那个转圈动画):

你输入需求 → 拼请求发给大模型(带上可用工具清单)→ 模型流式返回(可能是文字,也可能是"我要调 Edit 工具")→ 如果要调工具,就真去执行 → 把工具结果喂回给模型 → 模型继续 → …… → 直到模型说"干完了"。

这个循环在本项目由 src/query.ts + src/QueryEngine.ts 驱动(Day 03、06 细讲)。今天你只要记住"Agent = 模型 + 工具 + 一个不停转的循环"。

📝 举个例子:同一句话,聊天机器人 vs Agent 你说:把 README 里所有 "颜色" 改成 "color"
🗣️ 聊天机器人:输出一段文字"你可以打开 README,用查找替换……"(只是教你怎么做)。
🤖 Agent(本项目):调 Read 读 README → 调 Edit 真替换 → 调 Read 复查 → 回一句已改 3 处 ✅它自己动手把事办完了)。
一名"实习生"的身体构造 = 本项目四大块 😀 脸 · 终端界面 Ink UI · REPL.tsx · Day04 🧠 脑 · 查询循环 query.ts · Day03/06 ✋ 手 · 工具系统 Tool.ts · Day07/08 🔁 干活循环:想→动手→看结果→再想 把脑和手串起来 · Day03/05
图注:脑(想)+ 手(动手)+ 脸(对话),靠中间那个循环串起来——这就是全部 20 天要拆解的"实习生"。

👶 小白:那它会不会一直转、停不下来?

👨‍🏫 老师:不会。每一轮模型都会明确表态——"我还要调工具" 就继续转,"我说完了(没有工具请求)" 循环就停,把结果显示给你。判断"继续还是停"的那段代码 Day 03 会单步走给你看。

L04

技术栈

方面选型出处 / 备注
运行时Bun(不是 Node!).tool-versions 锁 bun 1.3.13;产物也兼容 node
语言TypeScript(strict)tsconfig.json:8,ESM 模块
终端 UIReact 19 + Ink(自研 fork @anthropic/ink用 React 写、渲染到终端;Day 04 细讲
CLI 框架Commander解析命令行参数/子命令
校验zod工具输入 schema 等
Lint/格式化Biomebiome.json
构建Bun.build + Vite 双管线Day 02/20 细讲
模型供应商Anthropic + OpenAI + Bedrock + Vertex + Gemini + Grok…7 个供应商,Day 17 讲
Bun 是一个比 Node 更快的 JavaScript 运行时(自带打包、测试、包管理)。
Ink 是"能用 React 写终端界面"的库——你写的还是 <Box><Text> 这种组件,但它渲染成的不是网页,而是终端里的字符。这就是为什么这个 CLI 里有 700+ 个 .tsx 文件。
L05

项目规模画像

先有个体量的心理准备(别怕,我们会拆开读):

2500+.ts 文件
700+.tsx 组件
15+monorepo 包
5640行 · main.tsx

src/ 下按文件数排:utils/(773)、components/(418)、commands/(400)、services/(301)、hooks/(119)…… 数量最大的是工具函数和 UI 组件,这很正常——一个成熟 CLI 大量代码花在"界面"和"打杂"上,真正的"agent 大脑"反而集中在少数几个文件里。

好消息:投入产出比最高的其实就几个文件——src/query.ts + src/QueryEngine.ts(大脑)、src/Tool.ts + packages/builtin-tools(手脚)、src/screens/REPL.tsx(界面)。本教程主要围绕它们,不会让你陷进 773 个 utils 里。
L06

核心模块地图

这是本教程最重要的一张图——记住这几大块各在哪、干什么,后面每天都是往里钻:

⚠️ 小白常误以为:这 8 块是平级、随便先看哪个都行。其实不是——① 查询循环是"心脏",其它块都是被它调度的;投入产出比最高的就是 ①②③。后面 5 块(MCP/Workflow/Bridge…)是"外挂器官",第 3 周才碰。先抓心脏,别一上来陷进 773 个 utils。

① Agent 查询循环

src/query.ts · QueryEngine.ts · query/

核心大脑:发消息、处理流式响应、执行 tool calls、管理一轮对话。Day 03/06/10

② 工具系统

src/Tool.ts · tools.ts · packages/builtin-tools

手脚:~60 个工具(读写文件、Bash、搜索、子代理…)。Day 07/08

③ 终端 UI (Ink)

src/components(418) · screens/REPL.tsx · main.tsx

脸面:消息列表、输入框、权限弹窗,全用 React 渲染到终端。Day 04/18

④ Slash 命令

src/commands(400) · commands.ts

"/help /model /compact" 等斜杠命令。Day 11

⑤ Services 服务层

src/services(301)

API 客户端、MCP、分析、oauth、SessionMemory 等后台服务。Day 17

⑥ MCP / Skills / Hooks

packages/mcp-client · src/skills · src/hooks

扩展能力:接外部工具、技能、生命周期钩子。Day 12/13/14

⑦ Workflow 引擎

src/workflow · packages/workflow-engine

多 Agent 编排(Ultracode)。Day 19

⑧ Bridge / Remote

src/bridge(40) · daemon · ssh · remote-control-server

远程控制:手机/web 控制终端里的 Claude Code。Day 19

除此之外还有一堆"锦上添花"的子系统:Buddy 陪伴宠物、Proactive 自主模式、Voice 语音、Vim 模式、Coordinator 多 worker、Daemon 守护进程。它们大多是可通过构建 feature flag 开关的扩展特性,不是核心,我们放到 Day 18/19 顺带讲。
L07

monorepo 包一览

package.json:32-36 定义 workspaces = packages/*packages/@ant/*packages/@anthropic-ai/*。关键包:

用途
builtin-tools★ 内置工具集(~60 个 tool 实现)。Day 08 精读
agent-tools子代理相关工具
mcp-client★ MCP 客户端库。Day 12
workflow-engine确定性 JS 脚本编排引擎(多 agent,端口适配器模式)。Day 19
remote-control-server自托管远程控制服务端(React+Vite Web UI,Docker 部署)。Day 19
@ant/ink★ fork 的 Ink 终端 UI 框架本体。Day 04
acp-link / cloud-artifacts / weixinACP 桥接 / HTML 托管 / 微信集成
*-napi(audio/image/color-diff/modifiers/url)原生能力(音频/图像/颜色/键盘修饰键/URL)。Day 20
monorepo(单体仓库):把很多相关的包放在同一个 git 仓库、用一套依赖统一管理。packages/* 里每个子目录都是一个能独立发布的包,但它们共享顶层的依赖锁和构建。napi 指用原生代码(非 JS)实现的能力,比如音频捕获——JS 干不了的活交给原生。
L08

bin 入口:命令怎么映射到代码

装好后你会得到几个命令行入口(package.json:27-31):

"bin": {
  "ccb": "dist/cli-node.js",           // 用 node 跑
  "ccb-bun": "dist/cli-bun.js",        // 用 bun 跑
  "claude-code-best": "dist/cli-node.js"
}

这些 cli-*.js 是构建生成的极薄 shim(就一行 import "./cli.js"),真正的产物是 dist/cli.js,它打包自源码入口 src/entrypoints/cli.tsx。所以完整映射链是:

你敲 ccb
  → dist/cli-node.js          (#!/usr/bin/env node, 一行 import)
  → dist/cli.js               (打包产物)
  → src/entrypoints/cli.tsx   (真正的源码入口 ★)
记住 src/entrypoints/cli.tsx 这个入口文件——明天 Day 02 我们就从它开始,一步步追到界面渲染出来。读任何 CLI 项目,"找到真正的入口文件"永远是第一步。
L09

读源路线 & 必知的坑

三条主线(贯穿本教程)

1

纵向:跟一次对话走完全程

从 cli.tsx 启动 → REPL 界面 → 你输入 → query 循环 → 调工具 → 返回。这是理解全局的主线。

2

横向:吃透工具系统

从 Tool 接口到一个具体工具(如 Edit)的完整生命周期。理解 Agent"手脚"的主线。

3

扩展:MCP / Skills / Hooks / Workflow

Agent 如何被外部能力增强。理解可扩展性的主线。

⚠️ 必知的坑

  • 文档滞后于代码CLAUDE.md 里写"当前版本 2.2.1"、"main.tsx ~5674 行",而实际 package.json 是 2.8.3、main.tsx 5640 行。一律以源码为准,文档是快照。
  • CLAUDE.md 和 AGENTS.md 几乎是同一份(AGENTS.md 开头标题甚至写着 "# CLAUDE.md")——两个副本供不同 AI 读取,别以为是两份不同文档。
  • 用的是 Bun 不是 Node:很多 import、构建、执行走 Bun API。产物靠构建时打补丁做到 node/bun 双跑(Day 02 讲)。
  • 用的是自研 fork 的 Ink@anthropic/ink),不是社区 ink 包;还用了 React Compiler(产物里满是 _c() memo 调用)。
L10

今日小结 + 动手

🧠 今天你应该能回答

  • CCB 是什么?(逆向重写的 Claude Code CLI,不是薄封装,功能更多)
  • "Agent" 和"聊天机器人"的区别?(Agent 会调工具、循环干活)
  • 技术栈?(Bun + TS + React/Ink)
  • 核心模块地图的 8 大块 + 各在哪个目录?
  • 真正的源码入口是哪个文件?(src/entrypoints/cli.tsx

✋ 动手 5 分钟(可选)

# 1. 确认项目身份
cd claude-code
head -10 package.json          # 看 name/description
sed -n '1,10p' CLAUDE.md        # 看"逆向"声明

# 2. 感受规模
find src -name '*.ts' -o -name '*.tsx' | wc -l
for d in src/*/; do echo "$(find $d -name '*.ts*'|wc -l) $d"; done | sort -rn | head

# 3. 看 bin 映射和入口
sed -n '27,36p' package.json
ls src/entrypoints/

# 4. 看 monorepo 包
ls packages/
明天预告 · Day 02:我们从 src/entrypoints/cli.tsx 出发,看清"敲下 ccb 到终端里出现交互界面"这一路上代码到底怎么跑——一个巨大的 fast-path 分发器、Bun 构建、以及 REPL 是怎么挂载起来的。
← 返回 20 天总目录 下一天 · 环境搭建与启动链 →