DOCUMENT 02 · 架构 · 模块 · 文件结构
五层骨架,刻意小核
读完这一篇,你能在 src/ 里找到任意特性。pi 的设计纪律:核心稳定且小,所有"业务感"功能下放到 Extensions / Skills / Prompts / Themes。本文按层走,逐目录注释,并给出关键模块的职责边界。
■ 五层架构
L1
L1 · Entry · 入口分发
解析 CLI 参数,决定运行哪个模式;区分普通
pi 和 pi install/... 包管理子命令。同时给 Bun 用户提供独立的 bun/cli.ts 入口(让 pi 也可用 Bun 跑而无须 Node)。L2
L2 · Modes · 模式渲染
同一个 Agent 内核外面套不同的 IO 形态。Interactive 是一个完整 TUI(自研组件库),Print 是一次性脚本式输出,RPC 是 stdio JSONL,SDK 是嵌入式 API。
L3
L3 · Agent Core · 会话内核
对话循环、上下文管理、工具调用编排、System Prompt 拼装、事件总线、模型解析。一个超大的
agent-session.ts(~100KB)是整套系统的"主大脑"。L4
L4 · Capability · 工具 · Extension · Compaction
所有"能力"都在这里:4 个内置工具、Extensions 注册系统、Skills 注入、Prompt Templates 展开、Compaction 算法、HTML 导出。可被 Extension 替换或扩充。
L5
L5 · Persistence · 存储 · 凭证 · 设置 · 包
JSONL 树状会话存储、auth 凭证加密、全局/项目 settings、模型注册表、pi packages 的 npm/git 安装与升级。
■ 源码树(color-coded)
高亮策略:目录、core 模块、modes/、tools/、extensions/、超大文件(≥40KB,"重灾区")、utils/与注释。
packages/coding-agent/
├── README.md # 27KB · 用户视角的全功能手册
├── package.json # 包元数据 + pi.dev 配置
├── src/
│ ├── bun/ # Bun 运行时专属入口
│ │ ├── cli.ts
│ │ ├── register-bedrock.ts
│ │ └── restore-sandbox-env.ts
│ ├── cli.ts # Node 主入口
│ ├── cli/ # 启动期 UI 与参数处理
│ │ ├── args.ts # 15KB · CLI 参数解析
│ │ ├── config-selector.ts
│ │ ├── file-processor.ts
│ │ ├── initial-message.ts
│ │ ├── list-models.ts
│ │ └── session-picker.ts
│ ├── config.ts # 17KB · 集中配置解析
│ ├── package-manager-cli.ts # 17KB · pi install/update/list 子命令
│ ├── core/
│ │ ├── agent-session.ts # 103KB · ★ Agent 主循环(最大文件)
│ │ ├── agent-session-runtime.ts # 14KB · 多 session 运行时编排
│ │ ├── agent-session-services.ts # 7KB · DI 容器(auth/registry/...)
│ │ ├── sdk.ts # 14KB · 对外 SDK API
│ │ ├── session-manager.ts # 45KB · JSONL 树存储与读写
│ │ ├── model-registry.ts # 33KB · Provider × 模型清单
│ │ ├── model-resolver.ts # 21KB · 别名 → 实际模型解析
│ │ ├── settings-manager.ts # 34KB · 全局/项目 settings 合并
│ │ ├── auth-storage.ts # 14KB · OAuth/API key 加密存储
│ │ ├── package-manager.ts # 77KB · ★ npm/git 包安装核心
│ │ ├── resource-loader.ts # 32KB · 多源资源(extensions/skills/...)加载
│ │ ├── system-prompt.ts # 6KB · System Prompt 模板
│ │ ├── prompt-templates.ts # 8KB · /name 命令展开
│ │ ├── skills.ts # 14KB · Skills 注入
│ │ ├── slash-commands.ts # 2KB · 内置斜杠命令注册表
│ │ ├── keybindings.ts # 11KB · 键位配置合并
│ │ ├── messages.ts # 5KB · 消息标准化
│ │ ├── event-bus.ts # 事件订阅
│ │ ├── footer-data-provider.ts # 状态栏数据源
│ │ ├── bash-executor.ts # 4KB · 共享 bash 执行
│ │ ├── output-guard.ts # 输出截断保护
│ │ ├── http-dispatcher.ts # HTTP 调度
│ │ ├── compaction/
│ │ │ ├── compaction.ts # 27KB · ★ 压缩主算法
│ │ │ ├── branch-summarization.ts # 11KB · 分支感知摘要
│ │ │ └── utils.ts
│ │ ├── tools/
│ │ │ ├── index.ts # 工具注册中心
│ │ │ ├── bash.ts # 16KB
│ │ │ ├── edit.ts # 17KB
│ │ │ ├── edit-diff.ts # 15KB · edit 的 diff 计算
│ │ │ ├── read.ts # 16KB
│ │ │ ├── find.ts # 13KB
│ │ │ ├── grep.ts # 14KB
│ │ │ ├── ls.ts # 8KB
│ │ │ ├── file-mutation-queue.ts
│ │ │ ├── output-accumulator.ts
│ │ │ └── path-utils.ts
│ │ ├── extensions/
│ │ │ ├── loader.ts # 19KB · 发现 + 加载
│ │ │ ├── runner.ts # 33KB · ★ 沙箱 + 调度执行
│ │ │ ├── types.ts # 54KB · ★ 公开 API 类型(重灾区)
│ │ │ ├── wrapper.ts # 适配 wrapper
│ │ │ └── index.ts
│ │ └── export-html/ # /export 与 /share 用
│ │ ├── index.ts # 11KB
│ │ ├── template.html · template.css · template.js # 浏览器侧
│ │ ├── ansi-to-html.ts · tool-renderer.ts
│ │ └── vendor/highlight.min.js · marked.min.js
│ ├── modes/
│ │ ├── index.ts
│ │ ├── print-mode.ts # 5KB
│ │ ├── interactive/
│ │ │ ├── interactive-mode.ts # 186KB · ★★ 整套 TUI 装配
│ │ │ ├── components/ # 30+ 个自研组件
│ │ │ │ ├── armin.ts · daxnuts.ts (彩蛋角色)
│ │ │ │ ├── footer.ts · custom-editor.ts
│ │ │ │ ├── model-selector.ts · session-selector.ts (33KB)
│ │ │ │ ├── settings-selector.ts (18KB) · tree-selector.ts (43KB)
│ │ │ │ └── tool-execution.ts · bash-execution.ts ...
│ │ │ └── theme/
│ │ │ ├── dark.json · light.json · theme-schema.json
│ │ │ └── theme.ts # 36KB · 主题运行时
│ │ └── rpc/
│ │ ├── rpc-mode.ts # 22KB
│ │ ├── rpc-client.ts
│ │ ├── rpc-types.ts
│ │ └── jsonl.ts # JSONL 严格 LF 帧
│ └── utils/ # 通用工具,无业务逻辑
│ ├── git.ts · shell.ts · paths.ts
│ ├── clipboard.ts · clipboard-image.ts · clipboard-native.ts
│ ├── image-{convert,resize}.ts · exif-orientation.ts
│ ├── syntax-highlight.ts · ansi.ts · highlight-js-lib-index.d.ts
│ ├── tools-manager.ts # 12KB
│ └── version-check.ts · windows-self-update.ts
├── docs/ # 用户文档(providers / sdk / rpc / 等)
├── examples/ # SDK / Extension 示例
├── scripts/
└── test/
■ 核心模块速查
core/agent-session.ts
103 KB
★ 整个项目最大文件。一个 session = 一个对话循环。负责调度 LLM 请求、工具执行、消息追加、事件广播、compaction 触发、错误恢复。是 03 文档的主角。
core/session-manager.ts
45 KB
JSONL 树状会话的所有读写。append-only 顺序写、按 parentId 重建 active path、fork / clone / 跳点。in-memory 与磁盘双实现。
core/package-manager.ts
77 KB
★ pi install/remove/update 的所有逻辑。支持 npm / git / ssh / https / 本地路径多协议;pin tag 与 commit;项目级 / 全局两套目录;npm 包用 --omit=dev,git 包用 install。
core/model-registry.ts
33 KB
所有内置 Provider × 模型的元数据:context window、是否支持 tool use、是否支持 thinking、定价等。
~/.pi/agent/models.json 可追加。core/settings-manager.ts
34 KB
合并全局 + 项目 settings.json,做字段验证、热更新。负责暴露
/settings 的可编辑字段。core/resource-loader.ts
32 KB
统一从多源(全局 / 项目 / npm 包 / git 包)发现 + 加载 extensions / skills / prompts / themes。支持 disabled 列表。
core/compaction/compaction.ts
27 KB
默认压缩算法:选择老消息、构造摘要 prompt、调模型生成摘要、替换原消息。可被 extension 完整覆盖。
core/auth-storage.ts
14 KB
OAuth tokens 与 API key 的存储。涉及 keychain / 文件加密 / 刷新流程。
■ 内置工具(4 个 + 辅助)
默认暴露给模型的工具按"最小够用"原则选择。其余工具(包括 web fetch / mcp / 远端执行 / 沙箱执行)都期望从 extension 提供。
| 工具 | 文件 | 说明 |
|---|---|---|
bash | core/tools/bash.ts | 执行 shell 命令;带超时/截断/工作目录控制。背后是 core/bash-executor.ts 的共享 spawn 逻辑。 |
read | core/tools/read.ts | 读文件,支持行号范围、PDF/notebook 等格式。 |
edit | core/tools/edit.ts + edit-diff.ts | 精确字符串替换 + diff 计算。和 file-mutation-queue.ts 配合避免并发覆盖。 |
write | (在 edit.ts 体系内) | 创建或覆盖文件,受同一队列保护。 |
辅助工具(默认未注入,按需启用)
| 工具 | 用途 |
|---|---|
find · grep · ls | 受 ripgrep 启发的搜索 / 列目录。可由 extension 启用并替换。 |
output-accumulator · output-guard | 把 streaming 输出装到模型可消化的窗口里,自动截断超长输出。 |
■ Extension 模型
Extension 是一个默认导出函数(可 async)的 TS 模块,接收一个 ExtensionAPI。一个文件能注册:
export default function (pi: ExtensionAPI) {
pi.registerTool({ name: "deploy", description: "...", schema: {...}, run: async ({ args, ctx }) => {...} });
pi.registerCommand("stats", { description: "...", run: ({ args, ctx }) => {...} });
pi.registerProvider({ id: "my-cloud", ... });
pi.registerCompactor({ ... }); // 替换默认压缩
pi.on("tool_call", async (event, ctx) => { ... });
pi.on("session_started", async (event, ctx) => { ... });
// 其余事件见 extensions/types.ts (54KB 的 API 类型)
}
关键文件
| 文件 | 职责 |
|---|---|
extensions/loader.ts | 扫描全局/项目/npm/git 目录,解析包 manifest,构造 extension 描述。 |
extensions/runner.ts | 调度 extension 工厂、运行钩子、暴露 ExtensionAPI、隔离错误。33KB,是 extension 系统的 runtime。 |
extensions/types.ts | ★ 54KB 的"对外契约"——ExtensionAPI / Hook / Tool / Provider / Compactor 等全部 TS 类型定义。读这个文件就知道 extension 能做什么。 |
extensions/wrapper.ts | 把内部 session API 包装成给 extension 看的稳定 API。 |
能力清单(来自 README):自定义工具或重写内置工具、Sub-agent / Plan Mode、自定义 Compaction、权限网关与路径保护、自定义编辑器与 UI 组件、Status line / Header / Footer / Overlay、Git checkpoint 自动 commit、SSH / 容器执行、MCP server 集成、模拟 Claude Code 外观、甚至跑 Doom……所有 "pi 默认不做" 的事,都在 extension 层完成。
■ Skills · Prompt Templates · Themes
Skills(按需注入的能力包)
~/.pi/agent/skills/my-skill/SKILL.md ← 主入口(带 description)
~/.pi/agent/skills/my-skill/... ← 任意辅助文件
遵循 agentskills.io 标准。模型可被指示"在 X 情况下加载这个 skill",也可手动 /skill:name。core/skills.ts 负责发现与注入。
Prompt Templates(可参数化的提示)
~/.pi/agent/prompts/review.md
<!-- {{focus}} 可注入参数 -->
用 /review 触发;core/prompt-templates.ts 负责扫描与展开。
Themes(可热重载)
~/.pi/agent/themes/my-theme.json ← 主题颜色与样式
← 修改后立即生效,无需重启
内置 dark / light。Schema 在 modes/interactive/theme/theme-schema.json。
■ Interactive TUI 的内部
Interactive 模式自己就是一整套 TUI 框架——30+ 自研组件、theme runtime、彩蛋角色(armin / daxnuts)……
| 核心组件 | 作用 |
|---|---|
interactive-mode.ts (186KB) | ★★ 全屏 TUI 的装配中心:编辑器、消息流、状态栏、模态选择器之间的协调。 |
tree-selector.ts (43KB) | 实现 /tree 的会话树导航、搜索、过滤、键位。 |
session-selector.ts (33KB) | /resume 视图,跨项目浏览所有历史会话。 |
settings-selector.ts (18KB) | /settings 的可视化编辑器。 |
config-selector.ts (19KB) | pi config 启用/禁用资源的视图。 |
model-selector.ts · scoped-models-selector.ts | 模型选择(Ctrl+L)与作用域设置(Ctrl+P 循环范围)。 |
tool-execution.ts · bash-execution.ts · diff.ts | 工具调用结果的渲染(含 diff 高亮、ANSI 处理)。 |
footer.ts | 状态栏:cwd / session / token / cost / context% / model。 |
下一篇 → 03 · 运行时 · 状态机 · 流程:进入
agent-session.ts 内部,看一次对话从用户敲下 Enter 到模型回包是怎么流动的,以及 Compaction、RPC 协议、Extension 生命周期。