01 · 从源码运行 Pi
这一篇先让原项目运行起来:确认源码版本,安装依赖,构建项目,进入 Pi 的终端界面,再连接模型完成一次最小对话。每一步由你在终端手动执行,AI 负责解释和排查报错。
这篇文章依据哪个版本
| 项目 | 本次依据 |
|---|---|
| 操作系统 | macOS;命令适用于当前工作区的 bash / zsh |
| 原始仓库 | earendil-works/pi |
| 本地源码 | /path/to/pi-study/pi,来自 Atmizz/pi |
| 检查时分支 | main |
| 完整 commit SHA | 63bc4da65adc2b45b1674d85a303d5eaefe3ae07 |
| CLI 包版本 | 1.5.0,来自 packages/coding-agent/package.json |
| 编写日期 | 2026-11-06,Asia/Taipei |
| 验证范围 | 已核对本地 README、配置与启动源码;未替你安装 Pi 依赖、构建或启动 Pi,运行结果等待你实际验证 |
后续 main 变化时,以你记录的 SHA 为准。构建期间联网获得的模型目录也可能随时间变化。
先分清三个运行对象
| 对象 | 界面与启动方式 | 本次安排 |
|---|---|---|
| 学习文档站点 | 浏览器;在 c-pi/docs/ 执行 npm run docs:dev | 用来阅读本文 |
| Pi coding agent CLI | 终端交互界面;在 pi/ 执行 bash ./pi-test.sh | 本文主线 |
| p2 | 浏览器应用;在 pi/apps/p2/ 执行 npm start | 文末可选体验 |
仓库根目录 package.json 没有 start 或 dev 脚本,因此不要在 pi/ 直接执行 npm start 或 npm run dev。p2 是另外一个应用,而且当前 README 明确将它标为不受支持、将被替换的实验原型。
我们要运行本地检出的源码,所以无需执行官方安装脚本或全局安装 npm 发布版。即使电脑上已有 pi 命令,本文仍使用仓库里的脚本,保证运行对象明确。
1. 确认目录、分支和版本
执行位置:新开一个终端,进入 pi/。 文档服务所在终端保持运行。
bash
cd /path/to/pi-study/pi
pwd
git status --short --branch
git branch --show-current
git rev-parse HEAD
git remote -v逐条观察:
pwd应以/pi-study/pi结尾。git status --short --branch查看分支与改动;干净工作区不会列出修改文件。git branch --show-current应显示main。如果不是,先查看是否有未完成改动;工作区干净且确定要回main时执行git switch main,再重新检查。git rev-parse HEAD是当前源码的完整 SHA,将它记到本文末尾的操作记录中。origin应指向https://github.com/Atmizz/pi.git。
Fork 与原项目的关系
Fork 仍然可以运行原项目代码。本次使用本地已有版本,不需要为了启动而先拉取上游或配置 upstream。日后的同步与分支比较单独学习,避免在运行途中改变基线。
检查时本地只有 main,尚未发现 pi-1106-2026。这不影响先在 main 完成环境准备,本篇也不要求你现在创建或切换到学习分支。
2. 检查 Node.js 与 npm
执行位置:仍在 pi/。
bash
node --version
npm --version
command -v node
command -v npm仓库声明的 Node.js 最低版本是 22.19.0。请注意 22.9.0 小于 22.19.0,版本号不能按小数比较。
编写时当前终端读到的是 Node.js v26.12.1、npm 11.20.0,满足声明的 Node 要求;这只是工具版本检查,不表示 Pi 已运行成功。你的手动终端若显示不同路径或版本,应以该终端实际环境为准。
如果已经满足要求,继续下一步。如果 node / npm 不存在或 Node 版本不足,先通过你已有的版本管理工具切换到满足要求的版本,再重复检查;不知道该如何切换时,先发回上述输出。
为什么要检查? 入口脚本直接用 Node 执行 TypeScript,依赖 Node 的类型擦除和模块解析能力,旧版本可能在项目代码运行前就失败。
3. 安装源码仓库依赖
执行位置:pi/ 根目录,有 package.json 和 package-lock.json 的位置。
bash
npm ci --ignore-scripts这里使用仓库现有的锁文件进行安装:
ci按锁文件安装,不用一次普通安装去重新选择依赖版本;如果已有node_modules/,它会先将其移除再安装。--ignore-scripts跳过安装生命周期脚本,这是原项目明确采用的安装方式。- 根目录配置了 npm workspaces,会管理多个子包的依赖和本地链接;不需要逐个进入
packages/安装。
安装过程中需要访问 npm 包源。耗时随网络和缓存不同而变化。
成功标志: 命令结束并返回终端提示符,没有以 npm error / npm ERR! 结束;生成根目录的 node_modules/。
安装结束后检查:
bash
git status --shortnode_modules/ 已被源码仓库忽略,正常不会出现在 Git 改动中。
为什么 README 写 npm install,而本文选择 npm ci?
原仓库 README 的开发步骤是 npm install --ignore-scripts;它的 AGENTS.md 同时允许用 npm ci --ignore-scripts 进行干净安装。这里已有锁文件,第一次复现优先保持锁定依赖。
如果 npm ci 报 package.json 与锁文件不一致,先停在这里保留错误。不要立刻删除锁文件或改用其他包管理器;我们先确认当前基线的问题,再决定是否需要使用 README 的安装方式。
4. 构建原项目
执行位置:仍在 pi/ 根目录。
bash
npm run build这条命令按照根目录脚本指定的顺序构建多个包,例如 telemetry → schema → chord → tui → … → ai → … → coding-agent。它会产生各包的 dist/,并为 coding-agent 打包 CLI 和资源。
其中 packages/ai 会先联网获取模型目录,再生成类型包装和模型数据,最后编译。因此「npm 包安装完成」与「可以完全离线构建」是两回事。
成功标志: 所有包的构建命令执行结束,回到终端提示符,过程中没有导致退出的错误。不需要出现一条固定的全局成功文案。
如果失败,不要进入启动步骤,先看错误发生在哪个包、哪条子命令。
模型目录与离线构建
初次构建会从模型目录服务读取数据。生成脚本使用严格模式,某个必需来源请求失败就可能使构建失败;日志会指出具体来源。
只有已经有当前源码所需的有效模型数据时,才适合执行下面的命令:
bash
npm run check:model-data
npm run build:offline前一条成功时会显示 Generated model data is valid.。如果提示数据缺失或过期,需要联网执行:
bash
npm run hydrate:model-data该命令本身仍需要网络;完成后再检查模型数据并执行 npm run build:offline。它不是首次安装遇到网络错误时可以直接跳过下载的捷径。
构建后看一次 Git 改动
bash
git status --short
git diff --statdist/ 和 packages/ai/src/providers/data/ 被忽略;但在线构建可能更新已跟踪的 models.generated.ts 或各 provider 的模型包装文件,因为远端目录可能已变化。
这类变更不一定是你操作错误。先记录和查看,不要直接提交、丢弃或修改生成文件;如有疑问,把路径与差异摘要发回。等确认结果后,再决定怎样保留学习基线。
5. 先用帮助命令验证入口
执行位置:pi/ 根目录。
bash
bash ./pi-test.sh --version
bash ./pi-test.sh --help第一条应输出与该源码基线一致的版本号,本次包配置为 1.5.0;第二条应输出 CLI 帮助。这里不需要先配置模型账号,也不会发送一次正常的模型对话。
pi-test.sh 的名字包含 test,但它是源码运行脚本,不是自动化测试套件。
这条命令如何进入源码
text
bash ./pi-test.sh
→ 定位脚本所在的 Pi 仓库
→ node --import <source-resolver.ts 的 file URL>
<packages/coding-agent/src/cli.ts>
→ setupCli()
→ main(process.argv.slice(2))source-resolver.ts 读取根目录 tsconfig.json 的路径配置,将 @earendil-works/… 内部引用解析到工作区源码,避免误用旧的 dist/ 文件。当前 Node 负责执行 TypeScript。
所以「先完整构建」是本篇采用的仓库开发准备流程,并不表示 pi-test.sh 会运行打包后的 CLI。阅读源码时,始终区分源码入口和发布包入口。
这一节对应:
pi/pi-test.shpi/packages/coding-agent/src/experimental/source-resolver.tspi/packages/coding-agent/src/cli.tspi/packages/coding-agent/src/main.ts
6. 启动终端交互界面
执行位置:仍在 pi/。
bash
bash ./pi-test.shPi 可能先询问是否信任当前项目目录,按提示阅读并选择。启动后应看到终端交互界面,包括对话区域、输入编辑器、当前工作目录和模型等状态信息。
到这里可以先确认「交互界面能启动」。如果尚未登录或没有可用模型,不能据此判断整个项目启动失败;下一步才验证模型连接。
当前进程的工作目录是 pi/,也是 Pi 处理文件、发现项目说明和配置的起点。脚本自身可以从其他目录调用,但不会自动把当前工作目录改成脚本目录。
命令输入到哪里?
npm …、git … 和 bash … 输入到系统终端;下面的 /login、/model、/quit 输入到 Pi 的编辑器中,然后按 Enter。
7. 连接模型并完成首次对话
执行位置:Pi 的交互编辑器。
text
/login选择你已有使用权限的 provider(模型服务提供方),按界面支持的登录方式授权或填写 API key。本文不预设你使用哪个服务,也不写死模型名称。
然后执行:
text
/model选择一个当前账号可用的模型。提交一条足够小的消息:
text
请只回复“Pi 已连接成功”,无需调用工具。成功标志: 收到模型的实际回复,没有鉴权、额度、网络或模型不可用错误。模型输出措辞可能略有不同,重点是请求与回复链路已经打通。
Pi 的配置与会话默认放在 ~/.pi/agent/;登录凭证可写入其中的 auth.json。截图或报错信息中若出现 key、token 或授权链接,应遮盖这些内容再分享。发送模型请求可能消耗该账号的额度。
暂时不连接模型也可以停在上一步,把完成状态记为「CLI 已启动,模型对话待验证」。
8. 退出与下次启动
执行位置:Pi 的交互编辑器。
text
/quit回到系统终端后,下次通常只需:
bash
cd /path/to/pi-study/pi
bash ./pi-test.sh想继续同一个工作目录的最近会话:
bash
bash ./pi-test.sh --continue无需每次都重新安装依赖或完整构建。更新源码、依赖或构建相关资源后,再按变化重新准备。未来进入学习分支前,先处理并记录本轮生成的文件变化,再确认分支基线。
可选:体验 p2 浏览器应用
CLI 主线完成后,如果还想看看仓库内的浏览器界面,再执行本节。p2 在这个基线中是实验原型,README 提示其数据格式和 API 可能无通知变化,且会被替换。
前提:已在 pi/ 安装依赖,并且 npm run check:model-data 通过。若主线构建没有走完,仍需先保证模型数据有效;p2 的 README 要求安装依赖和准备模型数据,不要求完整构建所有包。
执行位置:另开终端,进入 pi/apps/p2/。
bash
cd /path/to/pi-study/pi/apps/p2
npm start默认在 http://127.0.0.1:8788 打开界面;以启动日志为准。npm start 会加载 src/source.ts,运行 src/hosts/server.ts。
若只想先看演示,可以停止服务后改用:
bash
P2_FAKE=1 npm start它使用 fake provider,工具仍可能操作真实文件。演示成功不表示真实模型已连接。p2 的 provider 登录由浏览器中的 Providers 入口管理,凭证保存在 p2 私有数据目录,不应假定它自动复用 CLI 的登录。
默认数据目录是 ~/.pi/p2。默认端口冲突时,可以停止服务后指定另一个端口:
bash
PORT=8789 npm start然后打开 http://127.0.0.1:8789。停止 p2 服务在其终端按 Ctrl+C。本文只体验本机浏览器入口,p2 的远端访问、TUI 客户端和其他部署方式另行学习。
遇到报错时,从失败的步骤继续
| 现象 | 优先确认 |
|---|---|
找不到 package.json 或 Missing script | 执行 pwd;区分 pi/、pi/apps/p2/ 与 c-pi/docs/ 的脚本 |
EBADENGINE、TypeScript 执行或模块钩子错误 | 提供 node --version 与 command -v node,确认手动终端环境 |
npm ci 提示锁文件不一致 | 保留原错误和 SHA,先停止,不删锁文件 |
| npm 安装时超时、连接失败 | 提供实际失败的包源域名、错误码和命令;包源与模型目录是不同网络请求 |
构建时 fetch 或模型目录错误 | 保留失败来源与完整错误;先查 check:model-data,缺数据时不能直接离线构建 |
| 模块、原生二进制或资源缺失 | 提供缺失的具体路径,确认安装与构建是否成功;不直接移除 --ignore-scripts 重装 |
| Pi 界面出现,但无法回复 | 区分 CLI 启动与模型调用;查看 provider、模型选择、鉴权、网络和额度错误 |
p2 的 EADDRINUSE | 端口被占用;先确认是否已运行 p2,或按上面的方式换端口 |
| 终端布局或快捷键不正常 | 记录终端应用、Node 版本及现象;附界面截图继续排查 |
发回信息时可以按这个格式:
text
文章步骤:例如第 4 步,构建原项目
当前目录:pwd 的结果
当前分支与 SHA:git branch --show-current / git rev-parse HEAD
Node 与 npm:node --version / npm --version
执行命令:完整命令
错误:从第一个有效错误开始的完整输出或截图先停在失败处,不需要从头重装。我们会把已经验证的解决办法补回这一篇。
本篇完成标准与操作记录
完成后将下面的记录填入 学习进度,或者把结果发回对话后由 Agent 更新:
text
操作日期:
源码分支与完整 SHA:
Node / npm:
安装结果:
构建结果及生成文件变化:
帮助命令与交互界面:
模型对话结果(不含凭证):
p2(可选):
遇到的问题与已验证解决办法:下一篇再从这次实际走过的启动路径入手,逐层阅读源码并规划最小复现单元。本篇不创建 c-pi/ 的功能代码。
本篇的源码依据
以下链接固定在本文的源码 SHA,便于未来更新 main 后回看。它们对应本地 pi/ 下的同名文件。
- README:Development、AGENTS.md:安装、构建与依赖脚本约定。
- 根 package.json:workspaces、Node 要求和构建顺序。
- pi-test.sh、source-resolver.ts、cli.ts:源码启动链路。
- ai/package.json、模型目录说明:模型生成、数据准备和离线构建。
- Quickstart、交互使用说明、Slash commands:登录、模型选择、会话与退出。
- 配置说明、Provider 说明:配置与凭证位置。
- p2/README.md、p2/package.json:实验状态、浏览器启动、fake provider 与默认端口。