01 源码地图
从哪里开始读?按什么顺序读?每个模块和测试怎么对应?
🎯 本节目标
- 知道第二部分每章对应哪些源码文件
- 掌握推荐的阅读顺序(由简到难、由独立到耦合)
- 了解测试文件如何作为「行为说明书」使用
1. 推荐的阅读顺序
第二部分按照「从简单独立 → 到核心耦合」的顺序编排:
| 章节 | 源码文件 | 难度 | 为什么放这里 |
|---|---|---|---|
| 02 配置系统 | config/schema.ts、load-config.ts | ⭐ | 零依赖,先热身 |
| 03 通道层 | feishu/channel.ts、context.ts、webhook.ts | ⭐ | 只依赖 SDK 和 types,理解边界 |
| 04 路由与归一化 | bridge/conversation-router.ts、message-normalizer.ts | ⭐⭐ | 纯函数逻辑,测试驱动理解 |
| 05 会话管理 | bridge/session-host-manager.ts | ⭐⭐⭐ | 第一个「有状态」核心模块 |
| 06 运行时封装 | bridge/runtime-host.ts | ⭐⭐⭐⭐ | 最复杂:对接 Pi SDK 全家桶 |
| 07 流式渲染 | bridge/stream-renderer.ts | ⭐⭐⭐ | 流式状态机的经典范式 |
| 08 UI 桥接 | bridge/ui-context.ts | ⭐⭐⭐ | Promise 挂起 + 远程回调 |
| 09 卡片系统 | cards/*.ts、bridge/card-actions.ts | ⭐⭐ | 把交互串起来 |
| 10 附件处理 | attachments/*.ts | ⭐⭐ | 输入预处理决策树 |
| 11 文件回传工具 | tools/send-file-to-chat.ts | ⭐⭐ | AsyncLocalStorage 的实际应用 |
| 12 存储 | store/store.ts、json-store.ts | ⭐⭐ | 接口抽象 + 并发写 |
| 13 入口与扩展 | bin/pi-remote-feishu.ts、extensions/index.ts | ⭐⭐ | 最后看,因为它是组合根 |
| 14 测试与二次开发 | test/*.ts、package.json | ⭐ | 收尾 + 实践指南 |
2. 测试作为「行为说明书」
这个项目的测试写得非常干净,先读测试,再读实现是最高效的方式——测试告诉你「函数应该怎样表现」,实现告诉你「它是怎么做到的」。
| 测试文件 | 验证的行为 |
|---|---|
| prompt-queue.test.ts | 同队列串行 / 跨队列独立 |
| conversation-router.test.ts | 私聊/群聊/群按用户/未 @ 拒绝 |
| message-normalizer.test.ts | 命令识别、去 @、prompt 拼装 |
| card-actions.test.ts | 卡片动作分发、身份恢复 |
| attachments.test.ts | 附件分类决策树(mock channel) |
| send-file-to-chat.test.ts | 文件校验、发送(mock channel) |
| json-store.test.ts | CRUD、过滤、损坏降级、并发写 |
| config.test.ts | 配置解析合并默认值 |
💡 为什么绝大多数测试不依赖飞书?
因为 FeishuChannel 是接口。mock 一个接口比 mock 整个 SDK 容易得多。
这就是「依赖抽象而非实现」的直接回报——也是你写项目时应该学的。
3. 阅读工具建议
- VS Code:打开项目后按
Ctrl+P输入文件名快速跳转 - F12 / Cmd+点击:跳转到类型定义,追接口实现
- 跑测试:改代码后
npm test快速验证你的理解
4. 每个源码模块的「一句话职责」
| 文件 | 一句话职责 |
|---|---|
| types.ts | 全项目类型契约,是「地基中的地基」 |
| prompt-queue.ts | 26 行实现串行队列(Promise 链) |
| feishu/context.ts | 13 行实现 AsyncLocalStorage 上下文 |
| cards/common.ts | 卡片基础组件(文本/按钮/下拉) |
| attachments/mime.ts | MIME 推断 + 文本判断(19 行) |
| feishu/webhook.ts | 4 行的语义化占位 |
| store/store.ts | 存储工厂(12 行) |
✅ 本节小结
第二部分一共 14 章,按「简单 → 复杂 → 组合」编排。
每章建议配合 npm test 里的对应测试一起读。
✍️ 练习
- 先读
test/conversation-router.test.ts,预测routeConversation的行为,再去读实现验证。 - 打开
src/types.ts,把所有 interface 列出来,猜猜哪个是「被引用最多」的?