# Pi Subagent

[English](README.md) | 简体中文

给 Pi 配置可复用的专用助手，用于代码审查、资料调研等任务。每个助手都在独立的 Herdr 标签页中工作，将结果发回主对话，不继承主对话的聊天记录。

一份 **profile（角色配置）** 定义助手的指令、工具，以及可选的技能和模型。你可以手动调用，也可以让主 Pi 自行委派任务。

## 安装

需要 **Node.js 22.19+**、**[Pi](https://pi.dev) 1.2.0+** 和 **Herdr**。启动助手时，Pi 必须运行在 Herdr 工作区中，并且能调用 `herdr` 命令。

```bash
pi install npm:@oldflag2333333/pi-subagent
```

安装后重启 Pi，或执行 `/reload`。Pi Subagent 使用 Pi 已有的模型服务凭据，请先确认 Pi 能正常对话。

后续更新：

```bash
pi update npm:@oldflag2333333/pi-subagent
```

更新后同样需要重启 Pi 或执行 `/reload`。

## 快速上手：代码审查助手

Pi Subagent 不附带内置角色。先创建一个：

```bash
mkdir -p ~/.pi/agent/subagent/profiles/reviewer
```

将以下内容保存为 `~/.pi/agent/subagent/profiles/reviewer/config.json`：

```json
{
  "version": 1,
  "name": "reviewer",
  "description": "检查代码中的缺陷和测试遗漏，不修改文件。",
  "tools": ["read", "grep", "find", "ls"]
}
```

在同一目录下创建 `instructions.md`：

```markdown
检查指定代码中的缺陷、回归风险和测试遗漏。
不要修改文件。报告具体、可操作的问题，并附上文件路径和行号。
如果没有发现明显问题，请明确说明，并指出尚未验证的部分。
```

在 Pi 中执行 `/reload`，然后输入：

```text
/sub:reviewer 检查 src/auth 中的认证代码。
```

将 `src/auth` 替换为你项目中的路径。审查助手会在独立的 Herdr 标签页中启动，并将结果发回主对话。等待期间，你可以继续处理其他工作。

也可以直接让主 Pi 委派：

```text
让 reviewer 检查 src/auth 中的缺陷和测试遗漏。
```

## 日常使用

| 你想做什么 | 操作方式 |
| --- | --- |
| 查看可用角色或配置错误 | `/profiles` |
| 启动助手，或给它追加任务 | `/sub:reviewer <任务>` |
| 让 Pi 选择助手 | 告诉 Pi 将任务委派给合适的角色 |
| 查看进度 | 让 Pi 列出子助手，或打开助手的 Herdr 标签页 |
| 停止当前任务，但保留助手会话 | 让 Pi 中断该子助手 |
| 结束使用 | 让 Pi 关闭子助手，或手动关闭其 Herdr 标签页 |
| 清理已删除 Main 遗留的 Sub 会话和通信文件 | `/clean-sub` |

在同一个主会话（Main）中，多次调用 `/sub:reviewer` 会复用该角色已打开的子助手（Sub）。如果它正在工作，新任务会排队。任务完成后，标签页不会自动关闭。

**Sub-agents（子助手）** 列表只显示当前 Main 创建的助手：**Open** 包含所有已打开的子助手，包括空闲或状态未知的；**Resumable** 包含已确认关闭、且保存文件仍存在的持久化会话。其他 Main 或分叉会话不会继承这些助手，也不能恢复它们。重载或恢复同一个 Main 则会保留关联。

如果想将角色应用到当前 Pi，而不是打开子助手，可以这样启动：

```bash
pi --profile reviewer
```

不传入 `--profile` 时，Pi 原有的工具、模型和技能配置保持不变。

## 自定义角色

### 配置放在哪里

- **个人配置：** `~/.pi/agent/subagent/profiles/<name>/`
- **项目配置：** 项目或其上级目录中的 `.pi/subagent/profiles/<name>/`，仅在项目信任后加载。

每个目录都需要一份 `config.json`，其中的 `name` 必须与目录名一致。距离当前工作目录更近的项目配置会替换上级目录或个人目录中的同名角色，不会合并字段。旧式的 `<name>.json` 单文件配置仍然受支持。

### 角色指令

将角色说明写在 `config.json` 旁边的 `instructions.md` 中。它优先于 JSON 内的 `"instructions": "..."` 字段；文件不存在时才使用 JSON 字段。角色指令会补充 Pi 原有的项目上下文，而不是替换它。

指令文件不能为空，且不能超过 65,536 个字符。文件无效或无法读取时会报错，不会静默忽略。

修改角色后执行 `/reload`。已经打开的子助手保留启动时的配置，需要关闭并重新打开才能使用新配置。

### 可选设置

按需在 `config.json` 中添加：

| 字段 | 作用 |
| --- | --- |
| `"invocation": "manual"` | 只允许用户通过 `/sub:reviewer` 等命令启动。默认值为 `"both"`，也允许 Pi 自行委派。 |
| `"sessionPersistence": "persistent"` | 保存子助手对话，关闭后可以恢复。默认值为 `"ephemeral"`，仅保存在内存中。 |
| `"model": "provider/model-id"` | 指定 Pi 配置中可用的模型。 |
| `"thinkingLevel": "high"` | 请求所选模型支持的思考级别。 |
| `"skills": ["skill-name", "./path/to/SKILL.md"]` | 加载已安装的技能，或使用相对于角色配置的路径。 |
| `"extensions": ["npm:pi-model-calibration", "./hooks.ts"]` | 为子助手显式加载额外扩展，包括不提供工具的提示词或事件插件。 |

通过 `/sub:reviewer` 启动的持久化助手，在关闭后，可以从同一个已保存的主会话中再次执行该命令来恢复。不同的主会话各自拥有独立的助手。设置为手动调用的角色不能由 Pi 自行委派。

### 子助手扩展白名单

在角色的 `config.json` 中添加，例如：

```json
"extensions": ["npm:pi-model-calibration"]
```

支持 Pi 的 npm、`git:`、HTTP(S) 仓库地址、`builtin:` 标识，以及本地扩展文件或包目录。本地相对路径以 **配置文件所在目录** 为基准，也支持绝对路径和 `~/`。本地路径不存在时，启动会报错；重复条目只加载一次。包来源交给子助手中的 Pi 解析，可能触发下载或安装，不会在主 Pi 读取角色配置时执行。

`npm:` / `git:` 条目使用 Pi 的临时包缓存，已全局安装的包不一定在该缓存中；离线使用时，可直接列出已安装的入口文件，例如 `"extensions": ["~/.pi/agent/npm/node_modules/pi-model-calibration/index.ts"]`，避免重新下载。

不配置或设置 `[]` 时，不额外加载插件。子助手仍使用 `--no-extensions`：只显式加载通信与 Herdr 集成、常规 MCP 支持、角色工具依赖的扩展，以及此白名单，不会自动继承主 Pi 的其他插件。项目角色仍须经过项目信任，同名角色覆盖时不会合并白名单。

这个字段只控制 **Sub 启动**，不会给使用 `pi --profile` 的当前进程动态加载扩展；该场景仍需使用 Pi 的 `-e` 或常规扩展配置。扩展的加载不会自动将其工具加入角色的 `tools`；自定义非 MCP 工具仍须在主 Pi 中可用。

扩展可以执行代码、读取上下文并修改提示词，**白名单不是沙箱**，只添加你信任的插件。修改后重载主 Pi，并关闭、重新打开相关子助手。对于 `model-calibration`，加载后还需其规则匹配子助手所选模型才会注入校准提示词。

### 角色专属技能

将技能放在角色目录中，就只会在选中该角色时加载，无需填写 `skills` 字段：

```text
reviewer/
├── config.json
├── instructions.md
└── skills/
    └── code-review/
        └── SKILL.md
```

### 主 Pi 的委派规则

在 `~/.pi/agent/subagent/MAIN.md` 或受信任项目的 `.pi/subagent/MAIN.md` 中写入规则，例如：

```markdown
宣布任务完成之前，让 reviewer 审查本次代码变更。
```

这些指令只适用于主 Pi，不会加载到子助手中。主 Pi 和子助手都需要遵守的项目规则应放在 `AGENTS.md` 中。

## 清理已删除会话的遗留文件

持久化 Sub 使用 Pi 原生的 `--session-dir`，按所属 Main 分目录保存：

```text
~/.pi/agent/subagent/sessions/<main-session-id>/*.jsonl
```

执行 `/clean-sub`，找不到对应 Main ID 时，立即删除它的 Sub 会话目录和运行时通信目录。命令检查 Pi 默认会话目录和当前会话目录，始终保留当前 Main，不新增索引。会话文件无法读取或文件头无效时会停止清理，不会将它们当作已删除。

清理前请关闭遗留的 Sub 标签页，命令只删除文件。角色配置和全局设置不受影响；以前散落在专用目录之外的 Sub 文件仍需手动删除。如果移动过 Main 文件或使用其他自定义会话目录，请先确保这些会话位于扫描范围内，再执行清理。

## 使用须知

助手间消息使用自定义收件卡片，由 Pi 原生处理启动准备，不再添加用户角色唤醒消息。详见[消息机制](docs/messaging.md)。

- **子助手依赖 Herdr。** 不支持无界面后台运行；最多同时打开四个子助手，子助手不能继续委派。
- **角色配置不是沙箱。** 子助手以你的系统用户身份运行，配置“只读角色”不等于限制文件系统权限。
- **MCP 沿用 Pi 的常规配置。** 角色只选择非 MCP 工具，不隔离或筛选 MCP 服务。自定义的非 MCP 工具必须来自主 Pi 已加载的扩展。
- **子助手拥有独立对话。** 它会收到任务、角色配置和常规项目上下文，但不会收到主对话的聊天记录。请在任务中提供必要信息。
- **重载主 Pi 不会关闭子助手。** 不再需要时请关闭标签页；异常崩溃后可能需要手动清理。

新建或恢复子助手时，插件先发送一条短 shell 探针，并等待最多 60 秒确认它已执行，再提交完整 Pi 命令。这样可避免 macOS 上 shell 仍在初始化时，长命令（尤其是包含会话路径的 resume）被截断、末尾 Enter 丢失的问题。探针等待支持取消；启动失败会尝试关闭新建的标签页，不会向半截命令补发 Enter。参见 [Herdr 已知问题 #4950](https://github.com/herdrdev/herdr/issues/4950)。

如果找不到角色或启动失败，先运行 `/profiles`，检查目录名与 `name` 是否一致、项目是否受信任，以及引用的工具、技能和扩展是否可用。如果提示 Herdr 不可用，请确认 Pi 正在 Herdr 工作区内运行。

如需在 Herdr 的 Agents 面板中隐藏或显示 Pi Subagent 子助手，可安装可选的 [Herdr 配套插件](herdr-plugin/README.md)（英文说明）。

## 开发

```bash
npm install
npm run check
pi -e ./src/index.ts
```

维护者可参考[发布指南](docs/releasing.zh-CN.md)，了解首次 npm 发布、Trusted Publisher 配置和后续自动发布流程。
