@oldflag2333333/pi-subagent 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +179 -2
- package/README.zh-CN.md +180 -0
- package/docs/messaging.md +28 -0
- package/docs/releasing.md +72 -0
- package/docs/releasing.zh-CN.md +72 -0
- package/docs/third-party-notices.md +25 -0
- package/herdr-plugin/README.md +34 -0
- package/herdr-plugin/action.ts +19 -0
- package/herdr-plugin/herdr-plugin.toml +27 -0
- package/herdr-plugin/index.mjs +108 -0
- package/package.json +65 -4
- package/src/adapters/herdr.ts +157 -0
- package/src/adapters/index.ts +31 -0
- package/src/channel-monitor.ts +127 -0
- package/src/channel.ts +286 -0
- package/src/commands/clean-sub.ts +90 -0
- package/src/commands/sub.ts +39 -0
- package/src/inbox-state.ts +114 -0
- package/src/index.ts +45 -0
- package/src/main-context.ts +91 -0
- package/src/manual-context.ts +9 -0
- package/src/parent-wake.ts +86 -0
- package/src/profiles/context.ts +27 -0
- package/src/profiles/launch-args.ts +21 -0
- package/src/profiles/loader.ts +325 -0
- package/src/profiles/mcp.ts +16 -0
- package/src/profiles/runtime.ts +102 -0
- package/src/profiles/system-prompt.ts +33 -0
- package/src/profiles/tool-selection.ts +21 -0
- package/src/profiles/tool-sources.ts +49 -0
- package/src/profiles/types.ts +37 -0
- package/src/run-manager.ts +442 -0
- package/src/sessions.ts +61 -0
- package/src/talk-delivery.ts +78 -0
- package/src/talk-message.ts +32 -0
- package/src/talk-render.ts +18 -0
- package/src/tools/main.ts +299 -0
- package/src/tools/sub.ts +215 -0
- package/src/types.ts +113 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Facets contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,180 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Pi Subagent
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
English | [简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
Give Pi reusable specialists for code review, research, and other focused tasks. Each specialist runs in its own Herdr tab and reports back to your main conversation, without inheriting its chat history.
|
|
6
|
+
|
|
7
|
+
A **profile** defines a specialist's instructions, tools, and optional skills or model. You can invoke it yourself or let your main Pi delegate work to it.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
You need **Node.js 22.19+**, **[Pi](https://pi.dev) 1.0.4+**, and **Herdr**. To launch specialists, run Pi inside a Herdr workspace with the `herdr` command available.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pi install npm:@oldflag2333333/pi-subagent
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Restart Pi or run `/reload`. Pi Subagent uses your existing Pi provider credentials; make sure Pi can already run a normal conversation.
|
|
18
|
+
|
|
19
|
+
To update later:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pi update npm:@oldflag2333333/pi-subagent
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Restart Pi or run `/reload` after updating.
|
|
26
|
+
|
|
27
|
+
## Try it: a code reviewer
|
|
28
|
+
|
|
29
|
+
Pi Subagent ships without built-in profiles. Create your first one:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
mkdir -p ~/.pi/agent/subagent/profiles/reviewer
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Save this as `~/.pi/agent/subagent/profiles/reviewer/config.json`:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"version": 1,
|
|
40
|
+
"name": "reviewer",
|
|
41
|
+
"description": "Review code for bugs and missing tests without modifying files.",
|
|
42
|
+
"tools": ["read", "grep", "find", "ls"]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Save this beside it as `instructions.md`:
|
|
47
|
+
|
|
48
|
+
```markdown
|
|
49
|
+
Review the requested code for bugs, regressions, and missing tests.
|
|
50
|
+
Do not modify files. Report actionable findings with file paths and
|
|
51
|
+
line numbers. If nothing stands out, say so and note any testing gaps.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
In Pi, run `/reload`, then:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
/sub:reviewer Review the authentication code in src/auth.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Replace `src/auth` with a path in your project. The reviewer opens in a separate Herdr tab and sends its findings back to your main conversation. You can keep working while it runs.
|
|
61
|
+
|
|
62
|
+
Or ask your main Pi to delegate:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
Ask the reviewer profile to review src/auth for bugs and missing tests.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Everyday use
|
|
69
|
+
|
|
70
|
+
| What you want | How to do it |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| See available profiles or configuration errors | `/profiles` |
|
|
73
|
+
| Start a specialist or send it another task | `/sub:reviewer <task>` |
|
|
74
|
+
| Let Pi choose a specialist | Ask Pi to delegate the task to an appropriate profile |
|
|
75
|
+
| Check progress | Ask Pi to list its Subs, or open the specialist's Herdr tab |
|
|
76
|
+
| Stop its current task without closing it | Ask Pi to interrupt the Sub |
|
|
77
|
+
| Finish with a specialist | Ask Pi to close the Sub, or close its Herdr tab |
|
|
78
|
+
| Remove Sub sessions and communication files left by deleted Mains | `/clean-sub` |
|
|
79
|
+
|
|
80
|
+
Within the same Main session, repeated `/sub:reviewer` commands reuse that profile's open Sub. If it is busy, your next task is queued. Finishing a task does not automatically close the tab.
|
|
81
|
+
|
|
82
|
+
The **Sub-agents** list shows only assistants created by the current Main: all **Open** Subs (including idle or unknown status) and **Resumable** persistent sessions confirmed closed with saved files still available. Other Main sessions and forks do not inherit them or gain access to resume them. Reloading or resuming the same Main preserves ownership.
|
|
83
|
+
|
|
84
|
+
To use a profile in your current Pi instead of opening a Sub, start Pi with:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pi --profile reviewer
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Starting Pi without `--profile` leaves your existing tools, model, and skills unchanged.
|
|
91
|
+
|
|
92
|
+
## Customize a profile
|
|
93
|
+
|
|
94
|
+
### Where profiles live
|
|
95
|
+
|
|
96
|
+
- **Personal:** `~/.pi/agent/subagent/profiles/<name>/`
|
|
97
|
+
- **Project:** `.pi/subagent/profiles/<name>/` in your project or an ancestor directory; loaded only when the project is trusted.
|
|
98
|
+
|
|
99
|
+
Each directory needs a `config.json`, with a `name` matching the directory name. A nearer project profile replaces a same-named ancestor or personal profile; settings are not merged. Legacy `<name>.json` profiles are also supported.
|
|
100
|
+
|
|
101
|
+
### Instructions
|
|
102
|
+
|
|
103
|
+
Write the role in `instructions.md` beside `config.json`. It takes precedence over an inline `"instructions": "..."` field; if the file is absent, the inline field is used instead. Instructions add to Pi's normal project context, rather than replacing it.
|
|
104
|
+
|
|
105
|
+
Instruction files must be non-empty and no longer than 65,536 characters. An invalid or unreadable file is reported as an error, not silently ignored.
|
|
106
|
+
|
|
107
|
+
Run `/reload` after editing profiles. Already-open Subs keep their launch configuration; close and reopen them to use changes.
|
|
108
|
+
|
|
109
|
+
### Optional settings
|
|
110
|
+
|
|
111
|
+
Add these fields to `config.json` as needed:
|
|
112
|
+
|
|
113
|
+
| Field | Use it to… |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| `"invocation": "manual"` | Allow only user commands such as `/sub:reviewer` to start this specialist. Default: `"both"`, allowing Pi delegation too. |
|
|
116
|
+
| `"sessionPersistence": "persistent"` | Save the Sub's conversation so it can be resumed after closing. Default: `"ephemeral"`, which keeps it only in memory. |
|
|
117
|
+
| `"model": "provider/model-id"` | Choose a model available in your Pi configuration. |
|
|
118
|
+
| `"thinkingLevel": "high"` | Request a thinking level supported by the selected model. |
|
|
119
|
+
| `"skills": ["skill-name", "./path/to/SKILL.md"]` | Include installed skills or paths relative to the profile. |
|
|
120
|
+
|
|
121
|
+
For a persistent specialist started with `/sub:reviewer`, invoking the command again from the same saved Main session resumes it after closure. A different Main session gets its own specialist. Manual-only profiles are not available for Pi to delegate on its own.
|
|
122
|
+
|
|
123
|
+
### Profile-specific skills
|
|
124
|
+
|
|
125
|
+
Put skills inside the profile directory to load them only when that profile is selected. No `skills` field is needed:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
reviewer/
|
|
129
|
+
├── config.json
|
|
130
|
+
├── instructions.md
|
|
131
|
+
└── skills/
|
|
132
|
+
└── code-review/
|
|
133
|
+
└── SKILL.md
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Delegation rules for your main Pi
|
|
137
|
+
|
|
138
|
+
Use `~/.pi/agent/subagent/MAIN.md` or a trusted project's `.pi/subagent/MAIN.md` for rules such as:
|
|
139
|
+
|
|
140
|
+
```markdown
|
|
141
|
+
Ask the reviewer profile to review code changes before declaring a task complete.
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
These instructions apply only to your main Pi, not to its Subs. Keep shared project rules in `AGENTS.md`.
|
|
145
|
+
|
|
146
|
+
## Clean up deleted sessions
|
|
147
|
+
|
|
148
|
+
Persistent Sub histories are grouped by their owning Main, using Pi's native `--session-dir`:
|
|
149
|
+
|
|
150
|
+
```text
|
|
151
|
+
~/.pi/agent/subagent/sessions/<main-session-id>/*.jsonl
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Run `/clean-sub` to immediately delete both the Sub session directory and runtime communication directory for any Main ID no longer found among saved Pi sessions. It checks Pi's default session store and the current session directory, always preserves the current Main, and creates no index. Unreadable session files or invalid headers stop cleanup instead of being treated as deleted.
|
|
155
|
+
|
|
156
|
+
Close any orphaned Sub tabs before cleaning; the command only deletes files. Profiles and global settings are untouched. Older Sub files outside the managed directory still need manual deletion. If you moved Main files or use other custom session directories, make them available in the scanned locations before cleaning.
|
|
157
|
+
|
|
158
|
+
## Things to know
|
|
159
|
+
|
|
160
|
+
Messages use custom inbox cards. An idle receiver also gets a short user-role wake prompt to preserve its profile instructions. See [messaging behavior and the Pi wake workaround](docs/messaging.md).
|
|
161
|
+
|
|
162
|
+
- **Herdr is required for Subs.** There is no headless fallback. Up to four Subs can be open at once, and Subs cannot delegate further.
|
|
163
|
+
- **Profiles are not a sandbox.** Subs run as your OS user. A read-only role is not a filesystem permission boundary.
|
|
164
|
+
- **MCP follows Pi's normal configuration.** Profiles select non-MCP tools; they do not isolate or filter MCP servers. Custom non-MCP tools must come from extensions already loaded in Main.
|
|
165
|
+
- **Subs have separate conversations.** They receive their task, profile, and normal project context—not Main's chat history. Include the details they need in the task.
|
|
166
|
+
- **Reloading Main does not close Subs.** Close tabs you no longer need. Hard crashes may require manual cleanup.
|
|
167
|
+
|
|
168
|
+
If a profile is missing or fails to start, run `/profiles` first. Check its directory/name match, project trust, and any referenced tools or skills. If Herdr is unavailable, confirm Pi is running inside a Herdr workspace.
|
|
169
|
+
|
|
170
|
+
To hide or show Pi Subagent Subs in Herdr's Agents panel, see the optional [Herdr companion plugin](herdr-plugin/README.md).
|
|
171
|
+
|
|
172
|
+
## Development
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
npm install
|
|
176
|
+
npm run check
|
|
177
|
+
pi -e ./src/index.ts
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Maintainers: see [the release guide](docs/releasing.md) for CI and automatic npm publishing.
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Pi Subagent
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 简体中文
|
|
4
|
+
|
|
5
|
+
给 Pi 配置可复用的专用助手,用于代码审查、资料调研等任务。每个助手都在独立的 Herdr 标签页中工作,将结果发回主对话,不继承主对话的聊天记录。
|
|
6
|
+
|
|
7
|
+
一份 **profile(角色配置)** 定义助手的指令、工具,以及可选的技能和模型。你可以手动调用,也可以让主 Pi 自行委派任务。
|
|
8
|
+
|
|
9
|
+
## 安装
|
|
10
|
+
|
|
11
|
+
需要 **Node.js 22.19+**、**[Pi](https://pi.dev) 1.0.4+** 和 **Herdr**。启动助手时,Pi 必须运行在 Herdr 工作区中,并且能调用 `herdr` 命令。
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pi install npm:@oldflag2333333/pi-subagent
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
安装后重启 Pi,或执行 `/reload`。Pi Subagent 使用 Pi 已有的模型服务凭据,请先确认 Pi 能正常对话。
|
|
18
|
+
|
|
19
|
+
后续更新:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pi update npm:@oldflag2333333/pi-subagent
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
更新后同样需要重启 Pi 或执行 `/reload`。
|
|
26
|
+
|
|
27
|
+
## 快速上手:代码审查助手
|
|
28
|
+
|
|
29
|
+
Pi Subagent 不附带内置角色。先创建一个:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
mkdir -p ~/.pi/agent/subagent/profiles/reviewer
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
将以下内容保存为 `~/.pi/agent/subagent/profiles/reviewer/config.json`:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"version": 1,
|
|
40
|
+
"name": "reviewer",
|
|
41
|
+
"description": "检查代码中的缺陷和测试遗漏,不修改文件。",
|
|
42
|
+
"tools": ["read", "grep", "find", "ls"]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
在同一目录下创建 `instructions.md`:
|
|
47
|
+
|
|
48
|
+
```markdown
|
|
49
|
+
检查指定代码中的缺陷、回归风险和测试遗漏。
|
|
50
|
+
不要修改文件。报告具体、可操作的问题,并附上文件路径和行号。
|
|
51
|
+
如果没有发现明显问题,请明确说明,并指出尚未验证的部分。
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
在 Pi 中执行 `/reload`,然后输入:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
/sub:reviewer 检查 src/auth 中的认证代码。
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
将 `src/auth` 替换为你项目中的路径。审查助手会在独立的 Herdr 标签页中启动,并将结果发回主对话。等待期间,你可以继续处理其他工作。
|
|
61
|
+
|
|
62
|
+
也可以直接让主 Pi 委派:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
让 reviewer 检查 src/auth 中的缺陷和测试遗漏。
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 日常使用
|
|
69
|
+
|
|
70
|
+
| 你想做什么 | 操作方式 |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| 查看可用角色或配置错误 | `/profiles` |
|
|
73
|
+
| 启动助手,或给它追加任务 | `/sub:reviewer <任务>` |
|
|
74
|
+
| 让 Pi 选择助手 | 告诉 Pi 将任务委派给合适的角色 |
|
|
75
|
+
| 查看进度 | 让 Pi 列出子助手,或打开助手的 Herdr 标签页 |
|
|
76
|
+
| 停止当前任务,但保留助手会话 | 让 Pi 中断该子助手 |
|
|
77
|
+
| 结束使用 | 让 Pi 关闭子助手,或手动关闭其 Herdr 标签页 |
|
|
78
|
+
| 清理已删除 Main 遗留的 Sub 会话和通信文件 | `/clean-sub` |
|
|
79
|
+
|
|
80
|
+
在同一个主会话(Main)中,多次调用 `/sub:reviewer` 会复用该角色已打开的子助手(Sub)。如果它正在工作,新任务会排队。任务完成后,标签页不会自动关闭。
|
|
81
|
+
|
|
82
|
+
**Sub-agents(子助手)** 列表只显示当前 Main 创建的助手:**Open** 包含所有已打开的子助手,包括空闲或状态未知的;**Resumable** 包含已确认关闭、且保存文件仍存在的持久化会话。其他 Main 或分叉会话不会继承这些助手,也不能恢复它们。重载或恢复同一个 Main 则会保留关联。
|
|
83
|
+
|
|
84
|
+
如果想将角色应用到当前 Pi,而不是打开子助手,可以这样启动:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pi --profile reviewer
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
不传入 `--profile` 时,Pi 原有的工具、模型和技能配置保持不变。
|
|
91
|
+
|
|
92
|
+
## 自定义角色
|
|
93
|
+
|
|
94
|
+
### 配置放在哪里
|
|
95
|
+
|
|
96
|
+
- **个人配置:** `~/.pi/agent/subagent/profiles/<name>/`
|
|
97
|
+
- **项目配置:** 项目或其上级目录中的 `.pi/subagent/profiles/<name>/`,仅在项目信任后加载。
|
|
98
|
+
|
|
99
|
+
每个目录都需要一份 `config.json`,其中的 `name` 必须与目录名一致。距离当前工作目录更近的项目配置会替换上级目录或个人目录中的同名角色,不会合并字段。旧式的 `<name>.json` 单文件配置仍然受支持。
|
|
100
|
+
|
|
101
|
+
### 角色指令
|
|
102
|
+
|
|
103
|
+
将角色说明写在 `config.json` 旁边的 `instructions.md` 中。它优先于 JSON 内的 `"instructions": "..."` 字段;文件不存在时才使用 JSON 字段。角色指令会补充 Pi 原有的项目上下文,而不是替换它。
|
|
104
|
+
|
|
105
|
+
指令文件不能为空,且不能超过 65,536 个字符。文件无效或无法读取时会报错,不会静默忽略。
|
|
106
|
+
|
|
107
|
+
修改角色后执行 `/reload`。已经打开的子助手保留启动时的配置,需要关闭并重新打开才能使用新配置。
|
|
108
|
+
|
|
109
|
+
### 可选设置
|
|
110
|
+
|
|
111
|
+
按需在 `config.json` 中添加:
|
|
112
|
+
|
|
113
|
+
| 字段 | 作用 |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| `"invocation": "manual"` | 只允许用户通过 `/sub:reviewer` 等命令启动。默认值为 `"both"`,也允许 Pi 自行委派。 |
|
|
116
|
+
| `"sessionPersistence": "persistent"` | 保存子助手对话,关闭后可以恢复。默认值为 `"ephemeral"`,仅保存在内存中。 |
|
|
117
|
+
| `"model": "provider/model-id"` | 指定 Pi 配置中可用的模型。 |
|
|
118
|
+
| `"thinkingLevel": "high"` | 请求所选模型支持的思考级别。 |
|
|
119
|
+
| `"skills": ["skill-name", "./path/to/SKILL.md"]` | 加载已安装的技能,或使用相对于角色配置的路径。 |
|
|
120
|
+
|
|
121
|
+
通过 `/sub:reviewer` 启动的持久化助手,在关闭后,可以从同一个已保存的主会话中再次执行该命令来恢复。不同的主会话各自拥有独立的助手。设置为手动调用的角色不能由 Pi 自行委派。
|
|
122
|
+
|
|
123
|
+
### 角色专属技能
|
|
124
|
+
|
|
125
|
+
将技能放在角色目录中,就只会在选中该角色时加载,无需填写 `skills` 字段:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
reviewer/
|
|
129
|
+
├── config.json
|
|
130
|
+
├── instructions.md
|
|
131
|
+
└── skills/
|
|
132
|
+
└── code-review/
|
|
133
|
+
└── SKILL.md
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 主 Pi 的委派规则
|
|
137
|
+
|
|
138
|
+
在 `~/.pi/agent/subagent/MAIN.md` 或受信任项目的 `.pi/subagent/MAIN.md` 中写入规则,例如:
|
|
139
|
+
|
|
140
|
+
```markdown
|
|
141
|
+
宣布任务完成之前,让 reviewer 审查本次代码变更。
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
这些指令只适用于主 Pi,不会加载到子助手中。主 Pi 和子助手都需要遵守的项目规则应放在 `AGENTS.md` 中。
|
|
145
|
+
|
|
146
|
+
## 清理已删除会话的遗留文件
|
|
147
|
+
|
|
148
|
+
持久化 Sub 使用 Pi 原生的 `--session-dir`,按所属 Main 分目录保存:
|
|
149
|
+
|
|
150
|
+
```text
|
|
151
|
+
~/.pi/agent/subagent/sessions/<main-session-id>/*.jsonl
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
执行 `/clean-sub`,找不到对应 Main ID 时,立即删除它的 Sub 会话目录和运行时通信目录。命令检查 Pi 默认会话目录和当前会话目录,始终保留当前 Main,不新增索引。会话文件无法读取或文件头无效时会停止清理,不会将它们当作已删除。
|
|
155
|
+
|
|
156
|
+
清理前请关闭遗留的 Sub 标签页,命令只删除文件。角色配置和全局设置不受影响;以前散落在专用目录之外的 Sub 文件仍需手动删除。如果移动过 Main 文件或使用其他自定义会话目录,请先确保这些会话位于扫描范围内,再执行清理。
|
|
157
|
+
|
|
158
|
+
## 使用须知
|
|
159
|
+
|
|
160
|
+
助手间消息保留自定义收件卡片。接收方空闲时,会额外出现一条简短的用户角色唤醒消息,以确保角色指令正常加载。详见[消息机制与 Pi 唤醒问题的绕过方案](docs/messaging.md)。
|
|
161
|
+
|
|
162
|
+
- **子助手依赖 Herdr。** 不支持无界面后台运行;最多同时打开四个子助手,子助手不能继续委派。
|
|
163
|
+
- **角色配置不是沙箱。** 子助手以你的系统用户身份运行,配置“只读角色”不等于限制文件系统权限。
|
|
164
|
+
- **MCP 沿用 Pi 的常规配置。** 角色只选择非 MCP 工具,不隔离或筛选 MCP 服务。自定义的非 MCP 工具必须来自主 Pi 已加载的扩展。
|
|
165
|
+
- **子助手拥有独立对话。** 它会收到任务、角色配置和常规项目上下文,但不会收到主对话的聊天记录。请在任务中提供必要信息。
|
|
166
|
+
- **重载主 Pi 不会关闭子助手。** 不再需要时请关闭标签页;异常崩溃后可能需要手动清理。
|
|
167
|
+
|
|
168
|
+
如果找不到角色或启动失败,先运行 `/profiles`,检查目录名与 `name` 是否一致、项目是否受信任,以及引用的工具和技能是否可用。如果提示 Herdr 不可用,请确认 Pi 正在 Herdr 工作区内运行。
|
|
169
|
+
|
|
170
|
+
如需在 Herdr 的 Agents 面板中隐藏或显示 Pi Subagent 子助手,可安装可选的 [Herdr 配套插件](herdr-plugin/README.md)(英文说明)。
|
|
171
|
+
|
|
172
|
+
## 开发
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
npm install
|
|
176
|
+
npm run check
|
|
177
|
+
pi -e ./src/index.ts
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
维护者可参考[发布指南](docs/releasing.zh-CN.md),了解首次 npm 发布、Trusted Publisher 配置和后续自动发布流程。
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Message delivery and rendering
|
|
2
|
+
|
|
3
|
+
Main ↔ Sub messages remain custom inbox cards. Delivery uses the same `parentWake` wrapper in both directions:
|
|
4
|
+
|
|
5
|
+
- **Busy receiver:** `pi.sendMessage()` with `deliverAs: "followUp"` and `triggerTurn: true`, using Pi's native queue.
|
|
6
|
+
- **Idle receiver:** append the card with `pi.sendMessage(..., { triggerTurn: false })`, then start the run with a short, fixed `pi.sendUserMessage(..., { deliverAs: "steer" })` prompt. This goes through normal input preparation and `before_agent_start`.
|
|
7
|
+
|
|
8
|
+
The wake is a real, visible user-role message added by the extension, not a duplicate of the peer's message. It only asks the receiving agent to process its inbox within its existing task and authority. Peer text stays in the custom card and is never submitted as executable slash-command input.
|
|
9
|
+
|
|
10
|
+
## Delivery guarantees
|
|
11
|
+
|
|
12
|
+
- `content` carries the peer message and routing instructions; `details` carries rendering and receipt metadata and is not sent to the model.
|
|
13
|
+
- Custom cards retain their title, collapsed/expanded rendering, and saved-session rendering.
|
|
14
|
+
- A message file is removed only after its receipt appears in the receiving session. Legacy user-message receipts remain recognized.
|
|
15
|
+
- An idle burst shares one wake while that wake is starting. Reservations survive `/reload`, are scoped to the receiving session, and clear on `agent_start` or non-reload shutdown.
|
|
16
|
+
- If a wake never starts, a later idle delivery can request another wake after ten seconds. The deadline does not create a timer or promise autonomous retry after an input hook handles the wake.
|
|
17
|
+
- A synchronous wake failure keeps the message file retryable; retrying does not append the custom card again. Pi's fire-and-forget extension API does not expose asynchronous prompt failures as delivery receipts.
|
|
18
|
+
|
|
19
|
+
## Why the workaround exists
|
|
20
|
+
|
|
21
|
+
Pi 1.0.4 and 1.1.0 have an idle custom-message wake path that bypasses `before_agent_start` and can drop profile prompt sections:
|
|
22
|
+
|
|
23
|
+
- [#5581: custom-message starts bypass run preparation](https://github.com/earendil-works/pi/issues/5581)
|
|
24
|
+
- [#10267: contributed prompt sections are dropped](https://github.com/earendil-works/pi/issues/10267)
|
|
25
|
+
|
|
26
|
+
The implementation adapts [nicobailon/pi-subagents' parentWake](https://github.com/nicobailon/pi-subagents/blob/0c33ec7cb26ed1db270d72e746c3c975be880aeb/src/shared/parent-wake.ts), with retries for synchronous wake failures. Attribution and the MIT license are in [third-party notices](third-party-notices.md).
|
|
27
|
+
|
|
28
|
+
Real Pi SDK tests cover the first idle wake, subsequent turns, busy follow-ups, and reload. The previous upstream TODO is now a required passing regression test. This workaround does not patch Pi internals or claim to fix unrelated retry/resume paths in Pi itself.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Releasing Pi Subagent
|
|
2
|
+
|
|
3
|
+
English | [简体中文](releasing.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
## What CI does
|
|
6
|
+
|
|
7
|
+
`.github/workflows/release.yml` runs on PRs and pushes to `main`/`dev`, and through **Actions → CI and Release → Run workflow**.
|
|
8
|
+
|
|
9
|
+
- Type checks and tests on Node **22.19.0** and **24**.
|
|
10
|
+
- Package/lockfile validation and an npm packaging dry run.
|
|
11
|
+
- The Node 24 job uploads a `.tgz` as `npm-package-<commit SHA>` (retained for 14 days).
|
|
12
|
+
- Only a **version increase pushed to `main` in `oldflag2333333/pi-subagent`** triggers publication, after both check jobs pass. Ordinary pushes, PRs, manual CI runs, and tag pushes do not publish.
|
|
13
|
+
|
|
14
|
+
Publishing uses npm OIDC with provenance, reserves `v<version>` at the checked commit, and creates a GitHub Release. Stable versions use `latest`; prereleases use `next`.
|
|
15
|
+
|
|
16
|
+
## First npm release: 0.1.0
|
|
17
|
+
|
|
18
|
+
**npm requires the package to exist before a trusted publisher can be configured.** The first publish therefore needs your npm login, not OIDC. See [npm's prerequisites](https://docs.npmjs.com/cli/v11/commands/npm-trust/#prerequisites).
|
|
19
|
+
|
|
20
|
+
The npm package is **@oldflag2333333/pi-subagent**.
|
|
21
|
+
|
|
22
|
+
1. Enable 2FA on your npm account.
|
|
23
|
+
2. Push the intended release commit to `main`. Wait for the entire **CI and Release** run to succeed.
|
|
24
|
+
3. Download that run's `npm-package-<commit SHA>` artifact and extract it. Use a trusted `main` run, not a PR artifact.
|
|
25
|
+
4. In the extracted directory, run:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx --yes npm@11.21.0 login --registry=https://registry.npmjs.org
|
|
29
|
+
npx --yes npm@11.21.0 publish ./oldflag2333333-pi-subagent-0.1.0.tgz --access public --ignore-scripts --registry=https://registry.npmjs.org
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Complete the browser/2FA prompts yourself. Do not send credentials or OTPs to an agent. The tarball is the exact package produced by CI; no need to repack it locally. This initial interactive publish does not have CI provenance and does not create a GitHub Release.
|
|
33
|
+
|
|
34
|
+
5. Verify:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm view @oldflag2333333/pi-subagent version --registry=https://registry.npmjs.org
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Configure automatic publishing on npm
|
|
41
|
+
|
|
42
|
+
Open **npmjs.com → @oldflag2333333/pi-subagent → Settings → Trusted publishing → Add trusted publisher → GitHub Actions**:
|
|
43
|
+
|
|
44
|
+
| Field | Value |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| Organization or user | `oldflag2333333` |
|
|
47
|
+
| Repository | `pi-subagent` |
|
|
48
|
+
| Workflow filename | `release.yml` — filename only |
|
|
49
|
+
| Environment name | Leave empty |
|
|
50
|
+
| Allowed actions | Enable direct `npm publish`, not just staged publishing |
|
|
51
|
+
|
|
52
|
+
No `NPM_TOKEN` or other npm secret is needed in GitHub. The workflow requests `id-token: write` and uses GitHub's built-in token for tags/releases.
|
|
53
|
+
|
|
54
|
+
A new trust configuration must complete a successful OIDC publish **within 2 days**, or it expires. Configure it when you are ready for the next version, or recreate it if it expires. After verifying OIDC publishing, npm recommends **Publishing access → Require two-factor authentication and disallow tokens**.
|
|
55
|
+
|
|
56
|
+
Source: [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/).
|
|
57
|
+
|
|
58
|
+
## Subsequent releases
|
|
59
|
+
|
|
60
|
+
With a clean working tree:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm version patch --no-git-tag-version
|
|
64
|
+
# From 0.1.0, this produces 0.1.1.
|
|
65
|
+
git add package.json package-lock.json
|
|
66
|
+
git commit -m "chore: release v0.1.1"
|
|
67
|
+
git push origin main
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Use a PR instead if required by branch policy. Once the version bump reaches `main`, CI publishes npm and creates the tag and GitHub Release automatically. Do not publish locally again or pre-create the tag.
|
|
71
|
+
|
|
72
|
+
If publication fails, fix the external configuration and **re-run the original failed workflow**. An identical already-published artifact is not republished; conflicting artifacts or tags fail rather than overwrite existing releases. Never try to reuse an npm version for different contents. Publish one version at a time.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Pi Subagent 发布指南
|
|
2
|
+
|
|
3
|
+
[English](releasing.md) | 简体中文
|
|
4
|
+
|
|
5
|
+
## CI 已配置的内容
|
|
6
|
+
|
|
7
|
+
工作流位于 `.github/workflows/release.yml`:
|
|
8
|
+
|
|
9
|
+
- `main`、`dev` 的推送和 PR:在 Node **22.19.0 / 24** 上执行类型检查、测试、包信息校验和打包检查。
|
|
10
|
+
- Node 24 检查通过后上传 `.tgz` 安装包,名称为 `npm-package-<提交 SHA>`,保留 14 天。
|
|
11
|
+
- 可以在 **Actions → CI and Release → Run workflow** 手动运行检查,不会发布。
|
|
12
|
+
- 只有新仓库 `main` 上的**版本递增**才会在所有检查通过后自动发布 npm、创建版本标签和 GitHub Release。
|
|
13
|
+
|
|
14
|
+
普通代码提交、PR、手动运行 CI、推送标签都不会触发发布。正式版使用 npm 的 `latest`,预发布版使用 `next`。
|
|
15
|
+
|
|
16
|
+
## 首次发布 0.1.0
|
|
17
|
+
|
|
18
|
+
npm 包名为 **@oldflag2333333/pi-subagent**。
|
|
19
|
+
|
|
20
|
+
**npm 要求包已经存在,才能配置 Trusted Publisher。** 因此首次发布需要你登录 npm 手动完成,之后才使用 CI 自动发布。参见 [npm 官方说明](https://docs.npmjs.com/cli/v11/commands/npm-trust/#prerequisites)。
|
|
21
|
+
|
|
22
|
+
1. 为 npm 账号开启双因素认证(2FA)。
|
|
23
|
+
2. 将准备发布的代码推送到 `main`,等待整个 **CI and Release** 工作流通过。
|
|
24
|
+
3. 下载该次运行的 `npm-package-<提交 SHA>` artifact 并解压。使用确认过的 `main` 构建,不要使用 PR 的产物。
|
|
25
|
+
4. 在解压目录中执行:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx --yes npm@11.21.0 login --registry=https://registry.npmjs.org
|
|
29
|
+
npx --yes npm@11.21.0 publish ./oldflag2333333-pi-subagent-0.1.0.tgz --access public --ignore-scripts --registry=https://registry.npmjs.org
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
按提示完成浏览器登录和 2FA,不要把凭据或验证码发给助手。直接发布 CI 打好的包,不用在本地重新打包。首次交互式发布不带 CI provenance,也不会自动创建 GitHub Release。
|
|
33
|
+
|
|
34
|
+
5. 确认结果:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm view @oldflag2333333/pi-subagent version --registry=https://registry.npmjs.org
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## npm 网站上需要配置什么
|
|
41
|
+
|
|
42
|
+
进入 **@oldflag2333333/pi-subagent 包页面 → Settings → Trusted publishing → Add trusted publisher → GitHub Actions**:
|
|
43
|
+
|
|
44
|
+
| 字段 | 填写内容 |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| Organization or user | `oldflag2333333` |
|
|
47
|
+
| Repository | `pi-subagent` |
|
|
48
|
+
| Workflow filename | `release.yml`,不要填完整路径 |
|
|
49
|
+
| Environment name | 留空 |
|
|
50
|
+
| Allowed actions | 勾选允许直接 `npm publish`,不能只有 staged publishing |
|
|
51
|
+
|
|
52
|
+
**GitHub 不需要添加 `NPM_TOKEN`。** 工作流使用 OIDC 临时身份,标签和 Release 使用 GitHub 自动提供的 token。
|
|
53
|
+
|
|
54
|
+
新建的信任配置需要在 **2 天内成功完成一次 OIDC 发布**,否则会过期。准备发布下一版时再配置;过期后删除并重建即可。验证自动发布成功后,建议将 **Publishing access** 设置为 **Require two-factor authentication and disallow tokens**。
|
|
55
|
+
|
|
56
|
+
来源:[npm Trusted publishing 文档](https://docs.npmjs.com/trusted-publishers/)。
|
|
57
|
+
|
|
58
|
+
## 后续发布
|
|
59
|
+
|
|
60
|
+
在干净的工作区中执行:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm version patch --no-git-tag-version
|
|
64
|
+
# 0.1.0 → 0.1.1
|
|
65
|
+
git add package.json package-lock.json
|
|
66
|
+
git commit -m "chore: release v0.1.1"
|
|
67
|
+
git push origin main
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
如果仓库要求 PR,就通过 PR 将版本变更合入 `main`。之后 CI 自动完成 npm 发布、标签和 GitHub Release,不需要再手动 `npm publish`,也不要提前创建标签。
|
|
71
|
+
|
|
72
|
+
发布失败时,修正 npm 等外部配置后,重跑**原来失败的工作流**。相同产物不会重复发布;标签或包内容冲突会报错,不会覆盖。不要用同一个 npm 版本号发布不同内容,也不要并行发布多个版本。
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
`src/parent-wake.ts` adapts the parent wake workaround from [nicobailon/pi-subagents](https://github.com/nicobailon/pi-subagents/blob/0c33ec7cb26ed1db270d72e746c3c975be880aeb/src/shared/parent-wake.ts).
|
|
4
|
+
|
|
5
|
+
## pi-subagents — MIT License
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2026 Nico Bailon
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Pi Subagent Agent Visibility for Herdr
|
|
2
|
+
|
|
3
|
+
This companion Herdr plugin hides Pi Subagent-managed subs from the built-in Agents panel by default and provides actions to show, hide, or toggle them.
|
|
4
|
+
|
|
5
|
+
Pi Subagent marks each Herdr Sub pane with the metadata token `subagent_role=sub`. This plugin applies a transient `agent.view` filter; it does not affect `agent list`, notifications, lifecycle detection, or global attention counts.
|
|
6
|
+
|
|
7
|
+
## Link for development
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
herdr plugin link /absolute/path/to/pi-subagent/herdr-plugin
|
|
11
|
+
herdr plugin action invoke subagent.agent-visibility.hide-subs
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Actions
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
herdr plugin action invoke subagent.agent-visibility.toggle-subs
|
|
18
|
+
herdr plugin action invoke subagent.agent-visibility.hide-subs
|
|
19
|
+
herdr plugin action invoke subagent.agent-visibility.show-subs
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The selected visibility is stored in `HERDR_PLUGIN_STATE_DIR` and restored when the Herdr server starts. The initial default is hidden.
|
|
23
|
+
|
|
24
|
+
Optional keybinding:
|
|
25
|
+
|
|
26
|
+
```toml
|
|
27
|
+
[[keys.command]]
|
|
28
|
+
key = "prefix+shift+a"
|
|
29
|
+
type = "plugin_action"
|
|
30
|
+
command = "subagent.agent-visibility.toggle-subs"
|
|
31
|
+
description = "toggle Pi Subagent subs"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
After editing Herdr config, run `herdr server reload-config`.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { run } from "./index.mjs";
|
|
4
|
+
|
|
5
|
+
// WORKAROUND: herdr-plugin.toml uses Pi with --list-models to load this action
|
|
6
|
+
// without entering an interactive session. We run the visibility script during
|
|
7
|
+
// extension initialization and exit before model listing, relying on Pi's startup
|
|
8
|
+
// order. Prefer invoking index.mjs directly once Node availability is guaranteed
|
|
9
|
+
// in the Herdr plugin environment.
|
|
10
|
+
export default async function action(pi: ExtensionAPI): Promise<void> {
|
|
11
|
+
pi.registerFlag("subagent-visibility-action", {
|
|
12
|
+
description: "Internal Pi Subagent Herdr visibility action",
|
|
13
|
+
type: "string",
|
|
14
|
+
});
|
|
15
|
+
const flagIndex = process.argv.indexOf("--subagent-visibility-action");
|
|
16
|
+
const requested = flagIndex >= 0 ? process.argv[flagIndex + 1] : undefined;
|
|
17
|
+
await run(typeof requested === "string" && requested.length > 0 ? requested : "startup");
|
|
18
|
+
process.exit(0);
|
|
19
|
+
}
|