pi-subagents 0.32.0 → 0.33.1

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +34 -2
  2. package/README.md +147 -58
  3. package/install.mjs +2 -1
  4. package/package.json +3 -2
  5. package/skills/pi-subagents/SKILL.md +75 -17
  6. package/src/agents/agent-management.ts +177 -5
  7. package/src/agents/agent-memory.ts +254 -0
  8. package/src/agents/agent-serializer.ts +11 -0
  9. package/src/agents/agents.ts +142 -12
  10. package/src/agents/chain-serializer.ts +27 -2
  11. package/src/extension/doctor.ts +1 -9
  12. package/src/extension/fanout-child.ts +2 -2
  13. package/src/extension/index.ts +65 -90
  14. package/src/extension/rpc.ts +369 -0
  15. package/src/extension/schemas.ts +52 -8
  16. package/src/extension/tool-description.ts +200 -0
  17. package/src/intercom/intercom-bridge.ts +21 -253
  18. package/src/intercom/native-supervisor-channel.ts +519 -0
  19. package/src/runs/background/async-execution.ts +51 -7
  20. package/src/runs/background/async-job-tracker.ts +12 -2
  21. package/src/runs/background/async-status.ts +27 -2
  22. package/src/runs/background/completion-batcher.ts +166 -0
  23. package/src/runs/background/control-channel.ts +106 -1
  24. package/src/runs/background/fleet-view.ts +515 -0
  25. package/src/runs/background/notify.ts +161 -44
  26. package/src/runs/background/result-watcher.ts +1 -2
  27. package/src/runs/background/run-id-resolver.ts +3 -2
  28. package/src/runs/background/run-status.ts +166 -6
  29. package/src/runs/background/scheduled-runs.ts +514 -0
  30. package/src/runs/background/subagent-runner.ts +409 -35
  31. package/src/runs/background/wait.ts +353 -0
  32. package/src/runs/foreground/chain-execution.ts +95 -21
  33. package/src/runs/foreground/execution.ts +150 -21
  34. package/src/runs/foreground/subagent-executor.ts +378 -64
  35. package/src/runs/shared/dynamic-fanout.ts +1 -1
  36. package/src/runs/shared/model-fallback.ts +167 -20
  37. package/src/runs/shared/model-scope.ts +128 -0
  38. package/src/runs/shared/nested-events.ts +31 -0
  39. package/src/runs/shared/parallel-utils.ts +1 -0
  40. package/src/runs/shared/pi-args.ts +30 -1
  41. package/src/runs/shared/subagent-prompt-runtime.ts +123 -3
  42. package/src/runs/shared/tool-budget.ts +74 -0
  43. package/src/runs/shared/turn-budget.ts +52 -0
  44. package/src/shared/artifacts.ts +1 -0
  45. package/src/shared/atomic-json.ts +15 -2
  46. package/src/shared/child-transcript.ts +212 -0
  47. package/src/shared/settings.ts +3 -1
  48. package/src/shared/types.ts +134 -19
  49. package/src/slash/prompt-workflows.ts +330 -0
  50. package/src/slash/slash-commands.ts +16 -2
  51. package/src/tui/render.ts +16 -8
  52. package/src/extension/companion-suggestions.ts +0 -359
package/CHANGELOG.md CHANGED
@@ -2,16 +2,48 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
- ### Added
5
+ ## [0.33.1] - 2026-07-03
6
6
 
7
7
  ### Fixed
8
+ - Avoid native supervisor-channel tool conflicts when `pi-intercom` is also installed by deferring native tool registration until runtime startup and keeping a namespaced native supervisor reply tool.
9
+
10
+ ## [0.33.0] - 2026-07-03
11
+
12
+ ### Added
13
+ - Added optional `toolBudget` limits for child subagent tool calls. Runs, steps, and agents can set `{ soft?, hard, block? }`; the child runtime nudges at the soft limit and blocks configured tools after the hard limit so runaway browsing can still finish with final text.
14
+ - Added a stable v1 in-process event-bus RPC for other Pi extensions, with `ping`, `status`, async-only `spawn`, `interrupt`, and async `stop` over versioned request/reply envelopes.
15
+ - Added `toolDescriptionMode` with `full`, `compact`, and `custom` modes for the parent-facing `subagent` tool description. Compact mode reduces prompt bloat while keeping safety-critical orchestration guidance, and invalid custom descriptions fall back to full mode.
16
+ - Added an optional read-only subagent fleet/status view with `/subagents-fleet` and `subagent({ action: "status", view: "fleet" })`, plus `view: "transcript"` to tail active async child output/session artifacts.
17
+ - Added uniform per-child transcript artifacts (`<run>_<agent>_transcript.jsonl`) for foreground and async subagent runs, gated by `subagents.artifacts.includeTranscript` (default on). Each transcript is a versioned JSONL stream of child messages, tool starts/ends, and stdout/stderr lines with a byte cap and truncation marker.
18
+ - Added `subagent({ action: "steer", id, message, index? })` for non-terminal guidance to live async Pi child sessions, with file-backed control requests, per-child steering inboxes, status/event visibility, and queued delivery for pending indexed async children when the runtime supports mid-run steering.
19
+ - Added an optional `turnBudget` (`maxTurns` with `graceTurns`) for foreground and async/background subagent runs. At the soft `maxTurns` limit the child is warned via its system prompt to wrap up; after `graceTurns` additional assistant turns the run is aborted and partial output is returned. `turnBudget`, `turnBudgetExceeded`, and `wrapUpRequested` propagate through results, async status, and nested summaries.
20
+ - Added optional scheduled subagent runs so callers can defer a subagent launch until a future time. `subagent({ action: "schedule", agent, task?, schedule: "+10m" | "2030-01-01T09:00:00Z", scheduleName? })` arms a one-shot timer that launches the run as a normal tracked async run once it fires, with `schedule-list`, `schedule-status`, and `schedule-cancel` management actions. Schedules are persisted per session and restored after a Pi restart; jobs missed by more than the configured lateness window are marked `missed` instead of firing late. The feature is opt-in and requires `{ "scheduledRuns": { "enabled": true } }` in `~/.pi/agent/extensions/subagent/config.json`. Only schedule explicit delayed runs the user asked for. Thanks to @tintinweb for the concept.
21
+ - Added a real Pi-session E2E test lane with faux provider routing to verify parent-child subagent result delivery without network model calls.
22
+ - Hardened the `wait` tool's wake path so an event wake cancels its poll-interval fallback timer instead of letting both run, and so an already-aborted turn resolves immediately. Added a test that verifies an event wakes `wait` before the poll interval elapses.
23
+ - Added smart completion batching for async subagent notifications. Successful sibling completions that finish within a short window now arrive as a single grouped message instead of separate notifications; a hard max-wait cap prevents holding them indefinitely, and late-finishing siblings join a shorter straggler group. Failed and paused completions bypass batching and fire immediately so failure and attention signals are never delayed. The debounce window, max-wait cap, and straggler windows are configurable via `completionBatch` in `config.json`.
24
+ - Added `subagent({ action: "eject" })`, `disable`, `enable`, and `reset` management actions for bundled and custom agents. `eject` copies a builtin or package agent to user/project scope as an editable custom file that shadows the original; `disable`/`enable` toggle a reversible `agentOverrides.<name>.disabled` settings override without deleting the agent; `reset` removes the scope's custom agent file and/or settings override to restore the bundled default. All four accept `agentScope: "user" | "project"` (default `user`) and are blocked from child-safe fanout mode alongside `create`/`update`/`delete`.
25
+ - Added fuzzy model resolution so callers can specify models with provider separator variations, optional date-stamp parts, and case differences instead of exact `provider/modelId` strings. When `subagents.modelScope: { enforce: true, allow: [...] }` is configured, explicit caller-supplied out-of-scope models error while frontmatter/parent-inherited/fallback models warn. Inspired by @tintinweb's pi-subagents.
26
+ - Added a parent-side `wait` tool for detached async subagent runs. `wait()` returns when the next active run finishes or needs attention, `wait({ all: true })` drains all active runs, `wait({ id })` targets one run, and `wait({ timeoutMs })` caps the block. This lets background-launching skills and non-interactive `pi -p` runs keep going without sleep/status-polling loops or abandoned children. Thanks to RoboBryce (@robobryce) for #365.
27
+ - Added an opt-in `memory` frontmatter field for agent definitions so recurring custom agents can maintain role-specific durable memory (e.g. a security reviewer accumulating threat-model notes). `memory: { scope: "project" | "user", path: "<name>" }` resolves a safe `agent-memory/` directory, injects the first 200 lines of a `MEMORY.md` into the child system prompt, and falls back to a read-only memory block for agents without write tools. Memory lives under a dedicated namespace that does not conflict with Pi's parent/session/project memory system. Inspired by @tintinweb's pi-subagents.
28
+ - Added native supervisor coordination for child subagents. Children can use `contact_supervisor` without installing `pi-intercom`, and parent-side requests are scoped to the exact session id that spawned the child.
29
+ - Added native prompt workflow commands: `/prompt-workflow` runs a prompt template through a subagent, and `/chain-prompts` turns prompt templates into native subagent chain steps.
30
+
31
+ ### Fixed
32
+ - Let foreground sequential chain tool calls launch directly when `clarify` is omitted; use `clarify: true` to opt into the clarify UI. Addresses #385.
33
+ - Tolerate execution-mode action aliases such as `single`, `parallel`, `PARALLEL`, and `tasks` when the matching execution fields are present, while preserving clear runtime errors for unknown management actions, addressing #382.
34
+ - Removed companion-package recommendation messages from session start, `subagent({ action: "list" })`, and `/subagents-doctor`, addressing #381.
35
+ - Scope async subagent completion notifications to the exact owning Pi session so another session in the same repo no longer receives result notices.
36
+ - Harden scheduled-run timestamp parsing and persisted store validation so ambiguous absolute times and corrupted job records fail clearly instead of being normalized or dropped.
37
+ - Derive live-detail and full-notification hints from Pi's configured expand key instead of hard-coding `Ctrl+O`. Thanks to Kylegl (@kylegl) for #364.
38
+ - Tolerate transient Windows `EPERM`/`EBUSY`/`EACCES` locks when atomically replacing async JSON files. Thanks to ThanhNT29Jacky (@ThanhNT29Jacky) for #380.
39
+ - Hardened the async timeout integration test to wait for the mock child to spawn before asserting the timeout result, fixing a race where the timeout could fire before the child existed.
8
40
 
9
41
  ## [0.32.0] - 2026-07-01
10
42
 
11
43
  ### Added
12
44
  - Added `subagents.defaultModel` so subagents can have a global default model separate from the parent session model. Thanks to Artem Timofeev (@atimofeev) for #339.
13
45
  - Added `/subagent-cost` and `totalChildUsage` run details so parent sessions can inspect aggregate subagent child usage and cost. Thanks to Aaron Ky-Riesenbach (@aaronkyriesenbach) for #343.
14
- - Added configurable companion package recommendations for `pi-intercom` and `pi-prompt-template-model`, surfaced in session-start transcript messages, `subagent({ action: "list" })`, and `/subagents-doctor`, with `/subagents-companions` hide/show/status controls.
46
+ - Added configurable companion package recommendations for `pi-intercom` and `pi-prompt-template-model`, surfaced in session-start transcript messages, `subagent({ action: "list" })`, and `/subagents-doctor`, with `/subagents-companions` hide/show/status controls. Removed again in the next release after #381 because context-visible package recommendations were too noisy.
15
47
  - Added detached async runner stdout and stderr log files. Thanks to Daniel Mateos Carballares (@danim47c) for #358.
16
48
  - Added `totalCost` rollups to foreground single, parallel, and chain run details, including nested foreground subagent costs and compact progress display. Thanks to Clark Everson (@gr3enarr0w) for #345.
17
49
  - Added `globalConcurrencyLimit` to cap simultaneously running subagent tasks across parallel groups in a single run. Thanks to Clark Everson (@gr3enarr0w) for #349.
package/README.md CHANGED
@@ -95,7 +95,7 @@ Those are ordinary Pi requests. Pi decides whether to call `subagent`, which age
95
95
  | Run in the background | “Run this in the background.” |
96
96
  | Browse agents | “Show me the available subagents.” |
97
97
  | Use a saved workflow | “Run the review chain on this branch.” |
98
- | See running work | “Show active async runs.” |
98
+ | See running work | “Show active async runs.” or “Show the subagent fleet.” |
99
99
  | Check setup | “Check whether subagents are configured correctly.” |
100
100
 
101
101
  The extension ships with builtin agents you can use immediately.
@@ -168,11 +168,28 @@ To inspect what `pi-subagents` has actually loaded right now, use:
168
168
 
169
169
  That reports the live runtime mapping, which can differ from settings on disk until you reload Pi.
170
170
 
171
+ You do not have to spell a model exactly. Model ids are matched fuzzily against the registry, so provider separator variations (`anthropic/claude-sonnet-4`, `anthropic:claude-sonnet-4`, or `anthropic.claude-sonnet-4`), id separator variations (`claude-haiku-4.5` vs `claude-haiku-4-5`), case differences (`Claude-Sonnet-4` vs `claude-sonnet-4`), and optional trailing date stamps (`claude-haiku-4-5-20251001` or `claude-haiku-4-5-2025-10-01` vs `claude-haiku-4-5`) all resolve to the same model. Exact `provider/id` matches still win, and a qualified provider query never silently switches providers — it only matches within the named provider. Ambiguous bare ids that exist under multiple providers still require a provider prefix or the current session's provider to disambiguate.
172
+
173
+ To keep subagents inside a budget or compliance profile, enforce a model scope. Put `subagents.modelScope` in user or project settings (project overrides user):
174
+
175
+ ```json
176
+ {
177
+ "subagents": {
178
+ "modelScope": {
179
+ "enforce": true,
180
+ "allow": ["anthropic/*", "openai/gpt-5-*"]
181
+ }
182
+ }
183
+ }
184
+ ```
185
+
186
+ `allow` is a list of glob patterns matched against the resolved `provider/id` (only `*` is special, case-insensitive). A resolved model that matches none of the patterns is rejected. Models you pass explicitly — the tool-call `model`, `--model`, or a clarify pick — error and abort the run. Models that come from agent frontmatter, `subagents.defaultModel`, or the inherited parent session model only warn, so existing configurations keep working while you tighten the scope. `enforce: true` requires a non-empty `allow` list; otherwise the config is rejected at load time.
187
+
171
188
  ## Where running subagents show up
172
189
 
173
190
  Foreground runs stream progress in the conversation while they run.
174
191
 
175
- Background runs keep working after control returns to you. Inspect active runs with `subagent({ action: "status" })`, or a specific run with `subagent({ action: "status", id: "..." })`.
192
+ Background runs keep working after control returns to you. Inspect active runs with `subagent({ action: "status" })`, or a specific run with `subagent({ action: "status", id: "..." })`. For a read-only fleet view across active foreground and background work, use `/subagents-fleet` or `subagent({ action: "status", view: "fleet" })`. To inspect what a background child is saying without hunting through artifact directories, tail its live transcript with `subagent({ action: "status", id: "...", view: "transcript" })`; add `index` for a specific child in a parallel or chain run.
176
193
 
177
194
  They also show a compact async widget and send completion notifications. Parallel background runs show per-agent progress instead of fake chain steps. Chains with parallel groups keep their grouped shape in progress and results, so failed or paused agents stay visible next to completed ones. When a child is explicitly allowed to fan out with `tools: subagent`, its nested runs appear under that parent child in the main status tree instead of being hidden inside the child process.
178
195
 
@@ -186,6 +203,26 @@ Async runs also write machine-readable lifecycle artifacts for observability and
186
203
 
187
204
  The stable v1 status/result fields are `lifecycleArtifactVersion`, `runId`/`id`, `sessionId`, `mode`, `state`, `startedAt`, `lastUpdate`, `endedAt`, `durationMs`, `cwd`, `asyncDir`, `sessionFile`, `outputFile`, `workflowGraph`, `steps`, `results`, `totalTokens`, `totalCost`, `model`/`attemptedModels`/`modelAttempts`, `toolCount`, `turnCount`, and nested `children` when a child is allowed to launch subagents. `events.jsonl` records lifecycle transitions such as `subagent.run.started`, `subagent.step.started`, `subagent.step.completed`/`failed`/`paused`, control attention events, nested interrupt failures, and `subagent.run.completed`; run boundary events include the lifecycle artifact version. Consumers should read these JSON files instead of scraping terminal output; unknown fields and event types should be ignored for forward compatibility.
188
205
 
206
+ Other Pi extensions can use the versioned in-process event-bus RPC instead of scraping slash output or calling internal modules. Listen for `subagents:rpc:v1:ready`, send requests on `subagents:rpc:v1:request`, and read replies from `subagents:rpc:v1:reply:<requestId>`.
207
+
208
+ ```typescript
209
+ const requestId = crypto.randomUUID();
210
+ pi.events.on(`subagents:rpc:v1:reply:${requestId}`, (reply) => {
211
+ // { version: 1, requestId, success: true, data } or
212
+ // { version: 1, requestId, success: false, error: { code, message } }
213
+ });
214
+ pi.events.emit("subagents:rpc:v1:request", {
215
+ version: 1,
216
+ requestId,
217
+ method: "spawn",
218
+ params: { agent: "reviewer", task: "Review the current diff", context: "fresh" }
219
+ });
220
+ ```
221
+
222
+ The v1 methods are `ping`, `status`, `spawn`, `interrupt`, and `stop`. `status` and `interrupt` reuse the normal control actions. `spawn` is async-only: omit `async` or set `async: true`, omit `clarify` or set `clarify: false`, and do not pass management `action` values. It goes through the same executor as the `subagent` tool, so agent discovery, validation, session attribution, spawn limits, child-safety depth, artifacts, and async status all behave the same. `stop` targets running async runs through the existing timeout control channel.
223
+
224
+ `pi.events` is in-process only. It does not reach separate Pi processes or child subagents; use the file lifecycle artifacts or `pi-intercom` for cross-process coordination.
225
+
189
226
  If something feels misconfigured, run:
190
227
 
191
228
  ```text
@@ -228,17 +265,9 @@ The package includes reusable prompt templates for common workflows. You do not
228
265
 
229
266
  Add `autofix` to `/parallel-review` or `/parallel-cleanup` to apply only the synthesized fixes worth doing now after reviewers return.
230
267
 
231
- ## Optional pi-intercom companion
232
-
233
- `pi-subagents` works without `pi-intercom`. Install `pi-intercom` only if you want child agents to talk back to the parent Pi session while they are running.
268
+ ## Native supervisor coordination
234
269
 
235
- ```bash
236
- pi install npm:pi-intercom
237
- ```
238
-
239
- When `pi-intercom` is not active, `pi-subagents` may recommend it at session start, in `subagent({ action: "list" })`, and in `/subagents-doctor`. The recommendation is visible to the assistant so it can offer to run the install command or hide the recommendation after you approve that action.
240
-
241
- Most users do not call `intercom` directly. After `pi-intercom` is installed, `pi-subagents` can automatically give child agents a private coordination channel back to the parent session. The bridge recognizes the normal `pi install npm:pi-intercom` package install as well as legacy local extension checkouts.
270
+ Child agents can talk back to the parent Pi session without installing `pi-intercom`. `pi-subagents` now provides the child-facing `contact_supervisor` tool and the parent-facing `subagent_supervisor({ action: "reply" })` path natively. If no external `pi-intercom` tool owns the `intercom` name, the native channel also exposes `intercom` as a compatibility fallback.
242
271
 
243
272
  Use it for work where the child might need a decision instead of guessing:
244
273
 
@@ -252,11 +281,11 @@ Ask oracle to review this plan. If it sees a decision I need to make, have it as
252
281
 
253
282
  The child can use one dedicated coordination tool:
254
283
 
255
- - `contact_supervisor`: the child contacts the parent/supervisor session that delegated the task. Use `reason: "need_decision"` for blocking decisions or clarification, and `reason: "progress_update"` for short non-blocking updates when a discovery changes the plan. Do not ask for clarification when the only conflict is review-only/no-edit versus progress-writing or artifact-writing instructions; no-edit wins.
284
+ - `contact_supervisor`: the child contacts the parent/supervisor session that delegated the task. Use `reason: "need_decision"` for blocking decisions or clarification, `reason: "interview_request"` for structured input, and `reason: "progress_update"` for short non-blocking updates when a discovery changes the plan. Do not ask for clarification when the only conflict is review-only/no-edit versus progress-writing or artifact-writing instructions; no-edit wins.
256
285
 
257
- Child-side routine completion handoffs are still not expected. With the intercom bridge active, parent-side `pi-subagents` sends grouped completion results through `pi-intercom`: one grouped message per foreground parent `subagent` run and one per completed async result file. Acknowledged foreground delivery returns a compact receipt with artifact/session paths; if unacknowledged, the normal full output is preserved. Grouped messages include child intercom targets, full child summaries, and compact nested child summaries under the parent child that launched them.
286
+ The parent replies with `subagent_supervisor({ action: "reply", replyTo, message })` or checks pending requests with `subagent_supervisor({ action: "pending" })`. Supervisor messages are scoped to the exact Pi session id that spawned the child. A second Pi session in the same repository does not receive those requests.
258
287
 
259
- If a child appears stalled, needs-attention notices can show up in the parent session with useful next actions, such as checking `subagent({ action: "status" })`, interrupting the run, or nudging the child.
288
+ Child-side routine completion handoffs are still not expected. If a child appears stalled, needs-attention notices can show up in the parent session with useful next actions, such as checking `subagent({ action: "status" })`, interrupting the run, or nudging the child.
260
289
 
261
290
  If messages do not show up, run:
262
291
 
@@ -504,13 +533,15 @@ You can combine them in either order:
504
533
  /run reviewer "review this diff" --bg --fork
505
534
  ```
506
535
 
507
- Background runs are detached. If the parent agent has other independent work, it should keep working. If it has nothing useful to do until the background result arrives, it should end the turn instead of running sleep or status-polling loops. Pi will deliver the completion when the run finishes.
536
+ Background runs are detached. If the parent agent has other independent work, it should keep working. When it has nothing useful to do until a background result arrives, it should call the `wait` tool instead of running sleep or status-polling loops. `wait()` returns when the next active run finishes or needs attention and keeps the turn alive for normal notification delivery; use `wait({ all: true })` to drain every active run, `wait({ id })` for one run, and `wait({ timeoutMs })` to cap the block.
537
+
538
+ `wait` is what lets a background-launching skill keep moving in a single turn, including non-interactive `pi -p` invocations where there is no subsequent turn to receive a completion notification. Ending the turn to wait for a completion only works in an interactive session where the user will prompt the agent again; in a run-to-completion skill or a non-interactive run, use `wait` so the still-running children are not abandoned.
508
539
 
509
540
  The `oracle` and `worker` builtins are designed for an explicit decision loop. A typical pattern is to ask `oracle` for diagnosis and a recommended execution prompt, then only run `worker` after the main agent approves that direction.
510
541
 
511
542
  ## Clarify and launch UI
512
543
 
513
- Chains open a clarify UI by default so you can preview and edit the workflow before it runs. Single and parallel tool calls can opt into the same flow with `clarify: true`; slash commands launch directly.
544
+ Tool calls launch directly by default. Set `clarify: true` on single, parallel, or chain runs when you want to preview and edit the workflow before it runs; slash commands launch directly.
514
545
 
515
546
  Common clarify keys:
516
547
 
@@ -575,7 +606,7 @@ Supported override fields are `model`, `fallbackModels`, `thinking`, `systemProm
575
606
 
576
607
  Set `subagents.defaultModel` to give all subagents without an explicit model their own default model, separate from the parent session model. Per-agent model overrides and agent frontmatter still win.
577
608
 
578
- Set `disabled: true` to hide a builtin from runtime discovery and agent-facing `subagent({ action: "list" })` output. For bulk control, set `subagents.disableBuiltins: true` in settings.
609
+ Set `disabled: true` to hide a builtin from runtime discovery and agent-facing `subagent({ action: "list" })` output. For bulk control, set `subagents.disableBuiltins: true` in settings. You can also toggle a single agent without editing settings by hand: `subagent({ action: "disable", agent: "reviewer" })` writes that override, and `subagent({ action: "enable", agent: "reviewer" })` removes it.
579
610
 
580
611
  Set `subagents.disableThinking: true` to clear bundled builtin thinking defaults globally for providers that do not support `:low`, `:medium`, `:high`, or similar model suffixes. A higher-precedence per-agent `thinking` override can opt one builtin back in.
581
612
 
@@ -646,7 +677,22 @@ Important fields:
646
677
  | `defaultProgress` | Maintain `progress.md`. |
647
678
  | `completionGuard` | Set `false` only for non-implementation agents that may mention implementation words while using mutation-capable tools such as `bash`. |
648
679
  | `interactive` | Parsed for compatibility but not enforced in v1. |
649
- | `maxSubagentDepth` | Tightens nested delegation for this agents children. |
680
+ | `maxSubagentDepth` | Tightens nested delegation for this agent's children. |
681
+ | `memory` | Opt-in role-specific persistent memory. `memory: { scope: "project" \| "user", path: "<name>" }` injects the first lines of a `MEMORY.md` from a dedicated `agent-memory/` directory into the child system prompt. Agents with write tools (`edit`/`write`/`bash`) get a read-write block; read-only agents get a read-only fallback. Project scope resolves under `<project>/.pi/agent-memory/`, user scope under `~/.pi/agent/agent-memory/`. Paths are validated against traversal and symlink escape. |
682
+
683
+ ### Per-agent persistent memory
684
+
685
+ A recurring custom agent can opt into a durable, role-specific memory scope with the `memory` frontmatter field. This is independent of Pi's own parent/session/project memory system and writes nothing to it; memory lives under a dedicated `agent-memory/` namespace so the two never collide.
686
+
687
+ ```yaml
688
+ memory:
689
+ scope: project
690
+ path: security-reviewer
691
+ ```
692
+
693
+ On each run, the first 200 lines of `MEMORY.md` in the resolved memory directory are injected into the child system prompt so the agent can recall accumulated role notes such as threat-model entries, release gotchas, or verified commands. Agents that have write tools (`edit`, `write`, or `bash`, or no `tools` allowlist at all) are told they may append concise dated entries to the file. Agents without write tools receive a read-only memory block and are not instructed to edit it, so a read-only reviewer can still recall prior notes without being granted write capability. The memory directory is never created eagerly; the agent's own `write` tool creates it (and `MEMORY.md`) on the first persist. Memory paths are validated against `.`/`..` traversal and symlink escape, and an unsafe or unresolvable scope is silently skipped rather than breaking the run.
694
+
695
+ Project-scoped memory resolves under `<project>/.pi/agent-memory/<path>` and travels with the repo. User-scoped memory resolves under `~/.pi/agent/agent-memory/<path>` and is shared across projects for that agent.
650
696
 
651
697
  ### Tool and extension selection
652
698
 
@@ -838,7 +884,7 @@ What the bundled skill covers:
838
884
  - **Prompt workflow recipes**: how to apply the packaged techniques directly with `subagent(...)` when the user describes the workflow in natural language instead of invoking a slash command. This includes parallel review, review-loop, parallel research, parallel context-build, parallel handoff-plan, gather-context-and-clarify, and parallel cleanup
839
885
  - **Role-agent prompting guidance**: compact contract prompts instead of long scripts, what to include in role-specific meta prompts, and retrieval budgets for researchers
840
886
  - **Safety boundaries**: child agents must not run subagents unless their resolved builtin tools explicitly include `subagent`, must not invent intercom targets, and must escalate unapproved decisions
841
- - **Intercom conventions**: when to ask vs send, and how parent-side result delivery works with `pi-intercom`
887
+ - **Intercom conventions**: when to ask vs send, and how parent-side supervisor/result delivery works through the native channel
842
888
  - **Control and diagnostics**: attention signals, soft interrupts, status, and the `doctor` action
843
889
 
844
890
  If you are writing an agent that orchestrates subagents, the bundled skill helps it behave correctly without guessing the patterns. If you are a human user, you do not need to read it directly; the README and prompt shortcuts encode the same workflows in user-facing form.
@@ -974,33 +1020,45 @@ Agent definitions are not loaded into context by default. Management actions let
974
1020
  { action: "update", chainName: "review-pipeline", config: { steps: [...] } }
975
1021
  { action: "delete", agent: "scout" }
976
1022
  { action: "delete", chainName: "review-pipeline" }
1023
+
1024
+ { action: "eject", agent: "reviewer" }
1025
+ { action: "eject", agent: "reviewer", agentScope: "project" }
1026
+ { action: "disable", agent: "reviewer" }
1027
+ { action: "enable", agent: "reviewer", agentScope: "project" }
1028
+ { action: "reset", agent: "reviewer" }
977
1029
  ```
978
1030
 
979
1031
  `create` uses `config.scope`, not `agentScope`. `config.name` is the local frontmatter name; optional `config.package` registers the runtime name as `{package}.{name}` and is saved as separate `name` and `package` frontmatter. `update` and `delete` use the runtime name and `agentScope` only when the same runtime name exists in multiple scopes. To clear optional string fields, including `package`, set them to `false` or `""`.
980
1032
 
1033
+ `eject` copies a bundled builtin or package agent verbatim into the user or project agent dir (default `user`) as an editable custom file that shadows the original, so you can customize a builtin without hunting package files. `disable` writes a reversible `agentOverrides.<name>.disabled: true` entry to the user or project settings file (default `user`); the agent stays on disk but is hidden from runtime discovery and `list`. `enable` removes that `disabled` field while preserving any other override fields on the same entry. `reset` deletes the scope's custom agent file and/or settings override entry, restoring the bundled default; it refuses if no bundled default exists (use `delete` for purely custom agents). All four accept `agentScope: "user" | "project"` and operate in one scope at a time; project overrides still win over user ones, so a project-scope disable survives a user-scope `enable` until you target the project scope.
1034
+
981
1035
  ### Parameter reference
982
1036
 
983
1037
  | Param | Type | Default | Description |
984
1038
  |-------|------|---------|-------------|
985
1039
  | `agent` | string | - | Agent name for single mode, or target for management actions. |
986
1040
  | `task` | string | - | Task string for single mode. |
987
- | `action` | string | - | `list`, `get`, `create`, `update`, `delete`, `status`, `interrupt`, `resume`, `append-step`, or `doctor`. |
1041
+ | `action` | string | - | `list`, `get`, `create`, `update`, `delete`, `status`, `interrupt`, `resume`, `steer`, `append-step`, or `doctor`. |
988
1042
  | `chainName` | string | - | Chain name for management actions. |
989
1043
  | `config` | object/string | - | Agent or chain config for create/update. |
990
1044
  | `output` | `string \| false` | agent default | Override single-agent output file. |
991
1045
  | `outputMode` | `"inline" \| "file-only"` | `inline` | Return saved output inline or as a concise saved-file reference. `file-only` requires an `output` path. |
992
1046
  | `skill` | `string \| string[] \| false` | agent default | Override skills or disable all. |
993
1047
  | `model` | string | agent default | Override model. |
994
- | `tasks` | array | - | Top-level parallel tasks. Supports `agent`, `task`, `cwd`, `count`, `output`, `outputMode`, `reads`, `progress`, `skill`, `model`, and `acceptance`. |
1048
+ | `tasks` | array | - | Top-level parallel tasks. Supports `agent`, `task`, `cwd`, `count`, `output`, `outputMode`, `reads`, `progress`, `skill`, `model`, `toolBudget`, and `acceptance`. |
995
1049
  | `concurrency` | number | config or `4` | Top-level parallel concurrency. |
996
1050
  | `worktree` | boolean | false | Create isolated git worktrees for parallel tasks. |
997
1051
  | `chain` | array | - | Sequential, static parallel, and dynamic fanout chain steps. Steps and chain parallel tasks support `phase`, `label`, `as`, `outputSchema`, and `acceptance` in addition to the usual execution fields. Dynamic fanout uses `expand`, one child `parallel` template, and `collect`. With `action: "append-step"`, pass exactly one step to append to a running async chain. |
998
1052
  | `context` | `fresh \| fork` | per-agent default or `fresh` | Explicit `fresh` or `fork` overrides every child. When omitted, each agent uses its own `defaultContext`; `fork` creates real branched sessions from the parent leaf. Packaged `planner`, `worker`, and `oracle` default to `fork`. |
999
1053
  | `chainDir` | string | temp chain dir | Persistent directory for chain artifacts. |
1000
- | `clarify` | boolean | true for chains | Show TUI preview/edit flow. |
1054
+ | `view` | `fleet \| transcript` | - | Optional `status` view for the active fleet surface or transcript tail inspection. |
1055
+ | `lines` | number | `80` | Maximum transcript lines for `action: "status", view: "transcript"`; capped at 500. |
1056
+ | `clarify` | boolean | false | Show TUI preview/edit flow. Explicit `clarify: true` keeps the run foreground for the clarify UI. |
1001
1057
  | `agentScope` | `user \| project \| both` | `both` | Agent discovery scope. Project wins on collisions. |
1002
1058
  | `async` | boolean | false | Background execution. For chains, `clarify: true` explicitly keeps the run foreground for the clarify UI. |
1003
1059
  | `timeoutMs` / `maxRuntimeMs` | number | none | Optional run-level max runtime in milliseconds for foreground and async/background runs. |
1060
+ | `turnBudget` | object | none | Optional assistant-turn budget `{ maxTurns, graceTurns }`. At `maxTurns` the child is warned to wrap up; after `graceTurns` (default 1) more assistant turns the run is aborted and partial output is returned. |
1061
+ | `toolBudget` | object | none | Optional child tool-call budget `{ soft?, hard, block? }`. At `soft` the child is nudged to finalize. After `hard`, configured tools are blocked; `block` defaults to `read`, `grep`, `find`, and `ls`, or use `"*"` to block every tool call. Final assistant text is never blocked. |
1004
1062
  | `cwd` | string | runtime cwd | Override working directory. |
1005
1063
  | `maxOutput` | object | 200KB, 5000 lines | Final output truncation limits. |
1006
1064
  | `artifacts` | boolean | true | Write debug artifacts. |
@@ -1013,27 +1071,33 @@ Agent definitions are not loaded into context by default. Management actions let
1013
1071
 
1014
1072
  Use `outputMode: "file-only"` when a saved output may be large and the parent only needs a pointer. The returned text is a compact reference like `Output saved to: /abs/report.md (48.2 KB, 2847 lines). Read this file if needed.` Failed runs and save errors still return normal inline output for debugging. In chains, later `{previous}` steps receive the same compact reference when the prior step used file-only mode.
1015
1073
 
1016
- Sequential and parallel chain tasks accept `agent`, `task`, `phase`, `label`, `as`, `outputSchema`, `cwd`, `output`, `outputMode`, `reads`, `progress`, `skill`, and `model`. Parallel tasks also accept `count`. Parallel step groups accept `parallel`, `concurrency`, `failFast`, and `worktree`. If `outputSchema` is present, the child must call `structured_output` with schema-valid JSON; prose-only completion or invalid JSON fails the step. Validated structured values are preserved on the step result, and `as` also exposes a compact text representation through `{outputs.name}`.
1074
+ Sequential and parallel chain tasks accept `agent`, `task`, `phase`, `label`, `as`, `outputSchema`, `cwd`, `output`, `outputMode`, `reads`, `progress`, `skill`, `model`, and `toolBudget`. Parallel tasks also accept `count`. Parallel step groups accept `parallel`, `concurrency`, `failFast`, and `worktree`. If `outputSchema` is present, the child must call `structured_output` with schema-valid JSON; prose-only completion or invalid JSON fails the step. Validated structured values are preserved on the step result, and `as` also exposes a compact text representation through `{outputs.name}`.
1017
1075
 
1018
1076
  Status and control actions:
1019
1077
 
1020
1078
  ```ts
1021
1079
  subagent({ action: "status" })
1080
+ subagent({ action: "status", view: "fleet" })
1022
1081
  subagent({ action: "status", id: "<run-id>" })
1082
+ subagent({ action: "status", id: "<run-id>", view: "transcript", index: 0, lines: 80 })
1023
1083
  subagent({ action: "status", id: "<nested-run-id>" })
1024
1084
  subagent({ action: "interrupt", id: "<run-id>" })
1025
1085
  subagent({ action: "interrupt", id: "<nested-run-id>" })
1026
1086
  subagent({ action: "resume", id: "<run-id>", message: "follow-up question" })
1027
1087
  subagent({ action: "resume", id: "<run-id>", index: 1, message: "follow-up for child 2" })
1028
1088
  subagent({ action: "resume", id: "<nested-run-id>", message: "follow-up for a nested child" })
1089
+ subagent({ action: "steer", id: "<run-id>", message: "guidance for the running child" })
1090
+ subagent({ action: "steer", id: "<run-id>", index: 1, message: "guidance for child 2" })
1029
1091
  subagent({ action: "append-step", id: "<run-id>", chain: [{ agent: "worker", task: "Continue from {previous}" }] })
1030
1092
  subagent({ action: "doctor" })
1031
1093
  ```
1032
1094
 
1033
- `status` resolves exact foreground ids, top-level async ids, and nested run ids before falling back to prefix matching. Nested status shows the root/parent path, nested children, session/artifact paths when known, and nested control commands. Inside child-safe fanout mode, bare `status` requires an id when no local foreground run is active, so children cannot enumerate unrelated top-level async runs. Bare `interrupt` still targets only the visible top-level run; interrupting a nested run requires its explicit nested id.
1095
+ `status` resolves exact foreground ids, top-level async ids, and nested run ids before falling back to prefix matching. `view: "fleet"` is an optional read-only active-run surface with transcript commands; it does not add steering or stop controls. `view: "transcript"` tails the selected run's live `output-<index>.log` or persisted session transcript, with `lines` capped at 500. Nested status shows the root/parent path, nested children, session/artifact paths when known, and nested control commands. Inside child-safe fanout mode, bare `status` requires an id when no local foreground run is active, so children cannot enumerate unrelated top-level async runs. Bare `interrupt` still targets only the visible top-level run; interrupting a nested run requires its explicit nested id.
1034
1096
 
1035
1097
  `resume` sends the follow-up directly when an async child is still reachable over intercom. After completion, it revives the child by starting a new async child from the stored child session file. Multi-child async runs and remembered foreground single, parallel, or chain runs can be revived by passing `index` to choose the child. Nested runs can be resumed by nested id when their live route or persisted session metadata is available. Revive starts a new child process from the old session context; it does not restart the same OS process, and it requires the chosen child to have a persisted `.jsonl` session file.
1036
1098
 
1099
+ `steer` queues non-terminal guidance for a running async Pi child, or for a pending indexed child that will start later in the same async run. It does not interrupt, pause, or revive a child. Delivery requires the spawned Pi session to support mid-run `sendUserMessage(..., { deliverAs: "steer" })`; unsupported runtimes keep the request visible in control artifacts but cannot receive it live. Use `index` for multi-child runs when you want to steer one child; without `index`, steering targets the currently running child or children.
1100
+
1037
1101
  `append-step` accepts exactly one sequential, static parallel, or dynamic fanout chain step for a top-level async chain whose status is still `running`. The step is persisted in the run directory and becomes eligible only after the chain's already-queued steps finish; completed, failed, paused, foreground, single, and top-level parallel runs reject appends.
1038
1102
 
1039
1103
  ## Worktree isolation
@@ -1072,6 +1136,16 @@ After a worktree parallel step completes, per-agent diff stats are appended to t
1072
1136
 
1073
1137
  `pi-subagents` reads optional JSON config from `~/.pi/agent/extensions/subagent/config.json`.
1074
1138
 
1139
+ ### `toolDescriptionMode`
1140
+
1141
+ ```json
1142
+ { "toolDescriptionMode": "compact" }
1143
+ ```
1144
+
1145
+ Controls the parent-facing `subagent` tool description registered at startup. `full` is the default. `compact` keeps the execution modes, async/wait guidance, child-safety boundary, management/action split, one-writer review guidance, and artifact/status essentials with less prompt bloat.
1146
+
1147
+ `custom` reads `subagent-tool-description.md` from the project config directory, then from `~/.pi/agent/subagent-tool-description.md`. Missing, empty, unreadable, or oversized custom files fall back to the full description. Custom templates may use `{{fullDescription}}`, `{{compactDescription}}`, `{{safetyGuidance}}`, `{{agentDir}}`, and `{{projectConfigDir}}`; the safety guidance is always present so custom prose cannot remove the runtime guardrails. Restart Pi after changing the mode or custom file.
1148
+
1075
1149
  ### `asyncByDefault`
1076
1150
 
1077
1151
  ```json
@@ -1104,6 +1178,14 @@ Caps simultaneously running subagent tasks within a single run across top-level
1104
1178
 
1105
1179
  Caps the total number of child subagent launches allowed during one parent session, including single runs, parallel task counts, static chain steps, and bounded dynamic fanout children. Set `PI_SUBAGENT_MAX_SPAWNS_PER_SESSION` to override the config for a process. The default is `40`; `0` blocks new subagent launches for that session.
1106
1180
 
1181
+ ### `scheduledRuns`
1182
+
1183
+ ```json
1184
+ { "scheduledRuns": { "enabled": true, "maxPending": 20, "maxLatenessMs": 300000 } }
1185
+ ```
1186
+
1187
+ Enables optional one-shot scheduled subagent runs. When enabled, `subagent({ action: "schedule", agent, task?, schedule: "+10m" | "2030-01-01T09:00:00Z", scheduleName? })` defers a subagent launch until a future time. Absolute ISO timestamps must include a timezone (`Z` or an offset such as `+05:30`). The scheduled run launches as a normal tracked async run with fresh context once it fires, and joins the existing async widget, status, `wait`, and completion-notification paths. `schedule-list`, `schedule-status`, and `schedule-cancel` manage pending jobs. Schedules are persisted per session and restored after a Pi restart; a job missed by more than `maxLatenessMs` while Pi is unavailable is marked `missed` instead of firing late. `maxPending` caps the number of pending or running scheduled jobs per session (default `20`). The feature is opt-in: leave `enabled` unset to keep scheduling out of the tool surface and prompt. Only schedule explicit delayed runs the user asked for.
1188
+
1107
1189
  ### `parallel`
1108
1190
 
1109
1191
  ```json
@@ -1167,32 +1249,10 @@ Fields:
1167
1249
  - `mode`: default `always`; use `fork-only` to inject only for forked runs, or `off` to disable the bridge.
1168
1250
  - `instructionFile`: optional Markdown template replacing the default bridge instructions. `{orchestratorTarget}` is interpolated. Relative paths resolve from `~/.pi/agent/extensions/subagent/`.
1169
1251
 
1170
- Bridge activation also requires `pi-intercom` to be installed and enabled through `pi install npm:pi-intercom` or a legacy local extension checkout, a targetable current session name or fallback alias, and `pi-intercom` in any explicit agent `extensions` allowlist.
1252
+ Bridge activation requires a targetable current parent session id, which `pi-subagents` passes to children automatically. It no longer depends on an external `pi-intercom` installation or per-agent extension allowlists.
1171
1253
 
1172
1254
  The default injected guidance tells children to use `contact_supervisor` with `reason: "need_decision"` when blocked or needing a decision, `reason: "progress_update"` only for meaningful blocked/progress updates, generic `intercom` as fallback plumbing, and avoid routine completion handoffs.
1173
1255
 
1174
- ### `companionSuggestions`
1175
-
1176
- ```json
1177
- {
1178
- "companionSuggestions": {
1179
- "enabled": true,
1180
- "packages": {
1181
- "pi-intercom": {
1182
- "surfaces": ["session_start", "list", "doctor"]
1183
- },
1184
- "pi-prompt-template-model": {
1185
- "surfaces": ["session_start", "list", "doctor"]
1186
- }
1187
- }
1188
- }
1189
- }
1190
- ```
1191
-
1192
- Controls recommendations for optional companion packages. `pi-intercom` enables live supervisor decisions, progress updates, and grouped result delivery. `pi-prompt-template-model` makes subagent workflows reusable as prompt templates with model/thinking/skill/subagent frontmatter.
1193
-
1194
- Use `/subagents-companions status` to inspect recommendation status. Use `/subagents-companions hide pi-intercom workspace` or `/subagents-companions hide pi-prompt-template-model user` to hide a recommendation. Use `/subagents-companions show <package>` to show a workspace recommendation again. Set `companionSuggestions` to `false` to disable all companion recommendations.
1195
-
1196
1256
  ### `worktreeBaseDir`
1197
1257
 
1198
1258
  ```json
@@ -1220,6 +1280,25 @@ stdin is a JSON object with `repoRoot`, `worktreePath`, `agentCwd`, `branch`, `i
1220
1280
 
1221
1281
  `syntheticPaths` must be relative to the worktree root. They are removed before diff capture so helper files do not pollute patches. Tracked files are never excluded; marking a tracked path as synthetic fails setup. Default timeout is `30000` ms.
1222
1282
 
1283
+ ### `completionBatch`
1284
+
1285
+ ```json
1286
+ {
1287
+ "completionBatch": {
1288
+ "enabled": true,
1289
+ "debounceMs": 150,
1290
+ "maxWaitMs": 1000,
1291
+ "stragglerDebounceMs": 75,
1292
+ "stragglerMaxWaitMs": 400,
1293
+ "stragglerWindowMs": 2000
1294
+ }
1295
+ }
1296
+ ```
1297
+
1298
+ Controls smart batching of async-completion notifications. When several background subagents finish within a short window, their successful completions are held briefly and delivered as a single grouped message instead of separate notifications. A hard `maxWaitMs` cap (measured from the first completion in a group) guarantees nothing is held indefinitely, and late-finishing siblings that arrive within `stragglerWindowMs` of a group emit join a shorter straggler group governed by `stragglerDebounceMs` and `stragglerMaxWaitMs`.
1299
+
1300
+ Failed and paused completions bypass batching and fire immediately, flushing any held successes first, so failure and needs-attention signals are never delayed. Set `enabled` to `false` to restore the original one-notification-per-completion behavior. Changes apply on the next session start.
1301
+
1223
1302
  ## Files, logs, and observability
1224
1303
 
1225
1304
  Each chain run creates a user-scoped temp directory like:
@@ -1241,7 +1320,7 @@ Metadata records timing, usage, exit code, final model, attempted models, and fa
1241
1320
 
1242
1321
  Session files are stored under a per-run session directory. With `context: "fork"`, each child starts with `--session <branched-session-file>` produced from the parent’s current leaf. That is a real session fork, not an injected summary.
1243
1322
 
1244
- Async completions notify only the originating session. The result watcher emits `subagent:async-complete`, and the extension consumes that event to render completion notifications.
1323
+ Async completions notify only the originating session. The result watcher emits `subagent:async-complete`, and the extension consumes that event to render completion notifications. Successful sibling completions are held briefly and delivered as a single grouped message when they finish within a short window (see `completionBatch`); failed and paused completions always fire immediately.
1245
1324
 
1246
1325
  Async runs write:
1247
1326
 
@@ -1253,7 +1332,7 @@ Async runs write:
1253
1332
  subagent-log-<id>.md
1254
1333
  ```
1255
1334
 
1256
- `status.json` powers the widget and `subagent({ action: "status" })` output. `events.jsonl` contains wrapper events plus child Pi JSON events annotated with run and step metadata. Nested fanout status is stored as compact sidecar event/registry metadata and merged into parent status views and result/intercom payloads; full recursive status snapshots are not embedded in parent result files. `output-<n>.log` is a live human-readable tail. Fallback information is persisted so background runs are debuggable after completion.
1335
+ `status.json` powers the widget and `subagent({ action: "status" })` output. `events.jsonl` contains wrapper events plus child Pi JSON events annotated with run and step metadata, including `subagent.steer.requested` when live async steering is queued. Nested fanout status is stored as compact sidecar event/registry metadata and merged into parent status views and result/intercom payloads; full recursive status snapshots are not embedded in parent result files. `output-<n>.log` is a live human-readable tail. Fallback information is persisted so background runs are debuggable after completion.
1257
1336
 
1258
1337
  ## Acceptance Gates
1259
1338
 
@@ -1289,7 +1368,7 @@ For `attested` or stricter levels, the child prompt includes a standardized acce
1289
1368
 
1290
1369
  Foreground runs show compact live progress for single, chain, and parallel modes: current tool, recent output, token counts, aggregate cost, duration, activity freshness, current-tool duration, and chain graph metadata when available.
1291
1370
 
1292
- Press `Ctrl+O` to expand the full streaming view with complete output per step.
1371
+ Press Pi's configured expand key (`Ctrl+O` by default) to expand the full streaming view with complete output per step.
1293
1372
 
1294
1373
  Sequential chains show a flow line like `done scout → running planner`. Chains with parallel steps show per-step cards instead. Chain status uses `label` and `phase` metadata when present, while falling back to agent names for older chains.
1295
1374
 
@@ -1335,13 +1414,13 @@ Intercom delivery events:
1335
1414
  - `subagent:control-intercom`
1336
1415
  - `subagent:result-intercom`
1337
1416
 
1338
- The result watcher emits `subagent:async-complete`; `src/extension/index.ts` registers the notification handler that consumes it. Control/attention events are surfaced as visible parent notices and persisted for async runs. With `pi-intercom`, needs-attention notices and grouped parent-side subagent result deliveries can reach the orchestrator over intercom.
1417
+ The result watcher emits `subagent:async-complete`; `src/extension/index.ts` registers the notification handler that consumes it. Control/attention events are surfaced as visible parent notices and persisted for async runs. Native supervisor requests are delivered only to the exact parent session that spawned the child.
1339
1418
 
1340
1419
  ## Prompt-template integration
1341
1420
 
1342
- `pi-subagents` works standalone through natural language, the `subagent` tool, slash commands, and the packaged prompt shortcuts listed near the top of this README. If you use [pi-prompt-template-model](https://github.com/nicobailon/pi-prompt-template-model), you can also wrap subagent delegation in your own reusable prompt templates.
1421
+ `pi-subagents` works standalone through natural language, the `subagent` tool, slash commands, and the packaged prompt shortcuts listed near the top of this README. It also includes a native prompt-workflow adapter for reusable subagent prompt templates, so you do not need `pi-prompt-template-model` for the common subagent workflow path.
1343
1422
 
1344
- Example:
1423
+ Create a prompt in `.pi/prompts/` or `~/.pi/agent/prompts/`:
1345
1424
 
1346
1425
  ```md
1347
1426
  ---
@@ -1353,11 +1432,21 @@ cwd: /tmp/screenshots
1353
1432
  Use url in the prompt to take screenshot: $@
1354
1433
  ```
1355
1434
 
1356
- Then `/take-screenshot https://example.com` switches to Sonnet, delegates to `browser-screenshoter` with `/tmp/screenshots` as cwd, and restores your model when done. Runtime overrides like `--cwd=<path>` and `--subagent=<name>` work too.
1435
+ Then run it through the native adapter:
1436
+
1437
+ ```text
1438
+ /prompt-workflow take-screenshot https://example.com
1439
+ ```
1357
1440
 
1358
- For more reusable workflows on top of subagents, including `/chain-prompts` and compare-style prompts such as `/best-of-n`, install `pi-prompt-template-model` separately and copy the examples you want into `~/.pi/agent/prompts/`.
1441
+ The adapter delegates to the named subagent, applies `model`, `skill`, `cwd`, `worktree`, and fork/fresh context metadata, and supports runtime overrides such as `--subagent reviewer`, `--fork`, `--fresh`, `--worktree`, and `--bg`.
1442
+
1443
+ For prompt-template chains, use:
1444
+
1445
+ ```text
1446
+ /chain-prompts analyze -> fix -- user arguments here
1447
+ ```
1359
1448
 
1360
- When `pi-prompt-template-model` is not active, `pi-subagents` may recommend it at session start, in `subagent({ action: "list" })`, and in `/subagents-doctor`. The recommendation is only a prompt; package installation still requires an explicit user-approved command.
1449
+ Each named prompt becomes a native `subagent` chain step. This is intentionally scoped to subagent workflows; compare-style prompt features such as `/best-of-n` are not part of the built-in adapter.
1361
1450
 
1362
1451
  ## Runtime files
1363
1452
 
@@ -1377,4 +1466,4 @@ The main runtime files are:
1377
1466
  | `src/runs/shared/worktree.ts` | Git worktree isolation. |
1378
1467
  | `src/intercom/intercom-bridge.ts` | Runtime intercom bridge instructions and diagnostics. |
1379
1468
  | `src/extension/schemas.ts` / `src/shared/types.ts` | Tool schemas, shared types, and event constants. |
1380
- | `test/unit/` / `test/integration/` | Unit and loader-based integration tests. |
1469
+ | `test/unit/` / `test/integration/` / `test/e2e/` | Unit, loader-based integration, and real-session E2E tests. |
package/install.mjs CHANGED
@@ -85,8 +85,9 @@ if (fs.existsSync(EXTENSION_DIR)) {
85
85
  }
86
86
 
87
87
  console.log(`
88
- The extension is now available in pi. Tool added:
88
+ The extension is now available in pi. Tools added:
89
89
  • subagent - Delegate tasks to agents and inspect run status
90
+ • wait - Block until background subagent runs finish (delivers their results)
90
91
 
91
92
  Documentation: ${EXTENSION_DIR}/README.md
92
93
  `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-subagents",
3
- "version": "0.32.0",
3
+ "version": "0.33.1",
4
4
  "description": "Pi extension for delegating tasks to subagents with chains, parallel execution, and TUI clarification",
5
5
  "author": "Nico Bailon",
6
6
  "license": "MIT",
@@ -38,7 +38,8 @@
38
38
  "test": "npm run test:unit",
39
39
  "test:unit": "node --experimental-strip-types --test test/unit/*.test.ts",
40
40
  "test:integration": "node --experimental-transform-types --import ./test/support/register-loader.mjs --test test/integration/*.test.ts",
41
- "test:all": "npm run test:unit && npm run test:integration"
41
+ "test:e2e": "node --experimental-transform-types --import ./test/support/register-loader.mjs --test test/e2e/*.test.ts",
42
+ "test:all": "npm run test:unit && npm run test:integration && npm run test:e2e"
42
43
  },
43
44
  "pi": {
44
45
  "extensions": [