ai 管 provider,agent 管循环,coding-agent 管产品——这三个包占了 81% 的代码。其余七个包加起来不到两成,且多数标着 experimental。看规模分布比看包名更快理解一个仓库的重心:
| 包 | TS 行数 | 职责 |
|---|---|---|
coding-agent | 123797 | CLI 产品本体:工具、扩展、交互模式、会话管理 |
ai | 58449 | 统一多 provider 的 LLM API |
tui | 32374 | 自研终端 UI 库,差分渲染 |
agent | 21053 | agent 循环、工具执行、会话存储、harness v2 |
session-backends | 4039 | SQLite 后端(独立成包) |
server | 3761 | 会话服务端(experimental) |
client | 2472 | 客户端 |
protocol | 1961 | 线上协议(CBOR 编解码 + framing) |
evals | 1774 | 评测框架 |
telemetry | 1178 | 厂商中立的 telemetry 契约 |
行数由 tools/stats.sh 从锚定 SHA 的工作树程序化统计(含测试与生成文件),非手写。
telemetry → (无内部依赖)
tui → (无内部依赖)
protocol → (无内部依赖)
evals → (无内部依赖)
ai → telemetry
agent → ai, telemetry
client → protocol
server → ai, protocol
coding-agent → agent, ai, client, protocol, tui ← 唯一的汇聚点
tui 完全独立于 agent 逻辑——它是一个可以单独拿走用的终端 UI 库,不知道 LLM 的存在。这张图里最值得注意的是 agent 不依赖 tui,tui 也不依赖任何东西。渲染与执行彻底分离,是 headless 模式(第 14 章)能存在的结构前提。
作者分布是典型的「一个主力 + 一圈卫星」:Mario Zechner 3513 次提交(63%),Armin Ronacher 512 次,其后是 github-actions[bot] 与一串三位数以下的贡献者。286 位作者里,绝大多数只提交过个位数。
把这个分布和 第 18 章的贡献者门禁放在一起看才完整:240 个已批准账号,286 位历史作者——门禁不是把人挡在外面,而是把「随手扔一个 issue」和「真的来做事」分开。
provider 的模型元数据不在 git 里:
packages/ai/src/providers/data/
所以 npm run build 的注释写的是「先刷新模型数据,再构建全部包」,另有一个 build:offline 用已有数据、不联网。README.md:56–57 完整含义见 第 09 章。
12 万行里装的是:7 个内建工具、扩展系统、交互模式的全部 UI 组件、会话管理、设置系统、主题、键位、RPC/JSON 模式、导出 HTML……换句话说,凡是「产品决策」都在这一层。
这与 CONTRIBUTING.md 的声明是一致的:核心要最小,不属于核心的应该做成扩展。CONTRIBUTING.md:9 但要注意「核心」在这句话里指的是 packages/agent(2 万行),不是 coding-agent。coding-agent 本身不受这条约束——它是产品。
3.2 万行手写一个终端 UI 库,而不是用 Ink(React for CLI)或 blessed。代价是显然的;收益要到 第 11 章才说得清。这里先记一个事实:tui 包零内部依赖,也不依赖 React——它是这个仓库里最容易被单独复用的部分。
server 包的 README 第一句就是:Experimental. 本包处于活跃开发中,可能变更或移除,恕不另行通知;API 与行为尚不稳定。server/README.md:3
把稳定性承诺写在 README 第一行,比藏在版本号里诚实。对照 第 07 章提到的「唯一兼容承诺」,这是同一种做法:把变更自由度显式声明出来,而不是靠 semver 暗示。
tools/stats.sh 统计的是 packages/*/ 下全部 .ts/.tsx,不区分 src 与 test。真实的「产品代码」比表里的数字小。dependencies 与 peerDependencies。devDependencies 里的内部依赖未计入,所以实际的构建期耦合可能比图上更多。场景你想拿 pi 仓库里的一个包单独做自己的终端应用,且不想拖进任何 LLM 相关依赖。哪个包能直接拿走?
C。依赖图里 tui 没有任何 @earendil-works/* 依赖,也不依赖 React;agent 依赖 ai 和 telemetry,coding-agent 是全图唯一的汇聚点。
场景你 clone 仓库后在断网环境执行 npm run build,会发生什么?
B。39 个 provider 的模型清单在 gitignore 掉的 data/ 目录里,.gitignore:11 默认 build 第一步就是联网刷新它。README.md:56