@maxiaochao/pi-toolkit 0.10.23 → 0.10.24

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
@@ -1,3 +1,7 @@
1
+ ## 2026-10-12 - v0.10.24
2
+
3
+ - bundle herdr-subagents v0.4.10: Stabilize concurrency checks and cancellation synchronization on slower CI runners.
4
+
1
5
  ## 2026-10-12 - v0.10.23
2
6
 
3
7
  - bundle herdr-subagents v0.4.9: Stabilize concurrency checks on slower CI runners.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maxiaochao/pi-toolkit",
3
- "version": "0.10.23",
3
+ "version": "0.10.24",
4
4
  "description": "Personal pi coding agent toolkit: scheduler, /btw, /cache_export, apply_patch, browser automation, and bundled theme/skills.",
5
5
  "type": "module",
6
6
  "workspaces": [
@@ -1,3 +1,7 @@
1
+ ## 2026-10-12 - v0.4.10
2
+
3
+ - Stabilize concurrency checks and cancellation synchronization on slower CI runners.
4
+
1
5
  ## 2026-10-12 - v0.4.9
2
6
 
3
7
  - Stabilize concurrency checks on slower CI runners.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maxiaochao/pi-herdr-subagents",
3
- "version": "0.4.9",
3
+ "version": "0.4.10",
4
4
  "description": "Run inspectable interactive Pi subagent batches through Herdr.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -671,10 +671,32 @@ try {
671
671
  check("the parallel run closes only after its last blocked lane is answered", !secondOfBoth.isError && secondOfBoth.details.status === "completed" && secondOfBoth.details.tasks.every((entry) => entry.status === "completed") && bothBlockedHerdr.calls.filter(([name]) => name === "closeTab").length === 1);
672
672
  const mixedCancelHerdr = fakeHerdr();
673
673
  const mixedCancelPrompt = mixedCancelHerdr.promptAgent.bind(mixedCancelHerdr);
674
- mixedCancelHerdr.promptAgent = async (request) => request.prompt.includes("WAIT") ? await new Promise((_resolve, reject) => request.signal?.addEventListener("abort", () => reject(request.signal.reason), { once: true })) : mixedCancelPrompt(request);
674
+ let markMixedFailureSettled;
675
+ let markMixedWaitStarted;
676
+ const mixedFailureSettled = new Promise((resolve) => { markMixedFailureSettled = resolve; });
677
+ const mixedWaitStarted = new Promise((resolve) => { markMixedWaitStarted = resolve; });
678
+ mixedCancelHerdr.promptAgent = async (request) => {
679
+ if (request.prompt.includes("WAIT")) {
680
+ markMixedWaitStarted();
681
+ if (!request.signal) throw new Error("WAIT prompt requires an AbortSignal");
682
+ return await new Promise((_resolve, reject) => {
683
+ if (request.signal.aborted) reject(request.signal.reason);
684
+ else request.signal.addEventListener("abort", () => reject(request.signal.reason), { once: true });
685
+ });
686
+ }
687
+ return mixedCancelPrompt(request);
688
+ };
675
689
  const mixedCancelController = new AbortController();
676
- const mixedCancelPromise = executeHerdrSubagents({ concurrency: 2, tasks: [{ name: "fail-first", prompt: "FAIL", agent: "explorer" }, { name: "cancel-second", prompt: "WAIT", agent: "reviewer" }] }, mixedCancelController.signal, undefined, { cwd: root }, { agentsDirectory: join(process.cwd(), "agents"), herdr: mixedCancelHerdr });
677
- await new Promise((resolve) => setTimeout(resolve, 10));
690
+ const mixedCancelPromise = executeHerdrSubagents(
691
+ { concurrency: 2, tasks: [{ name: "fail-first", prompt: "FAIL", agent: "explorer" }, { name: "cancel-second", prompt: "WAIT", agent: "reviewer" }] },
692
+ mixedCancelController.signal,
693
+ (update) => {
694
+ if (update.details?.tasks?.some((task) => task.status === "failed")) markMixedFailureSettled();
695
+ },
696
+ { cwd: root },
697
+ { agentsDirectory: join(process.cwd(), "agents"), herdr: mixedCancelHerdr },
698
+ );
699
+ await Promise.all([mixedFailureSettled, mixedWaitStarted]);
678
700
  mixedCancelController.abort(new Error("Parent Pi session closed."));
679
701
  const mixedCancel = await mixedCancelPromise;
680
702
  check("failed and cancelled production tasks aggregate to partial", mixedCancel.details.status === "partial" && mixedCancel.details.tasks.some((task) => task.status === "failed") && mixedCancel.details.tasks.some((task) => task.status === "cancelled"));