第 5 章:可定制化——模板、技能、扩展、主题与包

内核做减法,生态做加法。

设计思想

Pi 的核心仅提供最基础的四种工具(read、write、edit、bash),所有高级能力均通过插件机制以“按需加载、可共享”的形式提供。这样做既保持了内核的简洁与安全,又使社区能够贡献和复用功能,用户可以根据实际需求只加载所需的插件,避免功能冗余。

原理

Pi 支持五类可定制资源,均约定了放置位置与激活方式:

  1. Prompt Templates(提示模板)

    • 位置:~/.pi/agent/prompts/(全局)、项目内 .pi/prompts/(需项目受信),或 pi 包内。
    • 格式:Markdown 文件,支持变量占位如 {{focus}}
    • 激活:在编辑器输入 /模板名 展开;亦可用 --prompt-template <path> 显式加载。
  2. Skills(Agent Skills 标准)

    • 位置:~/.pi/agent/skills/~/.agents/skills/.pi/skills/.agents/skills/(从 cwd 向上)或 pi 包内。
    • 每个 skill 是一个包含 SKILL.md(说明)以及可选实现(脚本、工具)的目录。
    • 激活:/skill:skillname 查看说明并按步骤操作;部分 skill 能被 agent 自动加载以响应特定关键词。
  3. Extensions(TypeScript 扩展)

    • 位置:~/.pi/agent/extensions/.pi/extensions/ 或 pi 包内。
    • 导出一个函数 export default function (pi: ExtensionAPI) { ... },可注册工具、命令、键绑定、事件处理器、UI 组件等。
    • 启动时自动加载;修改后可通过 /reload 热重载。
  4. Themes(主题)

    • 内置 darklight;自定义主题是 JSON 文件(定义 varscolors 等 token),不是 CSS。
    • 位置:~/.pi/agent/themes/*.json.pi/themes/*.json(需受信)、pi 包内,或 --theme <path> 指定。
    • 修改活动主题文件后即时热重载;首次运行时 pi 会根据终端背景自动选 dark/light。
  5. Pi Packages(分发单元)

    • 通过 npm 或 git 分发,内部可包含任意种类的上述资源。
    • package.json 中加入 pi 字段,例如:
      {
        "name": "my-pi-package",
        "keywords": ["pi-package"],
        "pi": {
          "extensions": ["./extensions"],
          "skills": ["./skills"],
          "prompts": ["./prompts"],
          "themes": ["./themes"]
        }
      }
      
    • 安装命令:pi install npm:<package>(或 git:<url>);
    • 项目局部安装使用 -l 参数安装到 .pi/npm/.pi/git/,同样受项目信任控制。
    • 安装后,可通过 pi config 启用/禁用其提供的资源,或直接使用其 skill/extension。

用法

  • 创建 Prompt

    mkdir -p ~/.pi/agent/prompts
    echo 'Review this code for bugs. Focus: {{focus}}' > ~/.pi/agent/prompts/review.md
    

    然后在对话中输入 /review 展开模板(变量会按模板定义提示填充)。

  • 安装 Skill: 将技能目录(如 my-skill/,内含 SKILL.md)复制到 ~/.pi/agent/skills/,使用 /skill:my-skill 查看说明并按照步骤操作。

  • 开发 Extension: 新建 ~/.pi/agent/extensions/hello.ts(官方 API 签名):

    import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
    
    export default function (pi: ExtensionAPI) {
      pi.registerCommand("hello", {
        description: "Say hello",
        handler: async (args, ctx) => {
          ctx.ui.notify(`Hello ${args || "world"}!`, "info");
        },
      });
    }
    

    测试:pi -e ./hello.ts 临时加载,或放入 extensions 目录后 /reload,即可使用 /hello。注册 LLM 可调用的工具用 pi.registerTool({ name, description, parameters, async execute(...) })

  • 切换主题: 通过 /settings 选择,或在 settings.json 里设 "theme": "my-theme";单次运行可用 pi --use-theme light(还支持 light/dark 跟随终端外观)。

  • 使用 Pi Package

    pi install npm:@foo/pi-tools
    pi config   # 启用新包提供的资源(如有需要)
    # 然后直接使用该包提供的 skill、extension 等
    
  • 项目级定制: 在项目中建立 .pi/skills/, .pi/prompts/, .pi/extensions/.pi/themes/ 等目录,放置对应资源。这些资源仅在该项目(及其子目录)被信任时才会加载,受 ~/.pi/agent/trust.json 控制。

  • 调试与重载: 修改任何本地资源后,运行 /reload 让 Pi 重新读取 extensions、skills、prompts、themes 及 keybindings,无需重启整个程序。