pi-herdr-agents 1.0.0 → 1.2.0

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/AGENTS.md CHANGED
@@ -104,7 +104,7 @@ Use `PI_TEST_MODEL="openai-codex/gpt-5.6-luna" PI_TEST_TIMEOUT=180000 npm run te
104
104
  Before committing:
105
105
 
106
106
  - inspect `git status` and the final diff;
107
- - confirm the package preview includes `skills/orchestrate/SKILL.md` and `pi-extension/subagents/workflow-worker.js`, while excluding plans, journals, sessions, prototypes, generated evidence, and local config;
107
+ - confirm the package preview includes `CHANGELOG.md`, `skills/orchestrate/SKILL.md`, and `pi-extension/subagents/workflow-worker.js`, while excluding plans, journals, sessions, prototypes, generated evidence, and local config;
108
108
  - run `npm pack --dry-run` when package contents or documentation paths changed;
109
109
  - confirm that no generated plans, journals, sessions, provider configuration, test scripts, or review artifacts are staged; and
110
110
  - confirm that no accidental empty directory exists at the repository root:
package/CHANGELOG.md ADDED
@@ -0,0 +1,103 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
9
+
10
+ ## [v1.2.0](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.1.0...v1.2.0)
11
+
12
+ ### Commits
13
+
14
+ - feat: add worktree session handoff [`8b6f928`](https://github.com/giuseppecrj/pi-herdr-agents/commit/8b6f928c0b61a97f66614054340a68c023df0c95)
15
+ - style: format worktree handoff changes [`c1cdc44`](https://github.com/giuseppecrj/pi-herdr-agents/commit/c1cdc4480f0e29268194bc80809959215d13044f)
16
+ - fix: confirm worktree handoff startup [`0e4a97c`](https://github.com/giuseppecrj/pi-herdr-agents/commit/0e4a97c46b6dd1d9fc56d9c74511e380dca6e6d0)
17
+ - feat: simplify worktree command [`4dc88e0`](https://github.com/giuseppecrj/pi-herdr-agents/commit/4dc88e0a962625eec10240d57cf67548510e6a9a)
18
+ - docs: add worktree handoff research [`00f95c6`](https://github.com/giuseppecrj/pi-herdr-agents/commit/00f95c65e0f050492259a0de625c35e4eef9aae8)
19
+ - test: cover failed worktree handoff recovery [`dd27c0a`](https://github.com/giuseppecrj/pi-herdr-agents/commit/dd27c0a8f17e51cff635e5b77e18ff7f05896650)
20
+ - ci: upgrade release actions to node24 [`ec9158d`](https://github.com/giuseppecrj/pi-herdr-agents/commit/ec9158d838cb0fae914c94fc448a6677b4ab1696)
21
+
22
+ ## [v1.1.0](https://github.com/giuseppecrj/pi-herdr-agents/compare/v1.0.0...v1.1.0) - 2026-08-11
23
+
24
+ ### Commits
25
+
26
+ - chore: initialize generated changelog [`77ca8eb`](https://github.com/giuseppecrj/pi-herdr-agents/commit/77ca8eb000e1d06f6d23bfbd8fdcac491bef581d)
27
+ - feat: label coordinated subagents [`e2d15ab`](https://github.com/giuseppecrj/pi-herdr-agents/commit/e2d15abf2cbe9f0557d14ab768dd39e64352577e)
28
+ - chore: release v1.1.0 [`732c0dc`](https://github.com/giuseppecrj/pi-herdr-agents/commit/732c0dcef0f0a85be737b9dd6023a59eb2771178)
29
+
30
+ ## [v1.0.0](https://github.com/giuseppecrj/pi-herdr-agents/compare/v0.1.4...v1.0.0) - 2026-08-11
31
+
32
+ ### Commits
33
+
34
+ - refactor: extract fresh Pi launch transaction [`2241084`](https://github.com/giuseppecrj/pi-herdr-agents/commit/22410845f8b62765fd2ac391cbd94156010abba6)
35
+ - refactor: remove external CLI subagent execution [`9c31fe7`](https://github.com/giuseppecrj/pi-herdr-agents/commit/9c31fe7e566c1fdb3fa8ac3c8a5879fbc25f0fb8)
36
+ - refactor: route Pi session resumes through launch module [`f16f42b`](https://github.com/giuseppecrj/pi-herdr-agents/commit/f16f42b003813852039be9ec1e91b65f28b87bb6)
37
+ - refactor: deliver subagent results through one message [`52c4e02`](https://github.com/giuseppecrj/pi-herdr-agents/commit/52c4e029bbe39170d16a0178b369ab2f68a2d40d)
38
+ - test: stabilize asynchronous subagent integration [`3d2cebb`](https://github.com/giuseppecrj/pi-herdr-agents/commit/3d2cebb41894f2c66038d636998a9b2e0b781431)
39
+ - _No commit message_ [`d5a5c2d`](https://github.com/giuseppecrj/pi-herdr-agents/commit/d5a5c2d0baa1b25a362e0c02de5f6d48342d9393)
40
+ - updates [`e345303`](https://github.com/giuseppecrj/pi-herdr-agents/commit/e345303338857ca19b8ce880c0707173505ad78b)
41
+ - chore: release v1.0.0 [`ccc0045`](https://github.com/giuseppecrj/pi-herdr-agents/commit/ccc0045f3bd6b937bf6acd238b97fe48341bd8ba)
42
+ - merge: deepen Pi subagent launch and resume [`674da9d`](https://github.com/giuseppecrj/pi-herdr-agents/commit/674da9dc5d752deca3538c0d8d7ffdbdecc00a4c)
43
+
44
+ ## [v0.1.4](https://github.com/giuseppecrj/pi-herdr-agents/compare/v0.1.3...v0.1.4) - 2026-08-10
45
+
46
+ ### Commits
47
+
48
+ - chore: release v0.1.4 [`0ce2fe4`](https://github.com/giuseppecrj/pi-herdr-agents/commit/0ce2fe45b3c76a2bffe1df561076d1c62537c139)
49
+
50
+ ## [v0.1.3](https://github.com/giuseppecrj/pi-herdr-agents/compare/v0.1.2...v0.1.3) - 2026-08-07
51
+
52
+ ### Commits
53
+
54
+ - fix: reject empty workflow completions [`338a788`](https://github.com/giuseppecrj/pi-herdr-agents/commit/338a788855c9ea7ac8b3f6214ff8b3130bc4b007)
55
+ - test: verify fallback completion from session evidence [`b2eb4b0`](https://github.com/giuseppecrj/pi-herdr-agents/commit/b2eb4b0fec5bd7d5ec9f473168cf3710e600052d)
56
+ - chore: release v0.1.3 [`a2cd1b5`](https://github.com/giuseppecrj/pi-herdr-agents/commit/a2cd1b5ab424226e371ee6388e79d8ccf3e9a304)
57
+
58
+ ## [v0.1.2](https://github.com/giuseppecrj/pi-herdr-agents/compare/v0.1.1...v0.1.2) - 2026-08-07
59
+
60
+ ### Commits
61
+
62
+ - chore: release v0.1.2 [`67608a5`](https://github.com/giuseppecrj/pi-herdr-agents/commit/67608a5b1950222b522277c2fb4a246cbffb91f8)
63
+
64
+ ## [v0.1.1](https://github.com/giuseppecrj/pi-herdr-agents/compare/v0.1.0...v0.1.1) - 2026-08-07
65
+
66
+ ### Commits
67
+
68
+ - fix: wait for Herdr shell readiness [`58bfa99`](https://github.com/giuseppecrj/pi-herdr-agents/commit/58bfa99c150963b4c7f7cc8348b8e2ead00399af)
69
+ - chore: release v0.1.1 [`9b9a3c9`](https://github.com/giuseppecrj/pi-herdr-agents/commit/9b9a3c9ded45f65be7c2814cb34230ee5bf82532)
70
+
71
+ ## [v0.1.0](https://github.com/giuseppecrj/pi-herdr-agents/compare/v0.0.4...v0.1.0) - 2026-08-05
72
+
73
+ ### Commits
74
+
75
+ - feat: add ordered subagent model fallbacks [`2ce041b`](https://github.com/giuseppecrj/pi-herdr-agents/commit/2ce041b51f1eb1906623bc0c361fea6a3acf019d)
76
+ - chore: release v0.1.0 [`b409457`](https://github.com/giuseppecrj/pi-herdr-agents/commit/b409457f58b738734b48a4e7cf3418da957db271)
77
+
78
+ ## [v0.0.4](https://github.com/giuseppecrj/pi-herdr-agents/compare/v0.0.3...v0.0.4) - 2026-08-05
79
+
80
+ ### Merged
81
+
82
+ - agents: extract Claude CLI adapter [`#5`](https://github.com/giuseppecrj/pi-herdr-agents/pull/5)
83
+
84
+ ### Commits
85
+
86
+ - release: update version to 0.0.4 [`c685c35`](https://github.com/giuseppecrj/pi-herdr-agents/commit/c685c3553ec76d987972c1786d966b704ad9197b)
87
+
88
+ ## [v0.0.3](https://github.com/giuseppecrj/pi-herdr-agents/compare/v0.0.2...v0.0.3) - 2026-08-05
89
+
90
+ ### Commits
91
+
92
+ - docs: enhance documentation for adversarial-reviewer and runtime adapter policies; clarify model selection process and permissions [`ddf4a34`](https://github.com/giuseppecrj/pi-herdr-agents/commit/ddf4a3411e018c7335bc66e191d5d84b187d8d07)
93
+ - agents: remove bundled Claude reviewer adapter [`ed12ddf`](https://github.com/giuseppecrj/pi-herdr-agents/commit/ed12ddf774046dd0a708fd54d53f12d25118d006)
94
+ - docs: align release baseline with 0.0.2 [`c136b16`](https://github.com/giuseppecrj/pi-herdr-agents/commit/c136b1659370bc4265b1ed4c67c2b670c764a8b1)
95
+ - release: update version to 0.0.3 [`c6ce52c`](https://github.com/giuseppecrj/pi-herdr-agents/commit/c6ce52c6af3b9a3157c073aa257ea69f826597ad)
96
+
97
+ ## v0.0.2 - 2026-08-05
98
+
99
+ ### Commits
100
+
101
+ - feat: launch Pi Herdr Agents 0.2.0 [`4fa3f26`](https://github.com/giuseppecrj/pi-herdr-agents/commit/4fa3f26d743defa68ce1c068fbc80cc5f3062934)
102
+ - release: prepare 0.0.2 [`5d6e65d`](https://github.com/giuseppecrj/pi-herdr-agents/commit/5d6e65d4c25a8df427dd057b77267985bb505d1a)
103
+ - update version [`4ffd68f`](https://github.com/giuseppecrj/pi-herdr-agents/commit/4ffd68f55f58cedbfb9fd84cd139f81c107552eb)
package/README.md CHANGED
@@ -67,7 +67,7 @@ pi -e npm:pi-herdr-agents
67
67
 
68
68
  Pi packages execute with your user account's full system access. Review the package source before installation.
69
69
 
70
- After the one-time first-package bootstrap, changing the `package.json` version on `main` automatically publishes to npm and creates the matching Git tag and GitHub Release. For bootstrap authentication, versioning, verification, and troubleshooting, see [RELEASING.md](RELEASING.md).
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).
71
71
 
72
72
  Start herdr, then run pi inside it:
73
73
 
@@ -103,7 +103,7 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
103
103
 
104
104
  ### Extensions
105
105
 
106
- **Subagents** — 5 main-session tools + 5 commands, plus 2 child-only tools:
106
+ **Subagents** — 5 main-session tools + 6 commands, plus 2 child-only tools:
107
107
 
108
108
  | Tool | Description |
109
109
  | -------------------- | ------------------------------------------------------------------------------------------- |
@@ -124,6 +124,7 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
124
124
  | `/iterate` | Fork into a subagent for quick fixes |
125
125
  | `/btw <question>` | Open an ephemeral side-question session in a background tab |
126
126
  | `/btw-close` | Close the current BTW session |
127
+ | `/worktree <name> [task]` | Continue this session in a new managed worktree (`/worktree list` lists them) |
127
128
  | `/subagent <agent> <task>` | Spawn a named agent directly (`/subagent list` lists available agents) |
128
129
 
129
130
  ### Taxonomy and discovery
@@ -149,6 +150,7 @@ The current workflow inventory is:
149
150
  | Planning | `/plan` | Scout → interactive planner → workers → reviewer; writes `.pi/plans/...` artifacts; runs on Pi. |
150
151
  | Iteration | `/iterate` | Opens one interactive full-context Pi fork and returns its completion summary. |
151
152
  | Side question | `/btw`, `/btw-close` | Opens one replaceable interactive Pi side session; its answer stays outside the parent transcript. |
153
+ | Worktree handoff | `/worktree <name> [task]`, `/worktree list` | Forks the active conversation into a long-lived interactive Pi process in a new worktree created from committed `HEAD`; retains the parent session. |
152
154
  | Approved review runner | `herdr_workflow` (low-level control tool) | Validates and runs exact approved project-local JavaScript with bounded read-only Pi reviewers. The bundled `orchestrate` skill authors this first-flow topology. |
153
155
  | Adversarial review | `adversarial-reviewer` | Transitional workflow implementation that selects three distinct authenticated Pi runtimes for generic reviewer passes, preferring provider diversity; it writes `.reviews/...` artifacts. It remains visible and launchable until a dedicated workflow surface replaces it. |
154
156
 
@@ -348,7 +350,7 @@ subagent({
348
350
 
349
351
  | Parameter | Type | Default | Description |
350
352
  | ---------------------- | ------- | -------------- | ------------------------------------------------------------------------------------------------- |
351
- | `name` | string | required | Display name (shown in widget and pane title) |
353
+ | `name` | string | required | Short stable child label; coordinated groups use `<task>-<role>[-n]` (widget and pane title) |
352
354
  | `task` | string | required | Task prompt for the sub-agent |
353
355
  | `agent` | string | — | Load defaults from agent definition |
354
356
  | `fork` | boolean | `false` | Force the full-context fork mode for this spawn, overriding any agent `session-mode` frontmatter |
@@ -361,6 +363,15 @@ subagent({
361
363
  | `cwd` | string | — | Working directory, or source repository when `worktree` is set (see [Role Folders](#role-folders)) |
362
364
  | `worktree` | object | — | Isolated Herdr-managed Git worktree; requires `branch`, with optional `base` (committed `HEAD` by default) |
363
365
 
366
+ ### Naming coordinated children
367
+
368
+ Before launching a new group, choose a short task slug and label each new child
369
+ `<task>-<role>[-n]`, such as `login-api` or `login-test2`. Roles are `plan`,
370
+ `research`, `ui`, `api`, `build`, `test`, `review`, `browser`, `security`,
371
+ `perf`, and `merge`. Leave existing labels unchanged. After the final launch,
372
+ print `name | agent kind | role | model | worktree` and use each name in
373
+ prompts, handoffs, and results.
374
+
364
375
  ### Isolated worktree runs
365
376
 
366
377
  Use one worktree per independent writing task; keep read-only agents in ordinary panes. `cwd` selects the source Git repository, `branch` must be unique, and `base` is resolved to an exact commit before creation. If `base` is omitted, the source checkout's committed `HEAD` is used. Parent-checkout changes that have not been committed are not copied.
@@ -518,6 +529,12 @@ BTW shares the current working directory. It treats inherited work as reference
518
529
 
519
530
  ---
520
531
 
532
+ ## The `/worktree` Workflow
533
+
534
+ `/worktree <worktree> [task]` creates a Herdr-managed worktree from the current committed branch and launches a new interactive Pi session there with the active conversation branch. The original session remains available. Use `/worktree list` to list worktrees for the current repository. This is a new-process handoff, not an in-place move of the existing shell or Pi process.
535
+
536
+ ---
537
+
521
538
  ## Custom Agents
522
539
 
523
540
  Custom agent roles are the package's primary extension mechanism. Create one
package/RELEASING.md CHANGED
@@ -40,7 +40,7 @@ The optional live-provider smoke test is not a release gate:
40
40
  PI_TEST_MODEL="openai-codex/gpt-5.6-luna" PI_TEST_TIMEOUT=180000 npm run test:integration:live
41
41
  ```
42
42
 
43
- Do not release from skipped Herdr tests. Confirm the package preview includes `README.md`, `AGENTS.md`, `docs/`, `agents/`, `skills/orchestrate/SKILL.md`, and `pi-extension/subagents/workflow-worker.js`. Confirm it excludes plans, journals, sessions, prototypes, generated evidence, and local `config.json`, and that the worktree integration tests leave no test workspace behind.
43
+ Do not release from skipped Herdr tests. Confirm the package preview includes `README.md`, `CHANGELOG.md`, `AGENTS.md`, `docs/`, `agents/`, `skills/orchestrate/SKILL.md`, and `pi-extension/subagents/workflow-worker.js`. Confirm it excludes plans, journals, sessions, prototypes, generated evidence, and local `config.json`, and that the worktree integration tests leave no test workspace behind.
44
44
 
45
45
  ## npm authentication
46
46
 
@@ -75,12 +75,15 @@ Choose the semantic version increment:
75
75
  Create the version commit without a local tag:
76
76
 
77
77
  ```bash
78
+ git fetch --tags --prune
78
79
  npm version patch --no-git-tag-version
79
- git add package.json package-lock.json
80
+ git add package.json package-lock.json CHANGELOG.md
80
81
  git commit -m "chore: release v$(node -p \"require('./package.json').version\")"
81
82
  git push origin main
82
83
  ```
83
84
 
85
+ The `npm version` hook regenerates `CHANGELOG.md` with `auto-changelog`. Use `npm run changelog` to regenerate it without changing the version.
86
+
84
87
  Replace `patch` with `minor` or `major` when appropriate. The push triggers the **Release** workflow, which installs dependencies, runs lint and unit tests, previews package contents, publishes to npm with provenance, creates and pushes the version tag, and creates the GitHub Release.
85
88
 
86
89
  You can rerun a failed or incomplete release from **Actions → Release → Run workflow**. If npm already has `PACKAGE_NAME@VERSION`, the workflow reads that version's `gitHead` and continues only when it matches `GITHUB_SHA` (exact-commit retry). A foreign publish fails before tag or GitHub Release creation. Existing tags are verified to point at the release commit. The workflow does not create a GitHub Release for a version that still needs publish and failed to publish.
@@ -0,0 +1,93 @@
1
+ # Pi session handoff into a Herdr worktree
2
+
3
+ **Date:** 2026-08-13
4
+ **Scope:** Read-only feasibility research for `pi-herdr-agents`. This is evidence, not a shipped contract.
5
+
6
+ ## Result
7
+
8
+ **A full-context Pi child in a newly created Herdr worktree is already feasible and partly implemented.** A `subagent({ fork: true, worktree: ... })` creates the worktree, writes a child session with the worktree as its `cwd`, copies parent context before the triggering user turn, and launches a separate Pi process in the worktree root pane.
9
+
10
+ **Replacing the current Pi runtime with that fork is supported by Pi's public extension API, but does not move or restart the existing terminal process.** `ctx.switchSession()` rebuilds Pi's cwd-bound runtime from the fork session header. It cannot change the shell's actual cwd, and Herdr pane movement does not change a running process's cwd. Therefore a single operation cannot truthfully promise both “same Pi process switched” and “shell is in the worktree.”
11
+
12
+ The smallest safe product is a **new explicit handoff command** which creates a full session fork in the worktree and starts/focuses a new Pi process in the worktree's root pane. It should leave the old parent Pi process idle and its session intact. Treat it as a user-visible session handoff, not a process move. Do not use `subagent_resume` for this purpose.
13
+
14
+ ## Evidence
15
+
16
+ ### Pi session capability
17
+
18
+ - Pi sessions are persisted JSONL trees. A child session may declare `parentSession`; the session header also owns `cwd`. Pi documents both fields and the active-branch semantics. [Pi session format](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/session-format.md)
19
+ - `SessionManager.createBranchedSession(leafId)` extracts one root-to-leaf branch. `SessionManager.forkFrom(sourcePath, targetCwd, sessionDir?, options?)` creates a full-history fork whose target cwd is explicit. These are public declarations in the installed Pi package: [`session-manager.d.ts`](../../node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.d.ts), lines 306–341; documented at [Pi session format — SessionManager API](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/session-format.md#sessionmanager-api).
20
+ - A command extension can replace the active runtime through `ctx.switchSession(path, { withSession })`; after replacement Pi has torn down the old runtime and rebound extensions, and `withSession` receives the fresh context. The API deliberately says not to reuse captured old session-bound objects. [Pi extensions — session replacement](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/extensions.md#session-replacement-lifecycle-and-footguns); installed declaration: [`types.d.ts`](../../node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.d.ts), lines 247–306.
21
+ - Pi's runtime API recreates cwd-bound services on session replacement. `AgentSessionRuntime.switchSession()` has an internal `cwdOverride`, but the extension command API does not expose it; a session header with `cwd: <worktree>` is therefore the supported extension route. [Pi SDK — AgentSessionRuntime](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/sdk.md#agent-session-runtime); installed declaration: [`agent-session-runtime.d.ts`](../../node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.d.ts), lines 43–89.
22
+
23
+ ### Herdr capability and limit
24
+
25
+ - `herdr worktree create --cwd ... --branch ... --base ... --no-focus` creates a Git worktree checkout and its own normal Herdr workspace/root pane. `herdr workspace focus <id>` focuses that workspace. [Herdr CLI reference](https://herdr.dev/docs/cli-reference/)
26
+ - Herdr supports `pane move <pane> --new-workspace` and cross-workspace pane moves. But its CLI reference states that a moved running process retains its launch-time Herdr IDs and the old pane ID remains an alias. It offers no command to change a running process's cwd. Moving the Pi pane is layout-only, not a worktree-shell restart. [Herdr CLI reference — pane move](https://herdr.dev/docs/cli-reference/)
27
+ - Herdr reports `foreground_cwd` when it can resolve it, separately from pane/workspace `cwd`; that distinction confirms that workspace association is not authority to rewrite a live process cwd. [Herdr CLI reference — pane inspection](https://herdr.dev/docs/cli-reference/)
28
+
29
+ ### Current extension implementation
30
+
31
+ - `launchPiSubagent()` owns the current worktree transaction: it resolves the base SHA, writes the ownership manifest before Herdr resource creation, calls `createWorktree`, waits for the returned root pane, and starts Pi there. [`pi-extension/subagents/launch.ts`](../../pi-extension/subagents/launch.ts), `launchPiSubagent`, `prepareLaunchSurface`, `prepareChildSession`, and `buildPiCommand` (lines 174–525).
32
+ - For `worktree`, `prepareLaunchSurface()` sets `targetCwd` to `created.path`; `buildPiCommand()` begins with `cd <targetCwd> && pi --session <child>`. Thus the child process and its initial shell command run at the worktree root. [`launch.ts`](../../pi-extension/subagents/launch.ts), lines 257–335 and 415–495.
33
+ - `fork: true` selects `sessionMode === "fork"`. `seedSubagentSessionFile()` creates a child session header with `cwd: childCwd` and `parentSession`, then copies entries from the parent file before its last user message. The triggering task is delivered directly, so the current child sees the inherited conversation plus the explicit task. [`launch.ts`](../../pi-extension/subagents/launch.ts), `resolveLaunchRequest` and `prepareTaskArtifacts`; [`session.ts`](../../pi-extension/subagents/session.ts), `seedSubagentSessionFile` and `getForkContentLines`.
34
+ - `/iterate` currently asks the parent model to invoke `subagent` with `fork: true, interactive: true`; it does not create a worktree or replace the parent session. [`pi-extension/subagents/index.ts`](../../pi-extension/subagents/index.ts), `/iterate` command at lines 3840–3851.
35
+ - `/btw` is the closest session snapshot precedent: it captures the active leaf with `createBtwSessionSnapshot()`, opens a non-focused pane, and launches a second Pi process. It deliberately keeps the parent unchanged and shares its cwd. [`index.ts`](../../pi-extension/subagents/index.ts), `/btw` handler at lines 3732–3834; [`session.ts`](../../pi-extension/subagents/session.ts), `createBtwSessionSnapshot`.
36
+ - `subagent_resume` explicitly opens a new ordinary pane and has no worktree lifecycle. This is documented as a current limit. [`docs/worktree-subagents.md`](../worktree-subagents.md#failure-help-and-restart-behavior).
37
+
38
+ ## Current behavior versus requested behavior
39
+
40
+ | Requested property | Current state | Evidence / gap |
41
+ | --- | --- | --- |
42
+ | Create managed Git worktree | Shipped | Manifest before `herdr worktree create`; retained workspace. |
43
+ | Fork current conversation into it | Mostly shipped for a child spawn | `fork: true` copies parent context before the triggering user turn and records parent linkage. It is not the native full-history `SessionManager.forkFrom()` API. |
44
+ | Carry explicit handoff context | Shipped for child task | Fork task is passed directly after inherited context. A named, durable handoff entry is not written. |
45
+ | Worktree shell starts at worktree root | Shipped | Launch command uses `cd <worktree> && pi ...` in Herdr's returned root pane. |
46
+ | Parent's active Pi session switches to fork | Not shipped | Current worktree launch is a separate child Pi process. |
47
+ | Existing parent pane moves/restarts into worktree | Not shipped; move alone is insufficient | Herdr can move panes but cannot change a live process cwd. |
48
+
49
+ ## Smallest safe design
50
+
51
+ Add one parent-only command, for example `/handoff-worktree <branch> [base]`, rather than changing ordinary `subagent` semantics.
52
+
53
+ 1. Require `ctx.waitForIdle()`, a persisted parent session file, selected model, and a cleanly resolved committed base.
54
+ 2. Reuse the existing worktree creation/manifest transaction. Keep its no-focus creation and exact-base rules.
55
+ 3. Create a target-cwd fork from the current active leaf, then append one visible user/custom handoff message to the *child* session containing the explicit task, base SHA, branch, source session path, and worktree path. `SessionManager.forkFrom()` is public and gives the target cwd, but copies the source file's full entry set; do not use it blindly when the source contains abandoned branches. Reuse or extract the active-branch logic in `session.ts` and ensure the child header names the worktree cwd. Bound the handoff size; do not copy secrets or arbitrary environment data.
56
+ 4. Start a new `pi --session <fork-file>` process in the returned worktree root pane. This reuses the proven `cd <worktree> && pi` launch pattern. Use a normal interactive Pi session, not a watcher-owned autonomous subagent.
57
+ 5. After a successful launch, call `herdr workspace focus <worktreeWorkspaceId>` (or present the workspace ID for the user to focus). The user is now operating the forked session in the correct checkout.
58
+ 6. Leave the original Pi process/session untouched and idle. Record both session paths and the workspace in the manifest. Do not auto-close either process, merge, push, or delete the worktree.
59
+
60
+ This has one intentional limitation: it is a **new-process handoff**, not in-place replacement. It is smaller and safer than coordinating parent process exit, cross-workspace pane movement, shell `cd`, and Pi restart.
61
+
62
+ ## Alternative: in-process context switch
63
+
64
+ An extension command can create a target-cwd fork and call `await ctx.switchSession(forkFile, { withSession: async next => next.sendUserMessage(handoff) })`. That gives the current Pi runtime the fork session and refreshes cwd-bound Pi resources. It is viable only when the terminal location is allowed to remain the old parent pane.
65
+
66
+ Do **not** combine it with `herdr pane move` and claim success: the running Pi and its shell retain their existing OS cwd. A correct “same pane, worktree shell” version needs an explicit supervised restart protocol outside the Pi process: persist the fork and launch intent, gracefully exit Pi, then have an external launcher issue `cd <worktree> && pi --session <fork>`. Neither Pi's public extension API nor the cited Herdr CLI provides that lifecycle as one atomic operation.
67
+
68
+ ## Safety risks and required guards
69
+
70
+ - **Concurrent session writes:** Never run two Pi processes against the same JSONL. Fork to a new file before launch; retain the source session as read-only reference.
71
+ - **Conversation fidelity:** The current `fork: true` helper copies raw lines only before the last user entry, so it intentionally omits the triggering user request and may not represent the active tree as precisely as `createBranchedSession()`/`forkFrom()`. Use Pi's public fork API for the handoff command and test branches plus compaction.
72
+ - **Uncommitted parent state:** The worktree excludes uncommitted/untracked files. Preserve the existing rule: refuse no worktree creation, pass explicit handoff context, and state the exact committed base. [Worktree guide](../worktree-subagents.md#launch-contract).
73
+ - **Partial creation/launch:** Keep the existing ownership manifest-before-resource invariant; if launch fails, retain the worktree and report its path/workspace/session rather than attempting destructive cleanup.
74
+ - **Parent watcher semantics:** Do not register the handoff process as an ordinary autonomous subagent or steer its result into the old session. It is user-driven and long-lived.
75
+ - **Focus is not ownership:** Focus only after the new Pi launch succeeds. A focus failure must not imply launch failure; report both independently.
76
+ - **Restart recovery:** Preserve session/worktree metadata. Existing worktree lifecycle has no automatic full-process restart recovery, so do not claim durable reattachment. [Worktree guide](../worktree-subagents.md#failure-help-and-restart-behavior).
77
+
78
+ ## Verification needed before implementation
79
+
80
+ 1. Unit: native fork has target `cwd`, parent linkage, full active branch, compaction compatibility, and one bounded handoff message; parent JSONL is byte-for-byte unchanged.
81
+ 2. Unit: manifest exists before Herdr creation; a launch failure retains all recorded identifiers.
82
+ 3. Integration in Herdr: the returned root pane reports `pwd == worktreePath`; the launched Pi reports the fork session and inherits the expected conversation plus handoff.
83
+ 4. Integration: focus transfers only after successful launch; parent transcript receives no autonomous result and parent session file remains unchanged.
84
+ 5. Regression: ordinary `subagent({ worktree })`, `/iterate`, `/btw`, and `subagent_resume` retain their documented behavior.
85
+
86
+ ## Primary sources
87
+
88
+ - [Pi README — sessions and `--fork`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/README.md#sessions)
89
+ - [Pi session format and SessionManager API](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/session-format.md)
90
+ - [Pi extensions — session replacement lifecycle](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/extensions.md#session-replacement-lifecycle-and-footguns)
91
+ - [Pi SDK — AgentSessionRuntime](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/sdk.md#agentsessionruntime-and-agentsessionruntime)
92
+ - [Herdr CLI reference](https://herdr.dev/docs/cli-reference/)
93
+ - [Current worktree operating contract](../worktree-subagents.md)
@@ -46,6 +46,8 @@ For a worktree launch:
46
46
  - Uncommitted and untracked files from the parent checkout are not copied. Commit anything the child must see before spawning it, or pass the needed context in the task.
47
47
  - Worktree creation does not steal terminal focus.
48
48
 
49
+ For an explicit interactive handoff, use `/worktree <worktree> [task]`. It creates the worktree from the current committed branch, forks the active conversation branch into the target-cwd session, launches a normal long-lived Pi process in the returned root pane, and focuses the destination workspace only after Herdr confirms Pi is running with the expected session and worktree cwd. Use `/worktree list` to inspect worktrees for the current repository. The original process and session remain intact; pane movement is not used to change a running shell's cwd.
50
+
49
51
  `worktree` cannot be set in agent frontmatter and is not exposed by the `/subagent <agent> <task>` shorthand. It is selected per call to the `subagent` tool. Ordered model fallback lists are not supported for worktree subagents: a failed attempt retains its worktree and branch for review, so a retry cannot safely reuse the requested branch.
50
52
 
51
53
  ## Parent and worker responsibilities
@@ -169,8 +171,8 @@ The extension never pushes, creates a PR, merges, cherry-picks, or changes the p
169
171
 
170
172
  ## Failure, help, and restart behavior
171
173
 
172
- - **Creation failure:** the manifest is marked failed; no successful worktree handoff is expected.
173
- - **Launch failure after creation:** the manifest is marked failed and the workspace/path are retained in the error.
174
+ - **Creation failure:** the manifest is marked failed. If Herdr created the branch but returned an incomplete response, the extension reconciles a unique branch match through `/worktree list` and records any recovered workspace/path.
175
+ - **Launch failure after creation:** the manifest is marked failed and the workspace, forked session, and path are retained. The destination is not focused unless Pi startup is confirmed.
174
176
  - **Worker failure:** summary and available Git state are returned; the workspace remains open.
175
177
  - **`caller_ping`:** the child exits with `needs_help`; continue worktree-bound follow-up in the retained workspace rather than through `subagent_resume`.
176
178
  - **Parent `/reload`, `/new`, `/resume`, or `/fork`:** active in-memory watchers transfer to the replacement parent session.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-herdr-agents",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Asynchronous Pi subagents and approved review workflows in Herdr, with optional isolated Git worktrees",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -29,10 +29,17 @@
29
29
  },
30
30
  "type": "module",
31
31
  "scripts": {
32
+ "changelog": "auto-changelog",
32
33
  "lint": "oxlint pi-extension test",
33
34
  "test": "node --experimental-strip-types --test test/test.ts test/launch.test.ts test/runtime-routing.test.ts test/release-workflow.test.ts test/workflow.test.ts test/package-skill.test.js",
34
35
  "test:integration": "node --experimental-strip-types --test --test-concurrency=1 test/integration/*.test.ts",
35
- "test:integration:live": "PI_TEST_LIVE=1 node --experimental-strip-types --test --test-concurrency=1 test/integration/*.test.ts"
36
+ "test:integration:live": "PI_TEST_LIVE=1 node --experimental-strip-types --test --test-concurrency=1 test/integration/*.test.ts",
37
+ "version": "auto-changelog --package && git add CHANGELOG.md"
38
+ },
39
+ "auto-changelog": {
40
+ "commitLimit": false,
41
+ "template": "keepachangelog",
42
+ "unreleased": true
36
43
  },
37
44
  "peerDependencies": {
38
45
  "@earendil-works/pi-ai": "*",
@@ -53,6 +60,7 @@
53
60
  "@earendil-works/pi-coding-agent": "^0.84.0",
54
61
  "@earendil-works/pi-tui": "^0.84.0",
55
62
  "@sinclair/typebox": "^0.34.52",
63
+ "auto-changelog": "^2.6.0",
56
64
  "oxlint": "^1.73.0"
57
65
  }
58
66
  }