跳转到主要内容

15 Pi 包

pi 包的安装管理、三种来源、创建方法、目录结构、依赖与过滤配置。

pi 可以帮你创建 pi 包。可以让它把你的扩展、技能、提示词模板或主题打包。

Pi 包把扩展、技能、提示词模板和主题打包在一起,让你可以通过 npm 或 git 分享它们。一个包可以在 package.json 的 pi 键下声明资源,也可以使用约定目录。

目录

安装与管理

安全提示: Pi 包以完整的系统权限运行。扩展会执行任意代码,技能可以指示模型执行任何操作,包括运行可执行文件。安装第三方包之前,请先审查其源代码。

pi install npm:@foo/bar@1.0.0
pi install git:github.com/user/repo@v1
pi install https://github.com/user/repo  # raw URLs work too
pi install /absolute/path/to/package
pi install ./relative/path/to/package

pi remove npm:@foo/bar
pi list                     # show installed packages from settings
pi update                   # update pi only
pi update --all             # update pi, update packages, and reconcile pinned git refs
pi update --extensions      # update packages and reconcile pinned git refs only
pi update --models          # refresh model catalogs only
pi update --self            # update pi only
pi update --self --force    # reinstall pi even if current
pi update npm:@foo/bar      # update one package
pi update --extension npm:@foo/bar

这些命令管理 pi 包,其中 pi update 还能更新 pi CLI 本身。对于实验性的安装器托管安装,pi update 会把确切的已检出版本安装到一个分阶段的、由锁文件支撑的发布中,并且只有在验证通过后才激活它;更新失败时当前发布保持不变。托管安装不支持 --force;要修复请重新运行安装器。要卸载 pi 本身,请参阅快速开始。

默认情况下,install 和 remove 写入用户设置(~/.pi/agent/settings.json)。使用 -l 可以改为写入项目设置(.pi/settings.json)。项目设置可以与团队共享;项目受信任之后,pi 会在启动时自动安装缺失的包。

要临时试用一个包而不正式安装,可以使用 --extension 或 -e。这只会在本次运行中安装到临时目录:

pi -e npm:@foo/bar
pi -e git:github.com/user/repo

包来源

Pi 在设置和 pi install 中接受三种来源类型。

npm

npm:@scope/pkg@1.2.3
npm:pkg
  • 带版本号的规格会被固定,包更新(pi update --extensions、pi update --all)会跳过它们。
  • 用户级安装位于 ~/.pi/agent/npm/ 之下。
  • 项目级安装位于 .pi/npm/ 之下。
  • 在 settings.json 中设置 npmCommand,可以把 npm 包查找和安装操作固定到某个特定的包装命令,例如 mise 或 asdf。

示例:

{
  "npmCommand": ["mise", "exec", "node@20", "--", "npm"]
}

git

git:github.com/user/repo@v1
git:git@github.com:user/repo@v1
https://github.com/user/repo@v1
ssh://git@github.com/user/repo@v1
  • 不带 git: 前缀时,只接受带协议的 URL(https://、http://、ssh://、git://)。
  • 带 git: 前缀时,接受简写格式,包括 github.com/user/repo 和 git@github.com:user/repo。
  • HTTPS 和 SSH URL 都受支持。
  • SSH URL 会自动使用你配置的 SSH 密钥(遵循 ~/.ssh/config)。
  • 在非交互运行(例如 CI)中,可以设置 GIT_TERMINAL_PROMPT=0 来禁用凭据提示,并设置 GIT_SSH_COMMAND(例如 ssh -o BatchMode=yes -o ConnectTimeout=5)以便快速失败。
  • ref 是固定的 tag 或 commit。pi update --extensions 和 pi update --all 不会把它们移动到更新的 ref,但会把已有克隆对账到配置的 ref。
  • 使用 pi install git:host/user/repo@new-ref 可以更新设置,并把已有包移动到新的固定 ref。
  • 克隆到 ~/.pi/agent/git/<host>/<path>(全局)或 .pi/git/<host>/<path>(项目)。
  • 当对账改变了检出内容时,pi 会重置并清理克隆,然后在存在 package.json 时运行 npm install。

SSH 示例:

# git@host:path shorthand (requires git: prefix)
pi install git:git@github.com:user/repo

# ssh:// protocol format
pi install ssh://git@github.com/user/repo

# With version ref
pi install git:git@github.com:user/repo@v1.0.0

本地路径

/absolute/path/to/package
./relative/path/to/package

本地路径指向磁盘上的文件或目录,会被加入设置而不做复制。相对路径相对于其所在的设置文件解析。如果路径是文件,则作为单个扩展加载;如果是目录,pi 会按照包规则加载其中的资源。

创建 Pi 包

在 package.json 中添加 pi 清单,或使用约定目录。加上 pi-package 关键字便于被发现。

{
  "name": "my-package",
  "keywords": ["pi-package"],
  "pi": {
    "extensions": ["./extensions"],
    "skills": ["./skills"],
    "prompts": ["./prompts"],
    "themes": ["./themes"]
  }
}

路径相对于包根目录。数组支持 glob 模式和 ! 排除项。清单中的正向 glob 会按字典序发现可见路径。以点开头的路径需要直接列出。如果某个 glob 需要穿越符号链接继续匹配,请直接列出该符号链接指向的资源根目录。

包展示页会展示带有 pi-package 标签的包。添加 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 优先。

包结构

约定目录

如果没有 pi 清单,pi 会从这些目录自动发现资源:

  • extensions/ 加载 .ts 和 .js 文件
  • skills/ 递归查找 SKILL.md 文件夹,并把顶层的 .md 文件作为技能加载
  • prompts/ 加载 .md 文件
  • themes/ 加载 .json 文件

依赖

第三方运行时依赖应放在 package.json 的 dependencies 中。不注册扩展、技能、提示词模板或主题的依赖也属于 dependencies。当 pi 从 npm 或 git 安装一个包时,会运行 npm install,因此这些依赖会被自动安装。

Pi 为扩展和技能打包了核心包。如果你导入了其中任何一个,请把它们列在 peerDependencies 中并使用 "*" 范围,而且不要打包它们:@earendil-works/pi-ai、@earendil-works/pi-agent-core、@earendil-works/pi-coding-agent、@earendil-works/pi-tui、typebox。

其他 pi 包必须打包进你的 tarball。把它们加入 dependencies 和 bundledDependencies,然后通过 node_modules/ 路径引用它们的资源。Pi 加载包时使用各自独立的模块根,因此分开安装的包不会冲突,也不会共享模块。

示例:

{
  "dependencies": {
    "shitty-extensions": "^1.0.1"
  },
  "bundledDependencies": ["shitty-extensions"],
  "pi": {
    "extensions": ["extensions", "node_modules/shitty-extensions/extensions"],
    "skills": ["skills", "node_modules/shitty-extensions/skills"]
  }
}

包过滤

在设置中使用对象形式,可以过滤一个包加载的内容:

{
  "packages": [
    "npm:simple-pkg",
    {
      "source": "npm:my-package",
      "extensions": ["extensions/*.ts", "!extensions/legacy.ts"],
      "skills": [],
      "prompts": ["prompts/review.md"],
      "themes": ["+themes/legacy.json"]
    }
  ]
}

+path 和 -path 是相对于包根目录的精确路径。

  • 省略某个键表示加载该类型的全部资源。
  • 使用 [] 表示不加载该类型的任何资源。
  • !pattern 排除匹配项。
  • +path 强制包含某个精确路径。
  • -path 强制排除某个精确路径。
  • 过滤器叠加在清单之上,只会收窄已经允许的范围。

启用与禁用资源

使用 pi config 可以启用或禁用来自已安装包和本地目录的扩展、技能、提示词模板和主题。pi config 默认从全局设置(~/.pi/agent/settings.json)开始;按 Tab 可以在全局与项目级模式之间切换。使用 pi config -l 可以从项目覆盖(.pi/settings.json)开始,继承自全局的资源会以暗淡方式显示。

作用域与去重

包可以同时出现在全局和项目设置中。如果同一个包同时出现在两处,项目条目优先,除非项目条目设置了 autoload: false,此时它作为对全局条目的增量应用。包的同一性由以下方式确定:

  • npm:包名
  • git:不带 ref 的仓库 URL
  • 本地路径:解析后的绝对路径