包管理:分享与复用
本教程共 30 篇 · 第 19 篇 · 更新于 2026-08-10 · 约 6 分钟阅读
本节目标:理解 pi Package 是什么、它跟 Extension 和 Skill 的关系是什么、怎么把自己写的东西打包分发给别人、怎么装别人打包好的工具。学完你能把团队的 pi 配置做成一个可复用的 Package。
从 Extension 到 Package:把一堆东西打成一个包
前面你学过了 Extension(扩展)和 Skill(技能包)。它们都是一个一个独立的”能力单元”——一个 Extension 注册几个工具,一个 Skill 提供一套指引。
但实际用起来你会遇到一个问题:一个完整的工具集,往往包含好几个 Extension、几个 Skill、可能还有一些提示词模板。比如你想给团队配一套”前端开发工具包”:一个 Extension 负责检查构建产物,一个 Skill 定义 CSS 最佳实践,两个提示词模板覆盖常用操作。
一个个装太碎、也不好分享。这时候就轮到 Package 出场了。
Package 就是一个”篮子”,把 Extensions、Skills、提示词模板和主题打包在一起,通过 npm 或 git 分发。安装一个 Package,等于同时装上里面包含的全部内容。
NotePackage 和 Extension 不是平级的概念。Extension 是 Package 里的一个”零件”,Package 是容器。一个 Package 可以包含零个或多个 Extension。
Package 长什么样
一个 Package 本质上就是一个 npm 包或 git 仓库,目录里按约定放好资源文件。pi 有两种方式识别包里的内容:
方式一:在 package.json 里声明(推荐)
在 package.json 里加一个 pi 字段,显式告诉 pi 去哪里找资源:
{
"name": "my-frontend-toolkit",
"version": "1.0.0",
"keywords": ["pi-package"],
"pi": {
"extensions": ["./extensions"],
"skills": ["./skills"],
"prompts": ["./prompts"],
"themes": ["./themes"],
"image": "https://example.com/screenshot.png"
}
}
keywords 里加上 "pi-package",你的包就会出现在 pi 官方包画廊 里。image 和 video 字段是可选的,用来在画廊里展示预览。
方式二:靠约定自动发现
如果 package.json 里没有 pi 字段,pi 会自动扫描以下约定目录:
| 目录 | 加载什么 |
|---|---|
extensions/ | .ts 和 .js 文件 |
skills/ | 递归查找包含 SKILL.md 的文件夹 |
prompts/ | .md 文件 |
themes/ | .json 文件 |
小项目用约定目录就够,正式发布推荐显式声明——可读性更好,而且能用 glob 模式做精确控制。
安装别人的 Package
pi 支持三种安装来源:npm、git 仓库、本地路径。
从 npm 安装
npm 是推荐的分发方式。版本号可以锁死也可以省略:
# 安装最新版
pi install npm:@myscope/my-toolkit
# 锁死版本
pi install npm:@myscope/my-toolkit@1.2.3
锁死版本后 pi update --extensions 不会自动升级它——这在团队环境里很有用,防止悄悄引入不兼容的变更。
安装位置:全局包在 ~/.pi/agent/npm/,项目级包在 .pi/npm/。
从 Git 安装
支持 HTTPS、SSH 和 git@ 格式:
# HTTPS
pi install https://github.com/user/repo@v1.0.0
# SSH(git@ 格式需要 git: 前缀)
pi install git:git@github.com:user/repo@v1.0.0
# ssh:// 协议
pi install ssh://git@github.com/user/repo@v1.0.0
Git 包的 ref(tag 或 commit)会被锁定。想切新版本需要手动跑 pi install 指定新 ref。
从本地路径安装
开发阶段还没发布到 npm,可以用本地路径直接引:
pi install /absolute/path/to/my-package
pi install ./relative/path/to/my-package
本地路径不会复制文件,pi 直接读原目录。改代码马上生效,调试很方便。
项目级安装 vs 全局安装
大多数 pi install 写的是全局配置(~/.pi/agent/settings.json)。加上 -l 参数则写到项目配置(.pi/settings.json):
pi install -l npm:@myscope/my-toolkit
项目级配置可以提交到 git,团队成员 clone 代码后 pi 会自动安装缺失的包。这是团队协作的标准做法。
临时试用一个包而不想写配置,用 -e 或 --extension:
pi -e npm:@myscope/my-toolkit
这会把包装到临时目录,当前会话结束后不保留。
自己做一个 Package
来走一遍完整流程。假设你想做一个”代码审查包”,包含一个 Extension 和一个 Skill。
第一步:创建项目结构
code-review-kit/
├── package.json
├── extensions/
│ └── review.ts
├── skills/
│ └── code-review/
│ └── SKILL.md
└── prompts/
└── review-checklist.md
第二步:写 package.json
{
"name": "code-review-kit",
"version": "1.0.0",
"keywords": ["pi-package"],
"pi": {
"extensions": ["./extensions"],
"skills": ["./skills"],
"prompts": ["./prompts"]
}
}
第三步:写 Extension
extensions/review.ts:
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.registerCommand("review", async (ctx) => {
await ctx.session.prompt("请审查刚才的代码改动,重点关注安全问题和性能瓶颈。");
});
}
第四步:写 Skill
skills/code-review/SKILL.md:
---
name: code-review
description: 代码审查指南,帮助检测常见安全和性能问题。
---
# 代码审查清单
审查代码时请关注:
- SQL 注入和 XSS 风险
- 未处理的异常
- N+1 查询
- 不必要的重渲染
第五步:发布
如果有 npm 账号,发布就是正常的 npm 流程:
npm publish
没有 npm 账号或者内部使用,推到 GitHub 然后让同事用 git 方式安装也一样。
依赖怎么管
如果你的 Package 里用了第三方 npm 包(比如 Extension 里 import 了一个工具库),把它们写在 dependencies 里。pi 安装包时会自动跑 npm install。
有五个核心包是 pi 自身提供的,不要在 Package 里重复打包。把它们列为 peerDependencies:
| 包名 | 说明 |
|---|---|
@earendil-works/pi-ai | AI 工具和类型 |
@earendil-works/pi-agent-core | Agent 核心 |
@earendil-works/pi-coding-agent | pi 主包 |
@earendil-works/pi-tui | TUI 组件 |
typebox | 参数 Schema 定义 |
如果你的 Package 依赖了另一个 pi Package(比如”前端工具包”依赖”通用工具包”),需要在 dependencies 和 bundledDependencies 里都声明它,然后在 pi.extensions 和 pi.skills 中通过 node_modules/ 路径引用。
精确控制:包过滤
有时候你只想用别人包里的一部分内容。比如某包带了 5 个 Extension,你只想要其中 2 个。
在 settings.json 的 packages 数组里用对象形式声明过滤规则:
{
"packages": [
"npm:simple-pkg",
{
"source": "npm:big-package",
"extensions": ["extensions/*.ts", "!extensions/legacy.ts"],
"skills": ["skills/brave-search"],
"prompts": [],
"themes": []
}
]
}
规则说明:
- 省略某个键 → 该类型全部加载
[]→ 该类型一个不加载!pattern→ 排除匹配项+path→ 强制包含-path→ 强制排除
过滤建立在 manifest 声明之上——先让包的 manifest 圈定范围,再在这个范围内过滤。想加载 manifest 之外的内容是做不到的。
用 pi config 管理已装资源
装完包之后,你可能想临时关掉某个 Extension 或者换一个 Skill。pi config 提供了交互式的开关界面:
# 编辑全局配置
pi config
# 编辑项目配置
pi config -l
Tab 键在全局模式和项目模式之间切换。操作跟之前学过的用 pi config 管理 Extension 和 Skill 完全一样,只是现在多了一层”按包管理”的视角。
关于安全:看一眼源码再装
Package 里的 Extension 是能执行任意代码的,Skill 也能引导模型做各种操作——包括跑命令、读写文件。
Note安装第三方的 Package 之前,花十分钟看一眼源码。至少扫一遍 Extension 的代码,确认它没有做你不希望它做的事。pi 官网的包画廊只是一个展示平台,不意味着 pi 团队审核过其中每一个包。
团队协作的标准玩法
项目级安装 + git 提交配置,是团队协作的推荐模式:
# 在项目根目录执行
pi install -l npm:ui-component-skill-pack
这会在 .pi/settings.json 中写入包引用。把这个文件提交到 git:
git add .pi/settings.json
git commit -m "add ui-component-skill-pack to project"
其他团队成员 pull 代码后,第一次在项目下启动 pi 时,pi 检测到未安装的包会自动补齐。不用每个人手动装一遍。
Tip
.pi/目录下还有 git clone 的包缓存(.pi/npm/和.pi/git/),这些不该进版本控制。记得在.gitignore里加上.pi/npm/和.pi/git/。