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 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.0](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.1.0...v1.2.0)
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
- Async subagents for [Pi](https://github.com/earendil-works/pi) running exclusively in [Herdr](https://herdr.dev). Spawn, orchestrate, and manage sub-agent sessions in dedicated herdr tabs or panes. **Fully non-blocking** — the main agent keeps working while subagents run in the background.
3
+ ![Pi Herdr Agents: parallel Pi agents running asynchronously in dedicated Herdr panes and managed worktrees.](https://raw.githubusercontent.com/giuseppecrj/pi-herdr-agents/main/docs/assets/pi-herdr-agents-gallery.png)
4
4
 
5
- Package: `pi-herdr-agents` · Repository: [`giuseppecrj/pi-herdr-agents`](https://github.com/giuseppecrj/pi-herdr-agents)
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
- ## How It Works
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
- Call `subagent()` and it **returns immediately**. The sub-agent runs in its own terminal pane. A live widget above the input shows all tracked agents with their projected state — for example `starting`, `active`, `waiting`, `blocked`, `interrupted`, `stalled`, `running`, or `finalizing`. The header summarizes **active** (processing) vs **open** (not processing). When every tracked subagent is open, the border switches to amber. When a sub-agent finishes, its result is **steered back** into the main session as an async notification — triggering a new turn so the agent can process it.
9
+ ## Features
10
10
 
11
- ```
12
- ╭─ Subagents ──────────────────── 1 active · 1 open ─╮
13
- 00:23 Scout: Auth (scout) active · bash 7m
14
- 00:45 Scout: DB (scout) waiting 2m
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
- For parallel execution, just call `subagent` multiple times — they all run concurrently:
19
+ ## Requirements
19
20
 
20
- ```typescript
21
- subagent({ name: "Scout: Auth", agent: "scout", task: "Analyze auth module" });
22
- subagent({ name: "Scout: DB", agent: "scout", task: "Map database schema" });
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
- Read-only agents can safely share the parent checkout. For parallel agents that write files, give each task a unique Herdr-managed worktree; see [Worktree subagents](docs/worktree-subagents.md).
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
- ## Development
27
+ ## Install
29
28
 
30
- Run unit tests and lint locally:
29
+ Install from npm:
31
30
 
32
31
  ```bash
33
- npm test
34
- npm run lint
32
+ pi install npm:pi-herdr-agents
35
33
  ```
36
34
 
37
- Run the required end-to-end suite from inside herdr:
35
+ Install project-locally or try it for one run:
38
36
 
39
37
  ```bash
40
- npm run test:integration
38
+ pi install -l npm:pi-herdr-agents
39
+ pi -e npm:pi-herdr-agents
41
40
  ```
42
41
 
43
- It launches real Pi sessions, Herdr panes, worktrees, and the extension from the working tree, but routes model requests to a local deterministic fixture. It needs no provider credentials or network access.
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
- PI_TEST_MODEL="openai-codex/gpt-5.6-luna" PI_TEST_TIMEOUT=180000 \
49
- npm run test:integration:live
45
+ herdr
46
+ pi
50
47
  ```
51
48
 
52
- `PI_TEST_MODEL` selects the parent and child runtime only in live mode.
49
+ Restart or `/reload` Pi after installation. Review package source before installing any Pi package.
53
50
 
54
- ## Install
51
+ ## Quick start
55
52
 
56
- Install the package globally from npm:
53
+ Ask Pi to delegate naturally:
57
54
 
58
- ```bash
59
- pi install npm:pi-herdr-agents
55
+ ```text
56
+ Use two scouts in parallel to map the authentication flow, then summarize their findings.
60
57
  ```
61
58
 
62
- Use `pi install -l npm:pi-herdr-agents` for a project-local installation, or try it for one run without changing settings:
59
+ Or launch a named role directly:
63
60
 
64
- ```bash
65
- pi -e npm:pi-herdr-agents
61
+ ```text
62
+ /subagent scout Analyze the authentication module and report relevant files and risks
66
63
  ```
67
64
 
68
- Pi packages execute with your user account's full system access. Review the package source before installation.
65
+ For an isolated writing task:
69
66
 
70
- The documented `npm version` release step updates [CHANGELOG.md](CHANGELOG.md). Pushing that version change to `main` publishes to npm and creates the matching Git tag and GitHub Release. For bootstrap authentication, versioning, verification, and troubleshooting, see [RELEASING.md](RELEASING.md).
67
+ ```text
68
+ /worktree auth-fix Implement the approved authentication fix and run the focused tests
69
+ ```
71
70
 
72
- Start herdr, then run pi inside it:
71
+ Pi can also call the tool directly:
73
72
 
74
- ```bash
75
- herdr
76
- pi
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
- herdr is the only supported terminal environment. The extension requires `HERDR_ENV=1` and the `herdr` CLI to be available.
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
- ### Troubleshooting completion delivery
83
+ ![Pi Herdr Agents lifecycle: spawn a child, run it in Herdr, supervise live state, and deliver one bounded result to the parent.](https://raw.githubusercontent.com/giuseppecrj/pi-herdr-agents/main/docs/assets/async-subagent-lifecycle.png)
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
- ## Requirements
883
+ ## Development
869
884
 
870
- - [Pi](https://github.com/earendil-works/pi) — the coding agent
871
- - [herdr](https://herdr.dev) — the required terminal workspace
885
+ Run local checks:
872
886
 
873
887
  ```bash
874
- herdr
875
- pi
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
- Other multiplexers and terminal backends are not supported. Worktrees provide Git checkout isolation only, not process or security isolation; child agents and installed Pi packages run with your user's filesystem and command permissions.
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.0",
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 = buildToolAllowlist(request.behavior.tools);
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
- if (request.behavior.autoExit) env.push("PI_SUBAGENT_AUTO_EXIT=1");
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
- ...(autoExit ? ["PI_SUBAGENT_AUTO_EXIT=1"] : []),
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 buildToolAllowlist(tools?: string): string | null {
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
- for (const tool of SUBAGENT_CONTROL_TOOLS) allow.add(tool);
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 autonomous agents to self-terminate
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",