pi-herdr-agents 1.2.0 → 1.2.2
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/CHANGELOG.md +15 -1
- package/README.md +79 -50
- package/package.json +3 -2
- package/pi-extension/subagents/index.ts +1 -26
- package/pi-extension/subagents/launch.ts +15 -6
- package/pi-extension/subagents/subagent-done.ts +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,7 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
9
9
|
|
|
10
|
-
## [v1.2.
|
|
10
|
+
## [v1.2.2](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.2.1...v1.2.2)
|
|
11
|
+
|
|
12
|
+
### Commits
|
|
13
|
+
|
|
14
|
+
- fix: hide completion tool from auto-exit children [`e4cad6b`](https://github.com/giuseppecrj/pi-herdr-agents/commit/e4cad6bdbe5d1952f5bb838640493c20ab332dbd)
|
|
15
|
+
|
|
16
|
+
## [v1.2.1](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.2.0...v1.2.1) - 2026-08-13
|
|
17
|
+
|
|
18
|
+
### Commits
|
|
19
|
+
|
|
20
|
+
- docs: polish package readme and artwork [`908dd76`](https://github.com/giuseppecrj/pi-herdr-agents/commit/908dd76875c91871b8d91113e6d1633d5112d5b3)
|
|
21
|
+
- chore: release v1.2.1 [`df87f12`](https://github.com/giuseppecrj/pi-herdr-agents/commit/df87f126ec5cad4735c441752471aa8bd724f2e9)
|
|
22
|
+
|
|
23
|
+
## [v1.2.0](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.1.0...v1.2.0) - 2026-08-13
|
|
11
24
|
|
|
12
25
|
### Commits
|
|
13
26
|
|
|
@@ -17,6 +30,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
17
30
|
- feat: simplify worktree command [`4dc88e0`](https://github.com/giuseppecrj/pi-herdr-agents/commit/4dc88e0a962625eec10240d57cf67548510e6a9a)
|
|
18
31
|
- docs: add worktree handoff research [`00f95c6`](https://github.com/giuseppecrj/pi-herdr-agents/commit/00f95c65e0f050492259a0de625c35e4eef9aae8)
|
|
19
32
|
- test: cover failed worktree handoff recovery [`dd27c0a`](https://github.com/giuseppecrj/pi-herdr-agents/commit/dd27c0a8f17e51cff635e5b77e18ff7f05896650)
|
|
33
|
+
- chore: release v1.2.0 [`dba1ab5`](https://github.com/giuseppecrj/pi-herdr-agents/commit/dba1ab5564b9ef64ae1f0f57b6df4bb40502970c)
|
|
20
34
|
- ci: upgrade release actions to node24 [`ec9158d`](https://github.com/giuseppecrj/pi-herdr-agents/commit/ec9158d838cb0fae914c94fc448a6677b4ab1696)
|
|
21
35
|
|
|
22
36
|
## [v1.1.0](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.0.0...v1.1.0) - 2026-08-11
|
package/README.md
CHANGED
|
@@ -1,84 +1,99 @@
|
|
|
1
1
|
# Pi Herdr Agents
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Asynchronous subagents and approved review workflows for [Pi](https://github.com/earendil-works/pi), running exclusively in [Herdr](https://herdr.dev).
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Delegate investigation, implementation, and review without blocking the parent session. Each child runs as a real Pi process in its own Herdr surface; results return automatically when the child finishes.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Features
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
- **Non-blocking delegation** — `subagent` acknowledges launch immediately while the parent keeps working.
|
|
12
|
+
- **Parallel execution** — run independent scouts, workers, and reviewers at the same time.
|
|
13
|
+
- **Live supervision** — track process and turn state in Pi's subagent widget; interrupt one child turn without destroying its session.
|
|
14
|
+
- **Managed worktrees** — isolate writing agents in retained Herdr workspaces with explicit Git ownership and recovery details.
|
|
15
|
+
- **Conversation handoff** — continue the active Pi conversation in a new worktree with `/worktree` while preserving the parent session.
|
|
16
|
+
- **Approved review workflows** — prepare and run bounded, read-only multi-agent reviews with fresh evidence and one synthesized result.
|
|
17
|
+
- **Reusable roles** — use bundled agents, project or global definitions, and installable role packs.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
## Requirements
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// Both return immediately, results steer back independently
|
|
24
|
-
```
|
|
21
|
+
- [Pi](https://github.com/earendil-works/pi) with package support
|
|
22
|
+
- [Herdr](https://herdr.dev) and its CLI
|
|
23
|
+
- `HERDR_ENV=1` — start Pi from inside Herdr
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
Other terminal multiplexers are not supported. Worktrees isolate Git checkouts, not processes or permissions; child agents and installed Pi packages run with your user account's access.
|
|
27
26
|
|
|
28
|
-
##
|
|
27
|
+
## Install
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
Install from npm:
|
|
31
30
|
|
|
32
31
|
```bash
|
|
33
|
-
npm
|
|
34
|
-
npm run lint
|
|
32
|
+
pi install npm:pi-herdr-agents
|
|
35
33
|
```
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
Install project-locally or try it for one run:
|
|
38
36
|
|
|
39
37
|
```bash
|
|
40
|
-
|
|
38
|
+
pi install -l npm:pi-herdr-agents
|
|
39
|
+
pi -e npm:pi-herdr-agents
|
|
41
40
|
```
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
An optional live-provider smoke test remains available for Pi/provider compatibility; it is not a merge gate:
|
|
42
|
+
Then start Pi inside Herdr:
|
|
46
43
|
|
|
47
44
|
```bash
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
herdr
|
|
46
|
+
pi
|
|
50
47
|
```
|
|
51
48
|
|
|
52
|
-
`
|
|
49
|
+
Restart or `/reload` Pi after installation. Review package source before installing any Pi package.
|
|
53
50
|
|
|
54
|
-
##
|
|
51
|
+
## Quick start
|
|
55
52
|
|
|
56
|
-
|
|
53
|
+
Ask Pi to delegate naturally:
|
|
57
54
|
|
|
58
|
-
```
|
|
59
|
-
|
|
55
|
+
```text
|
|
56
|
+
Use two scouts in parallel to map the authentication flow, then summarize their findings.
|
|
60
57
|
```
|
|
61
58
|
|
|
62
|
-
|
|
59
|
+
Or launch a named role directly:
|
|
63
60
|
|
|
64
|
-
```
|
|
65
|
-
|
|
61
|
+
```text
|
|
62
|
+
/subagent scout Analyze the authentication module and report relevant files and risks
|
|
66
63
|
```
|
|
67
64
|
|
|
68
|
-
|
|
65
|
+
For an isolated writing task:
|
|
69
66
|
|
|
70
|
-
|
|
67
|
+
```text
|
|
68
|
+
/worktree auth-fix Implement the approved authentication fix and run the focused tests
|
|
69
|
+
```
|
|
71
70
|
|
|
72
|
-
|
|
71
|
+
Pi can also call the tool directly:
|
|
73
72
|
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
```typescript
|
|
74
|
+
subagent({ name: "Auth scout", agent: "scout", task: "Map the authentication flow" });
|
|
75
|
+
subagent({ name: "DB scout", agent: "scout", task: "Map the session schema" });
|
|
76
|
+
// Both return immediately; each result comes back independently.
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
Use ordinary panes for read-only agents. Give each independent writing agent a unique managed worktree; see [Worktree subagents](docs/worktree-subagents.md).
|
|
80
|
+
|
|
81
|
+
## How it works
|
|
80
82
|
|
|
81
|
-
|
|
83
|
+

|
|
84
|
+
|
|
85
|
+
A `subagent` call creates a dedicated Herdr pane or worktree, launches a child Pi session, and returns `started`. The parent watcher combines Herdr process state with child activity details and projects the result into a live widget:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
╭─ Subagents ──────────────────── 1 active · 1 open ─╮
|
|
89
|
+
│ 00:23 Scout: Auth (scout) active · read 7m │
|
|
90
|
+
│ 00:45 Reviewer (reviewer) waiting 2m │
|
|
91
|
+
╰────────────────────────────────────────────────────╯
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
When the child completes, the parent receives one bounded `subagent_result` message and starts a new turn with that result in context. Callers never need to poll, tail session files, or wait in a shell loop.
|
|
95
|
+
|
|
96
|
+
## Troubleshooting completion delivery
|
|
82
97
|
|
|
83
98
|
If a child finishes but the parent returns an empty or unrelated response, first verify that the result reached the parent session:
|
|
84
99
|
|
|
@@ -865,17 +880,31 @@ Every sub-agent session displays a compact tools widget showing available and de
|
|
|
865
880
|
|
|
866
881
|
---
|
|
867
882
|
|
|
868
|
-
##
|
|
883
|
+
## Development
|
|
869
884
|
|
|
870
|
-
|
|
871
|
-
- [herdr](https://herdr.dev) — the required terminal workspace
|
|
885
|
+
Run local checks:
|
|
872
886
|
|
|
873
887
|
```bash
|
|
874
|
-
|
|
875
|
-
|
|
888
|
+
npm ci
|
|
889
|
+
npm test
|
|
890
|
+
npm run lint
|
|
891
|
+
npm pack --dry-run
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
Run the required end-to-end suite from inside Herdr:
|
|
895
|
+
|
|
896
|
+
```bash
|
|
897
|
+
npm run test:integration
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
The deterministic suite launches real Pi sessions, Herdr panes, and worktrees without provider credentials. The optional live-provider smoke test is not a merge gate:
|
|
901
|
+
|
|
902
|
+
```bash
|
|
903
|
+
PI_TEST_MODEL="openai-codex/gpt-5.6-luna" PI_TEST_TIMEOUT=180000 \
|
|
904
|
+
npm run test:integration:live
|
|
876
905
|
```
|
|
877
906
|
|
|
878
|
-
|
|
907
|
+
See [RELEASING.md](RELEASING.md) for versioning, trusted publication, and release verification.
|
|
879
908
|
|
|
880
909
|
---
|
|
881
910
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-herdr-agents",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Asynchronous Pi subagents and approved review workflows in Herdr, with optional isolated Git worktrees",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -53,7 +53,8 @@
|
|
|
53
53
|
],
|
|
54
54
|
"skills": [
|
|
55
55
|
"./skills"
|
|
56
|
-
]
|
|
56
|
+
],
|
|
57
|
+
"image": "https://raw.githubusercontent.com/giuseppecrj/pi-herdr-agents/main/docs/assets/pi-herdr-agents-gallery.png"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
60
|
"@earendil-works/pi-ai": "^0.84.0",
|
|
@@ -117,6 +117,7 @@ import {
|
|
|
117
117
|
persistWorktreeResult,
|
|
118
118
|
runSubagentScript,
|
|
119
119
|
writeWorktreeManifest,
|
|
120
|
+
buildSubagentToolAllowlist,
|
|
120
121
|
type WorktreeHandoff,
|
|
121
122
|
type WorktreeLaunch,
|
|
122
123
|
} from "./launch.ts";
|
|
@@ -1404,32 +1405,6 @@ function updateWidget() {
|
|
|
1404
1405
|
* first positional message so that /skill: args land in messages[1..] and arrive
|
|
1405
1406
|
* as standalone prompts in the child session.
|
|
1406
1407
|
*/
|
|
1407
|
-
const SUBAGENT_CONTROL_TOOLS = ["caller_ping", "subagent_done"] as const;
|
|
1408
|
-
|
|
1409
|
-
/**
|
|
1410
|
-
* Build the child --tools allowlist.
|
|
1411
|
-
*
|
|
1412
|
-
* Pi 0.70+ applies --tools to built-in, extension, and custom tools. If a
|
|
1413
|
-
* subagent definition restricts tools to e.g. "read,bash,write", the child
|
|
1414
|
-
* control tools from subagent-done.ts would otherwise be hidden, leaving a
|
|
1415
|
-
* manually resumed or user-touched subagent unable to call subagent_done.
|
|
1416
|
-
*/
|
|
1417
|
-
function buildSubagentToolAllowlist(effectiveTools?: string): string | null {
|
|
1418
|
-
const requested = (effectiveTools ?? "")
|
|
1419
|
-
.split(",")
|
|
1420
|
-
.map((tool) => tool.trim())
|
|
1421
|
-
.filter(Boolean);
|
|
1422
|
-
|
|
1423
|
-
if (requested.length === 0) return null;
|
|
1424
|
-
|
|
1425
|
-
const allow = new Set(requested);
|
|
1426
|
-
for (const tool of SUBAGENT_CONTROL_TOOLS) {
|
|
1427
|
-
allow.add(tool);
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
return [...allow].join(",");
|
|
1431
|
-
}
|
|
1432
|
-
|
|
1433
1408
|
function buildPiPromptArgs(params: {
|
|
1434
1409
|
effectiveSkills?: string;
|
|
1435
1410
|
taskDelivery: "direct" | "artifact";
|
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
type HerdrWorktreeSurface,
|
|
29
29
|
} from "./terminal.ts";
|
|
30
30
|
|
|
31
|
-
const SUBAGENT_CONTROL_TOOLS = ["caller_ping", "subagent_done"] as const;
|
|
32
31
|
const SUBAGENTS_DIR = dirname(fileURLToPath(import.meta.url));
|
|
33
32
|
|
|
34
33
|
type SubagentSessionMode = "standalone" | "lineage-only" | "fork";
|
|
@@ -550,7 +549,10 @@ function buildPiCommand(
|
|
|
550
549
|
shellQuote(artifacts.systemPromptFile),
|
|
551
550
|
);
|
|
552
551
|
}
|
|
553
|
-
const toolAllowlist =
|
|
552
|
+
const toolAllowlist = buildSubagentToolAllowlist(
|
|
553
|
+
request.behavior.tools,
|
|
554
|
+
request.behavior.autoExit,
|
|
555
|
+
);
|
|
554
556
|
if (toolAllowlist) parts.push("--tools", shellQuote(toolAllowlist));
|
|
555
557
|
if (!request.handoff) {
|
|
556
558
|
for (const prompt of buildPromptArgs(
|
|
@@ -579,7 +581,9 @@ function buildPiCommand(
|
|
|
579
581
|
env.push(`PI_SUBAGENT_NAME=${shellQuote(request.name)}`);
|
|
580
582
|
if (request.agent)
|
|
581
583
|
env.push(`PI_SUBAGENT_AGENT=${shellQuote(request.agent)}`);
|
|
582
|
-
|
|
584
|
+
env.push(
|
|
585
|
+
`PI_SUBAGENT_AUTO_EXIT=${request.behavior.autoExit ? "1" : "0"}`,
|
|
586
|
+
);
|
|
583
587
|
env.push(`PI_SUBAGENT_SESSION=${shellQuote(artifacts.sessionFile)}`);
|
|
584
588
|
env.push(`PI_SUBAGENT_ID=${shellQuote(resolved.id)}`);
|
|
585
589
|
env.push(`PI_SUBAGENT_ACTIVITY_FILE=${shellQuote(artifacts.activityFile)}`);
|
|
@@ -678,7 +682,7 @@ async function launchResumedPiSubagent(
|
|
|
678
682
|
`PI_SUBAGENT_SESSION=${shellQuote(request.sessionFile)}`,
|
|
679
683
|
`PI_SUBAGENT_ID=${shellQuote(id)}`,
|
|
680
684
|
`PI_SUBAGENT_ACTIVITY_FILE=${shellQuote(activityFile)}`,
|
|
681
|
-
|
|
685
|
+
`PI_SUBAGENT_AUTO_EXIT=${autoExit ? "1" : "0"}`,
|
|
682
686
|
];
|
|
683
687
|
const command = [
|
|
684
688
|
...env,
|
|
@@ -722,14 +726,19 @@ async function launchResumedPiSubagent(
|
|
|
722
726
|
};
|
|
723
727
|
}
|
|
724
728
|
|
|
725
|
-
function
|
|
729
|
+
export function buildSubagentToolAllowlist(
|
|
730
|
+
tools?: string,
|
|
731
|
+
autoExit = false,
|
|
732
|
+
): string | null {
|
|
726
733
|
const requested = (tools ?? "")
|
|
727
734
|
.split(",")
|
|
728
735
|
.map((tool) => tool.trim())
|
|
729
736
|
.filter(Boolean);
|
|
730
737
|
if (requested.length === 0) return null;
|
|
731
738
|
const allow = new Set(requested);
|
|
732
|
-
|
|
739
|
+
allow.delete("subagent_done");
|
|
740
|
+
allow.add("caller_ping");
|
|
741
|
+
if (!autoExit) allow.add("subagent_done");
|
|
733
742
|
return [...allow].join(",");
|
|
734
743
|
}
|
|
735
744
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Extension loaded into sub-agents.
|
|
3
3
|
* - Shows agent identity + available tools as a styled widget above the editor (toggle with Ctrl+J)
|
|
4
|
-
* - Provides a `subagent_done` tool for
|
|
4
|
+
* - Provides a `subagent_done` tool for interactive agents to self-terminate
|
|
5
5
|
*/
|
|
6
6
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
7
7
|
import { Box, Text } from "@earendil-works/pi-tui";
|
|
@@ -302,6 +302,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
302
302
|
},
|
|
303
303
|
});
|
|
304
304
|
|
|
305
|
+
if (autoExit) return;
|
|
306
|
+
|
|
305
307
|
pi.registerTool({
|
|
306
308
|
name: "subagent_done",
|
|
307
309
|
label: "Subagent Done",
|