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

# 第 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**(主题)
   - 内置 `dark`、`light`;自定义主题是 **JSON 文件**(定义 `vars`、`colors` 等 token),不是 CSS。
   - 位置:`~/.pi/agent/themes/*.json`、`.pi/themes/*.json`(需受信)、pi 包内,或 `--theme <path>` 指定。
   - 修改活动主题文件后即时热重载;首次运行时 pi 会根据终端背景自动选 dark/light。

5. **Pi Packages**(分发单元)
   - 通过 npm 或 git 分发,内部可包含任意种类的上述资源。
   - 在 `package.json` 中加入 `pi` 字段,例如:
     ```json
     {
       "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**:
  ```bash
  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 签名):
  ```ts
  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**:
  ```bash
  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,无需重启整个程序。