@esso0428/pi-subagents 0.17.19 → 0.17.20

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,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.17.20] - 2026-10-01
11
+
12
+ ### Changed
13
+ - **Removed blocking waits from `get_subagent_result`**: the legacy `wait` parameter is now a non-blocking compatibility flag. Running or queued agents return their current status immediately, while background and wait-group completion notifications remain the expandable output surface for finished results.
14
+
10
15
  ## [0.17.19] - 2026-09-30
11
16
 
12
17
  ### Added
package/README.md CHANGED
@@ -432,10 +432,10 @@ Check status and retrieve results from a background agent.
432
432
  | Parameter | Type | Required | Description |
433
433
  |-----------|------|----------|-------------|
434
434
  | `agent_id` | string | yes | Agent ID to check |
435
- | `wait` | boolean | no | Wait for completion |
435
+ | `wait` | boolean | no | Deprecated compatibility flag; never blocks |
436
436
  | `verbose` | boolean | no | Include full conversation log |
437
437
 
438
- Cancelling a `wait: true` call (for example, with `Esc`) stops only the wait. The background agent keeps running, and its completion notification still arrives normally.
438
+ `get_subagent_result` never blocks. If an agent is still running or queued, the tool returns the current status immediately; wait for the background or wait-group completion notification for the expandable final output.
439
439
 
440
440
  ### `steer_subagent`
441
441
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esso0428/pi-subagents",
3
- "version": "0.17.19",
3
+ "version": "0.17.20",
4
4
  "description": "A pi extension that brings smart Claude Code-style autonomous sub-agents to pi, with npm:pi-subagents-style JSON agent overrides.",
5
5
  "author": "ESSO0428",
6
6
  "repository": {
package/src/index.ts CHANGED
@@ -61,39 +61,6 @@ function textResult(msg: string, details?: AgentDetails) {
61
61
  return { content: [{ type: "text" as const, text: msg }], details: details as any };
62
62
  }
63
63
 
64
- /** Await a promise until it settles or the caller cancels, without aborting the underlying work. */
65
- function abortable<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {
66
- if (!signal) return promise;
67
- if (signal.aborted) return Promise.reject(signal.reason);
68
-
69
- return new Promise<T>((resolve, reject) => {
70
- let settled = false;
71
- const cleanup = () => signal.removeEventListener("abort", onAbort);
72
- const onAbort = () => {
73
- if (settled) return;
74
- settled = true;
75
- cleanup();
76
- reject(signal.reason);
77
- };
78
-
79
- signal.addEventListener("abort", onAbort, { once: true });
80
- promise.then(
81
- (value) => {
82
- if (settled) return;
83
- settled = true;
84
- cleanup();
85
- resolve(value);
86
- },
87
- (error: unknown) => {
88
- if (settled) return;
89
- settled = true;
90
- cleanup();
91
- reject(error);
92
- },
93
- );
94
- });
95
- }
96
-
97
64
  export function renderRunningAgentStatus(
98
65
  frame: string,
99
66
  statsText: string,
@@ -337,9 +304,6 @@ export default function (pi: ExtensionAPI) {
337
304
  // before they reach pi.sendMessage (fire-and-forget).
338
305
  const pendingNudges = new Map<string, ReturnType<typeof setTimeout>>();
339
306
  const NUDGE_HOLD_MS = 200;
340
- // A queued result wait must observe completion before its held notification
341
- // can fire, so successful waits can still suppress that redundant nudge.
342
- const QUEUE_WAIT_POLL_MS = Math.floor(NUDGE_HOLD_MS / 4);
343
307
 
344
308
  function scheduleNudge(key: string, send: () => void, delay = NUDGE_HOLD_MS) {
345
309
  cancelNudge(key);
@@ -1689,7 +1653,7 @@ Terse command-style prompts produce shallow, generic work.
1689
1653
  }),
1690
1654
  wait: Type.Optional(
1691
1655
  Type.Boolean({
1692
- description: "If true, wait for the agent to complete before returning. Default: false.",
1656
+ description: "Deprecated compatibility flag. Results never block; running agents return current status immediately.",
1693
1657
  }),
1694
1658
  ),
1695
1659
  verbose: Type.Optional(
@@ -1698,27 +1662,12 @@ Terse command-style prompts produce shallow, generic work.
1698
1662
  }),
1699
1663
  ),
1700
1664
  }),
1701
- execute: async (_toolCallId, params, signal, _onUpdate, _ctx) => {
1665
+ execute: async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
1702
1666
  const record = manager.getRecord(params.agent_id);
1703
1667
  if (!record) {
1704
1668
  return textResult(`Agent not found: "${params.agent_id}". It may have been cleaned up.`);
1705
1669
  }
1706
1670
 
1707
- // Wait for completion if requested. Cancellation stops only this tool
1708
- // call; the background agent keeps running and remains unconsumed so its
1709
- // completion notification can still be delivered.
1710
- // Queued agents have no promise yet (it's created when the queue starts
1711
- // them), so poll until they leave the queue, then await like a running one.
1712
- if (params.wait && (record.status === "running" || record.status === "queued")) {
1713
- while (record.status === "queued") {
1714
- await abortable(
1715
- new Promise<void>((resolve) => setTimeout(resolve, QUEUE_WAIT_POLL_MS)),
1716
- signal,
1717
- );
1718
- }
1719
- if (record.promise) await abortable(record.promise, signal);
1720
- }
1721
-
1722
1671
  const durableResult = !record.result?.trim() && record.transcriptPath && currentCtx?.cwd
1723
1672
  ? readAgentHistoryResult(currentCtx.cwd, record.transcriptPath)
1724
1673
  : undefined;
@@ -1737,8 +1686,10 @@ Terse command-style prompts produce shallow, generic work.
1737
1686
  `Type: ${displayName} | Status: ${record.status}${getStatusNote(record.status)} | ${statsParts.join(" | ")}\n` +
1738
1687
  `Description: ${record.description}\n\n`;
1739
1688
 
1740
- if (record.status === "running") {
1741
- output += "Agent is still running. Use wait: true or check back later.";
1689
+ if (record.status === "running" || record.status === "queued") {
1690
+ output += params.wait
1691
+ ? `Agent is still ${record.status}. wait:true is deprecated and no longer blocks; wait for the background completion notification or check again later.`
1692
+ : `Agent is still ${record.status}. Wait for the background completion notification or check again later.`;
1742
1693
  } else if (record.status === "error") {
1743
1694
  output += `Error: ${record.error}${partialOutputSuffix(record, durableResult)}`;
1744
1695
  } else {