仓库 scripts 脚本
TL;DR:根目录
scripts/是整个 monorepo 的工程化工具箱,大部分脚本不需要手动调用,而是挂在根package.json的 npm script、husky pre-commit 钩子或 GitHub Actions 上。按用途分五类:提交和 CI 时自动跑的检查、发版与发布、模型目录维护、打包与产物验证、本地开发与会话分析。理解这些脚本的价值不在于记住名字,而在于看出仓库在防什么:依赖漂移、包边界被破坏、发布产物装不上、模型目录让旧客户端崩溃。
怎么分组
判断一个脚本属于哪类,看它被谁触发。npm run check 和 pre-commit 触发的是门禁,任何人提交都会跑;release:*、publish 只有维护者发版时用;模型目录脚本服务于 pi-ai 的内置模型数据和 pi.dev 的目录服务;打包脚本在 CI 和本地发版演练里验证"发布出去的东西真能装、真能跑";剩下的是开发者按需运行的小工具。另有几个没有入口的 .mjs 是被其他脚本 import 的公共库(如 package-files.mjs、package-workspaces.mjs、release-packages.mjs、npm-command.mjs),以及与之配套的 *.test.mjs,由 npm run test:scripts 统一跑,这里不逐个列出。
提交与 CI 时自动运行的检查
pre-commit 钩子先跑 check-lockfile-commit.mjs,再跑 npm run check,涉及 ai 包或锁文件时追加浏览器冒烟。check 链路的设计见 Monorepo 工程化。
check-lockfile-commit.mjs:发现暂存的锁文件里有包版本变化时阻止提交,除非设置PI_ALLOW_LOCKFILE_CHANGE=1。biome-check.mjs(+biome/model-type-comparison.grit):包装biome check --error-on-warnings,在没有原生二进制的 Android/Termux 上回退到 WASM;.grit是仓库自定义的 lint 规则。check-pinned-deps.mjs:所有package.json的直接依赖必须是精确版本。check-runtime-deps.mjs:用 TypeScript 7 的 AST API 扫描公开包源码,运行时 import 的包必须在本包dependencies里声明,也不允许通过 import 把 tsconfig 排除的文件拉回构建。check-ts-relative-imports.mjs:检查相对导入写法(源码统一写.ts后缀)。check-entry-graphs.mjs:每个导出入口有模块图预算,防止一个export *让窄入口拖进整个 barrel。generate-coding-agent-install-lock.mjs --check:确认packages/coding-agent/install-lock/与根锁文件同步;不带--check时重新生成(npm run install-lock:coding-agent)。check-browser-smoke.mjs:用 esbuild 打包browser-smoke-entry.ts、durable-browser-smoke-entry.ts、agent-treeshake-smoke-entry.ts,抓误引入的 Node-only 模块,并验证只用一个 provider 时 agent 能被 tree-shake。npm-audit.mjs:CI 定期跑npm audit --omit=dev,被接受的漏洞必须写明包名和不适用理由。
发版与发布
release.mjs(npm run release:patch|minor|major或指定x.y.z):完整发版流程。检查工作区干净,确认所有公开包已在 npm 注册,为 Nix 钉住最新模型目录并构建,升版本,把各 CHANGELOG 的[Unreleased]改成版本号,重新生成产物,跑检查和测试,提交并打 tag,再加回新的[Unreleased],最后推送 main 和 tag,由 CI 完成真正的 npm 发布。sync-versions.js:被version:*调用,校验所有公开包版本一致(lockstep),并把内部依赖改成精确的新版本号。publish.mjs(npm run publish、publish:dry):逐个包检查是否已发布、再npm publish,--dry-run只做验证。publish-release-announcement.mjs:npm 发布后,从 registry 解析刚发布的包,更新 pi.dev 上releases/v1与安装器installer/v1的指针,带重试。release-notes.mjs:从 CHANGELOG 提取某版本的 GitHub Release 说明;npm run release:fix-links修复历史 Release 中的仓库链接。create-source-archive.sh:生成随 GitHub Release 上传的确定性源码包(需先 hydrate 模型数据)。preview-packages.mjs:CI 里把内部依赖指向本次提交的构建、npm pack所有公开包,发布到 pkg.earendil.com 作为预览版本。
模型目录
pi-ai 的内置模型数据由 packages/ai/catalog/generate.ts 从上游生成,同一份目录也以 JSON 形式由 pi.dev 分发给已发布的客户端。根目录这几个脚本负责其中"跨仓库、跨版本"的部分:
model-catalog-protocol.ts:pi 与 pi.dev 共享的目录协议(存储布局、索引格式、版本排序),两个仓库各一份,必须逐字节一致。model-catalog-minimum-version.mjs:能收到本仓库所发布目录的最低 pi 版本;只有生成的模型元数据依赖旧客户端没有的行为时才上调。check-model-catalog-compat.mjs(npm run check:model-catalog-compat):发布前确认已发布的 pi 版本能使用即将发布的目录。pi.dev 会把目录直接推给所有不低于最低版本的客户端,客户端不更新也会立刻使用,所以目录一旦需要新代码就会让旧版崩溃,这个检查就是防这个。publish-model-catalog.mjs:把生成的 JSON 目录按协议发布;npm run check:model-catalog是它的 dry-run。update-model-catalog-pin.mjs:查询最新发布的目录,更新nix/model-catalog.json里钉住的 revision(sha256),供 Nix 离线构建使用。diff-model-catalog.mjs(npm run diff:model-catalog):在 HEAD 和工作区各生成一次目录,打印 JSON 差异;--thinking借助generate-thinking-capabilities.mjs比较各模型的有效 thinking 等级。
打包与产物验证
pack-packages.mjs(npm run pack:packages):构建所有公开包,输出一组一致的本地产物(.artifacts/),可用--offline-model-data离线构建;底层逻辑在package-artifacts.mjs。check-package-install.mjs(npm run check:package-install):把每个包单独装进一个临时消费者项目,做导入冒烟测试,local-package-install.mjs提供安装逻辑,coding-agent-smoke.mjs负责 coding-agent 的启动冒烟。local-release.mjs(npm run release:local):本地发版演练,打包后装进仓库外的隔离目录做测试。use-local-packages.mjs:把外部项目(npm 或 pnpm)的依赖改指向本地产物,用于在真实下游项目里试用未发布的改动。build-coding-agent-bundle.mjs:coding-agentbuild的第二步,用 esbuild 打出dist/bundle/cli.js。build-binaries.sh:本地复现.github/workflows/build-binaries.yml,为各平台构建 Bun 单文件二进制;smoke-test-codemode-binary.mjs在 CI 里验证编译后的二进制能启动 codemode worker。
本地开发与分析工具
auto-pi.sh:用本仓库最近一次npm run build的产物运行 pi,默认开启PI_EXPERIMENTAL=1,--stable改用 PATH 上的正式版。profile-coding-agent-node.mjs(npm run profile:tui|rpc):分析 coding-agent 在 TUI 或 RPC 模式下的启动性能。stats.ts、cost.ts:从本地会话文件统计 token 用量和成本。tool-stats.ts、read-tool-stats.mjs、edit-tool-stats.mjs:分析各工具的调用次数与 token 消耗、read 的读取模式、edit 的成功率等,用来评估工具设计。session-context-stats.mjs、session-transcripts.ts:分析上下文窗口使用和压缩频率;把某个 cwd 的会话抽成按上下文大小切分的文本,可选择启动 pi 子 agent 分析模式。update-source-imports-to-ts.sh:把源码相对导入从.js批量改成.ts(编译时rewriteRelativeImportExtensions再改回.js),是迁移时用的一次性工具。repro-5893-wsl-bash.mjs:在 Windows + WSL bash 下复现 issue #5893 的变量展开问题。issues/:每日 issue 分诊的本地工具,用gh api同步 issue,再让一个 pi-durable agent 逐个查重、分类、建议优先级,结果只存本地,通过一个 Web UI 审阅。它本身就是 Pi 自家库的一个真实用例。
源码入口(v1.5):package.json、.husky/pre-commit、scripts/release.mjs、scripts/check-entry-graphs.mjs、scripts/check-model-catalog-compat.mjs、scripts/package-artifacts.mjs