pi-herdr-agents 2.0.2 → 2.0.4
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 +18 -1
- package/README.md +1 -1
- package/docs/worktree-subagents.md +1 -1
- package/package.json +1 -1
- package/pi-extension/subagents/herdr.ts +1 -0
- package/pi-extension/subagents/index.ts +35 -16
package/CHANGELOG.md
CHANGED
|
@@ -7,13 +7,30 @@ 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
|
-
## [v2.0.
|
|
10
|
+
## [v2.0.4](https://github.com/giuseppecrj/pi-herdr-agents/compare/v2.0.3...v2.0.4)
|
|
11
|
+
|
|
12
|
+
### Merged
|
|
13
|
+
|
|
14
|
+
- perf: batch persistent delivery ledger reads [`#58`](https://github.com/giuseppecrj/pi-herdr-agents/pull/58)
|
|
15
|
+
|
|
16
|
+
## [v2.0.3](https://github.com/giuseppecrj/pi-herdr-agents/compare/v2.0.2...v2.0.3) - 2026-09-21
|
|
17
|
+
|
|
18
|
+
### Commits
|
|
19
|
+
|
|
20
|
+
- fix: skip startup worktree inventory outside Herdr [`34800d7`](https://github.com/giuseppecrj/pi-herdr-agents/commit/34800d79464575063a61ad6f240cd49cc8acd730)
|
|
21
|
+
- chore: release v2.0.3 [`60888f2`](https://github.com/giuseppecrj/pi-herdr-agents/commit/60888f2dea48317257909abbcd0dd374ed861d77)
|
|
22
|
+
|
|
23
|
+
## [v2.0.2](https://github.com/giuseppecrj/pi-herdr-agents/compare/v2.0.1...v2.0.2) - 2026-09-19
|
|
11
24
|
|
|
12
25
|
### Merged
|
|
13
26
|
|
|
14
27
|
- fix(subagents): allow isolated same-family review fallback [`#54`](https://github.com/giuseppecrj/pi-herdr-agents/pull/54)
|
|
15
28
|
- fix(subagents): remove conflicting Ctrl+J shortcut [`#53`](https://github.com/giuseppecrj/pi-herdr-agents/pull/53)
|
|
16
29
|
|
|
30
|
+
### Commits
|
|
31
|
+
|
|
32
|
+
- chore: release v2.0.2 [`49efa52`](https://github.com/giuseppecrj/pi-herdr-agents/commit/49efa52bf671fbef00ad1be2d8b679188c5d1de3)
|
|
33
|
+
|
|
17
34
|
## [v2.0.1](https://github.com/giuseppecrj/pi-herdr-agents/compare/v2.0.0...v2.0.1) - 2026-09-18
|
|
18
35
|
|
|
19
36
|
### Merged
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Delegate investigation, implementation, and review without blocking the parent s
|
|
|
23
23
|
- [Herdr](https://herdr.dev) and its CLI
|
|
24
24
|
- `HERDR_ENV=1` — start Pi from inside Herdr
|
|
25
25
|
|
|
26
|
-
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.
|
|
26
|
+
Other terminal multiplexers are not supported. Outside Herdr, the extension skips automatic startup worktree inventory. Explicit inventory tools still report unavailable inspection as unknown. Worktrees isolate Git checkouts, not processes or permissions; child agents and installed Pi packages run with your user account's access.
|
|
27
27
|
|
|
28
28
|
## Install
|
|
29
29
|
|
|
@@ -231,7 +231,7 @@ Ignored files do not block cleanup. Inventory shows their exact file count, and
|
|
|
231
231
|
|
|
232
232
|
Open workspaces are removed through Herdr. Git-only orphans use `git worktree remove`, verify checkout absence, and then prune stale Git registrations. Failed removal is reported, never forced. A reachable owned manifest is merge-updated to `removed` with `workspaceRemovedAt` only after success; absent cross-session manifests are reported and are not rewritten. A manifest update failure after removal is a removed-with-warning result, not a failed removal. Removed manifests provide already-removed no-op evidence only; a new checkout at the same path is classified independently. Missing and dangling manifest paths are non-matches. Permission errors, symlink loops, and other undecidable manifest identities remain blockers, as do genuine identity disagreements. Cleanup Git and Herdr calls have 30-second timeouts; a timed-out operation fails closed rather than proceeding with removal.
|
|
233
233
|
|
|
234
|
-
Branches and their commits are always retained: cleanup never deletes, force-updates, or rewrites a branch. It never runs on completion, shutdown, or a timer.
|
|
234
|
+
Branches and their commits are always retained: cleanup never deletes, force-updates, or rewrites a branch. It never runs on completion, shutdown, or a timer. Inside Herdr with its CLI available, parent session start emits only one compact inventory count when contained worktrees remain. Outside Herdr, startup skips the automatic inventory; explicit inventory tools remain available and report unavailable inspection as unknown. Unsupported platforms or failed global process enumeration block removal; individual visibility gaps are disclosed warnings, never proof that an orphan is idle.
|
|
235
235
|
|
|
236
236
|
## Current limits
|
|
237
237
|
|
package/package.json
CHANGED
|
@@ -108,6 +108,7 @@ function extractHerdrWorktree(output: string): HerdrWorktreeSurface {
|
|
|
108
108
|
|
|
109
109
|
function herdrExec(args: string[], timeout?: number): string {
|
|
110
110
|
return execFileSync("herdr", args, {
|
|
111
|
+
stdio: "pipe",
|
|
111
112
|
encoding: "utf8",
|
|
112
113
|
timeout,
|
|
113
114
|
killSignal: "SIGKILL",
|
|
@@ -2422,6 +2422,7 @@ export const __test__ = {
|
|
|
2422
2422
|
resolveUnexpectedErrorPresentation,
|
|
2423
2423
|
shouldAdvanceToFallback,
|
|
2424
2424
|
deliverPersistentTaskEvent,
|
|
2425
|
+
drainPersistentTaskEvents,
|
|
2425
2426
|
notifyPersistentCrash,
|
|
2426
2427
|
sendSubagentResult,
|
|
2427
2428
|
shouldRetainSubagentSurface,
|
|
@@ -2657,11 +2658,13 @@ function deliverPersistentTaskEvent(
|
|
|
2657
2658
|
running: RunningSubagent,
|
|
2658
2659
|
event: ReturnType<typeof readPersistentTaskEvents>[number],
|
|
2659
2660
|
api: Pick<ExtensionAPI, "sendMessage">,
|
|
2661
|
+
ledgerSnapshot?: ReturnType<typeof readPersistentDeliveryLedger>,
|
|
2660
2662
|
): void {
|
|
2661
2663
|
if (!running.persistent || event.generation !== running.generationId) return;
|
|
2662
2664
|
const deliveryKey = `${running.id}:${event.type}:${event.task}`;
|
|
2663
2665
|
if (inFlightPersistentTaskDeliveries.has(deliveryKey)) return;
|
|
2664
|
-
const ledger =
|
|
2666
|
+
const ledger =
|
|
2667
|
+
ledgerSnapshot ?? readPersistentDeliveryLedger(running.sessionFile);
|
|
2665
2668
|
if (event.type === "help-request") {
|
|
2666
2669
|
if (
|
|
2667
2670
|
ledger.some(
|
|
@@ -2685,13 +2688,15 @@ function deliverPersistentTaskEvent(
|
|
|
2685
2688
|
},
|
|
2686
2689
|
{ triggerTurn: true, deliverAs: "steer" },
|
|
2687
2690
|
);
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2691
|
+
ledger.push(
|
|
2692
|
+
appendPersistentDeliveryLedger(running.sessionFile, {
|
|
2693
|
+
task: event.task,
|
|
2694
|
+
outcome: "help-requested",
|
|
2695
|
+
generation: running.generationId!,
|
|
2696
|
+
logicalId: running.logicalId!,
|
|
2697
|
+
policyHash: running.policyHash!,
|
|
2698
|
+
}),
|
|
2699
|
+
);
|
|
2695
2700
|
if (running.taskId === event.task) running.taskId = undefined;
|
|
2696
2701
|
} finally {
|
|
2697
2702
|
inFlightPersistentTaskDeliveries.delete(deliveryKey);
|
|
@@ -2724,13 +2729,15 @@ function deliverPersistentTaskEvent(
|
|
|
2724
2729
|
policyHash: running.policyHash!,
|
|
2725
2730
|
},
|
|
2726
2731
|
);
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2732
|
+
ledger.push(
|
|
2733
|
+
appendPersistentDeliveryLedger(running.sessionFile, {
|
|
2734
|
+
task: event.task,
|
|
2735
|
+
outcome: "delivered",
|
|
2736
|
+
generation: running.generationId!,
|
|
2737
|
+
logicalId: running.logicalId!,
|
|
2738
|
+
policyHash: running.policyHash!,
|
|
2739
|
+
}),
|
|
2740
|
+
);
|
|
2734
2741
|
running.tasksCompleted = completed;
|
|
2735
2742
|
if (running.taskId === event.task) running.taskId = undefined;
|
|
2736
2743
|
if (running.stopState === "pending")
|
|
@@ -2743,13 +2750,25 @@ function deliverPersistentTaskEvent(
|
|
|
2743
2750
|
function drainPersistentTaskEvents(
|
|
2744
2751
|
running: RunningSubagent,
|
|
2745
2752
|
api: Pick<ExtensionAPI, "sendMessage">,
|
|
2753
|
+
readLedger = readPersistentDeliveryLedger,
|
|
2746
2754
|
): void {
|
|
2747
2755
|
const events = readPersistentTaskEvents(running.sessionFile);
|
|
2756
|
+
let ledger: ReturnType<typeof readPersistentDeliveryLedger> | undefined;
|
|
2748
2757
|
for (const event of events.slice(running.observedTaskEvents ?? 0)) {
|
|
2758
|
+
if (!running.persistent || event.generation !== running.generationId)
|
|
2759
|
+
continue;
|
|
2760
|
+
if (
|
|
2761
|
+
inFlightPersistentTaskDeliveries.has(
|
|
2762
|
+
`${running.id}:${event.type}:${event.task}`,
|
|
2763
|
+
)
|
|
2764
|
+
)
|
|
2765
|
+
continue;
|
|
2766
|
+
ledger ??= readLedger(running.sessionFile);
|
|
2749
2767
|
deliverPersistentTaskEvent(
|
|
2750
2768
|
running,
|
|
2751
2769
|
event,
|
|
2752
2770
|
selectCompletionApi(api, runtime.pi),
|
|
2771
|
+
ledger,
|
|
2753
2772
|
);
|
|
2754
2773
|
}
|
|
2755
2774
|
running.observedTaskEvents = events.length;
|
|
@@ -3131,7 +3150,7 @@ export default function subagentsExtension(
|
|
|
3131
3150
|
startStatusRefresh(pi);
|
|
3132
3151
|
updateWidget();
|
|
3133
3152
|
}
|
|
3134
|
-
if (parentSession && ctx.cwd && ctx.hasUI) {
|
|
3153
|
+
if (parentSession && ctx.cwd && ctx.hasUI && isTerminalAvailable()) {
|
|
3135
3154
|
try {
|
|
3136
3155
|
const notice = worktreeInventoryNotice(
|
|
3137
3156
|
await listContainedWorktrees(cleanupInput(ctx)),
|