两种声明方式
一个 Pi Package 的资源,可以二选一声明:
- 在
package.json里写一个pi键,显式列出各资源路径 - 用约定目录,pi 自动发现
两者可以混用,但记住:显式 pi 键是更可控的生产级选择,约定目录是偷懒时的兜底。
md-tools 的包结构,从这一节开始真正成型。你要决定它用 pi 键还是约定目录、把哪类资源放哪。**建议直接上手 pi 键——因为它能精确控制哪些文件进包、哪些不进,这对分发干净很关键。** 现在就把 md-tools 的资源分类想清楚:扩展放哪、技能放哪、主题放哪。方式一:package.json 的 pi 键
在 package.json 里加一个 pi 字段,声明四类资源的路径。路径相对包根目录,数组支持 glob 和 ! 排除:
{
"name": "my-package",
"keywords": ["pi-package"],
"pi": {
"extensions": ["./extensions"],
"skills": ["./skills"],
"prompts": ["./prompts"],
"themes": ["./themes"]
}
}
加 pi-package 这个 keyword 很重要——包画廊(gallery)靠它来收录和展示你的包。
方式二:约定目录
如果 package.json 里没有 pi 键,pi 会自动从这些约定目录发现资源:
| 目录 | 加载什么 |
|---|---|
extensions/ |
.ts 和 .js 文件 |
skills/ |
递归找 SKILL.md 文件夹,顶层 .md 文件当技能 |
prompts/ |
.md 文件 |
themes/ |
.json 文件 |
一个极简包的目录结构大概长这样:
md-tools/
├── package.json
├── extensions/
│ └── index.ts
├── skills/
│ └── md-convert/SKILL.md
├── prompts/
│ └── normalize.md
└── themes/
└── md-tools.json
画廊元数据:让别人一眼看懂
想让包在画廊里更好看,加 video 或 image 字段显示预览:
{
"name": "my-package",
"keywords": ["pi-package"],
"pi": {
"extensions": ["./extensions"],
"video": "https://example.com/demo.mp4",
"image": "https://example.com/screenshot.png"
}
}
video只支持 MP4,桌面端悬停自动播放image支持 PNG / JPEG / GIF / WebP,作静态预览- 两个都设时,video 优先
依赖声明:peerDependencies vs bundledDependencies
这一节最容易踩坑的就是依赖。三句关键话:
- 第三方运行时依赖放
dependencies,pi 装包时自动跑npm install @earendil-works/pi-*这套核心包不要打包,改成peerDependencies用"*"范围——pi 已经内置了它们- 其他 pi 包必须打进你的 tarball,用
bundledDependencies
{
"dependencies": {
"shitty-extensions": "^1.0.1"
},
"bundledDependencies": ["shitty-extensions"],
"pi": {
"extensions": ["extensions", "node_modules/shitty-extensions/extensions"],
"skills": ["skills", "node_modules/shitty-extensions/skills"]
}
}
核心包清单(用 peerDependencies,别打包):@earendil-works/pi-ai、@earendil-works/pi-agent-core、@earendil-works/pi-coding-agent、@earendil-works/pi-tui、typebox。
落地练习:给 md-tools 写 package.json
动手写 md-tools 的包骨架:
- 建
md-tools/目录,初始化package.json(name: "md-tools",加keywords: ["pi-package"]) - 写上
pi键,声明extensions、skills、prompts、themes四个路径 - 在里面放好约定目录(可以先放占位文件),确认路径和目录对得上
怎么判断做对了?——
pi install ./md-tools能装上,pi list能看到四类资源各就各位;如果哪类没加载,多半是路径写错或目录命名不对。
卡住了怎么办? 资源没加载?先用约定目录(不写 pi 键)跑通一遍,再改成显式 pi 键。依赖报错?回想上面的「核心包放 peerDependencies」规则。
常见坑:把 pi 核心包打进 dependencies
最常见的依赖错误,是把 @earendil-works/pi-coding-agent 这类核心包写进 dependencies,自己打包一份。
后果是:版本冲突、重复加载、行为诡异。正确做法是让它们当 peerDependencies(范围 "*"),因为 pi 运行时已经内置了。你能打包的是「你自己的代码」,不是 pi 自己。 这个边界理不清,包会越做越乱。
小结
- 资源声明两种方式:
package.json的pi键,或约定目录 - 加
pi-packagekeyword 才会进画廊 - 画廊可用
video/image显示预览 - 第三方依赖进
dependencies,pi 核心包进peerDependencies - 其他 pi 包用
bundledDependencies打进 tarball
下一节,我们讲怎么安装、管理和最终发布这个包。