pi-subagents 0.81.0 → 0.82.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 (152) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +1 -1
  3. package/bundle/agents.js +3 -3
  4. package/bundle/child-tool-plan.js +2 -2
  5. package/bundle/{chunk-L5ZHE4L4.js → chunk-3JCDWF4V.js} +4 -4
  6. package/bundle/{chunk-LSRUTHT7.js → chunk-43SCHIMD.js} +1 -1
  7. package/bundle/{chunk-VJHOELQP.js → chunk-46XKCPJR.js} +193 -81
  8. package/bundle/{chunk-G5DKFLLI.js → chunk-4SDU2BZX.js} +15 -10
  9. package/bundle/{chunk-2ZSNH26H.js → chunk-4Y2ROR7L.js} +7 -7
  10. package/bundle/{chunk-V2JWDB5U.js → chunk-52UBALJL.js} +2 -2
  11. package/bundle/{chunk-3DC5KBVP.js → chunk-5TYMSZX3.js} +1 -1
  12. package/bundle/{chunk-NNLASTQE.js → chunk-6XJB7PIX.js} +20 -6
  13. package/bundle/{chunk-ZBC44JJ3.js → chunk-CIZQXJ5Q.js} +22 -9
  14. package/bundle/{chunk-KSWQVGDW.js → chunk-FXUXCX2K.js} +225 -18
  15. package/bundle/{chunk-563BHAZ5.js → chunk-G4GZD3OJ.js} +35 -26
  16. package/bundle/{chunk-ARRKBB2B.js → chunk-GJECHSAR.js} +2 -2
  17. package/bundle/{chunk-V3BIUPLU.js → chunk-IVAE5Z6Q.js} +256 -52
  18. package/bundle/{chunk-V6MR5TOQ.js → chunk-JYUKW2SY.js} +25 -19
  19. package/bundle/{chunk-BJN5LUQY.js → chunk-OYF6AFDY.js} +1 -1
  20. package/bundle/{chunk-CEKS3TFO.js → chunk-PBK2I7WY.js} +6 -6
  21. package/bundle/{chunk-TUWLXTAM.js → chunk-PDZWJCHD.js} +681 -320
  22. package/bundle/{chunk-EYNJ6VL6.js → chunk-PLCCBLPY.js} +2 -2
  23. package/bundle/{chunk-XMFLCKMQ.js → chunk-QE4AGIMG.js} +339 -132
  24. package/bundle/{chunk-74RT5YQE.js → chunk-RMQFMMAT.js} +123 -33
  25. package/bundle/{chunk-WSBNENFS.js → chunk-UCPP4GNU.js} +14 -4
  26. package/bundle/{chunk-2XYWN7QJ.js → chunk-UTT254JE.js} +2 -2
  27. package/bundle/{chunk-BPS2AGBZ.js → chunk-VSUSLDNW.js} +93 -52
  28. package/bundle/{chunk-ZP3HODFH.js → chunk-XSWOTIA3.js} +1 -1
  29. package/bundle/{chunk-3IF2PGW7.js → chunk-YKEWIB4M.js} +1 -1
  30. package/bundle/{chunk-26C3WLYQ.js → chunk-ZIV4J4HG.js} +498 -274
  31. package/bundle/control-channel.js +2 -2
  32. package/bundle/index.js +1 -1
  33. package/bundle/intercom-bridge.js +2 -2
  34. package/bundle/preflight.js +8 -8
  35. package/bundle/project-panes.js +3 -3
  36. package/docs/agents.md +37 -7
  37. package/docs/configuration.md +9 -1
  38. package/docs/tool-reference.md +3 -1
  39. package/docs/workflows.md +16 -0
  40. package/package.json +2 -2
  41. package/skills/council-mode/SKILL.md +1 -4
  42. package/skills/pi-subagents/SKILL.md +130 -107
  43. package/skills/pi-subagents/references/orchestration.md +124 -0
  44. package/skills/pi-subagents/references/prompting-and-roles.md +96 -295
  45. package/src/agents/agent-management.js +3 -3
  46. package/src/agents/agent-memory.js +3 -1
  47. package/src/agents/agents.js +6 -6
  48. package/src/agents/frontmatter.d.ts +2 -0
  49. package/src/agents/frontmatter.js +15 -1
  50. package/src/agents/skills.js +2 -1
  51. package/src/extension/config.js +3 -0
  52. package/src/extension/herdr-pi-bridge.js +17 -10
  53. package/src/extension/index.js +82 -2
  54. package/src/extension/reply-workflow-script.js +5 -2
  55. package/src/extension/schemas.js +3 -3
  56. package/src/extension/subagent-guide.js +1 -2
  57. package/src/intercom/native-supervisor-channel.js +20 -0
  58. package/src/missions/lifecycle.js +7 -1
  59. package/src/runs/background/active-async-capacity.d.ts +1 -0
  60. package/src/runs/background/active-async-capacity.js +9 -3
  61. package/src/runs/background/async-execution.js +20 -10
  62. package/src/runs/background/async-job-tracker.d.ts +6 -1
  63. package/src/runs/background/async-job-tracker.js +9 -4
  64. package/src/runs/background/async-status.d.ts +4 -0
  65. package/src/runs/background/async-status.js +22 -3
  66. package/src/runs/background/await-async-run.js +3 -7
  67. package/src/runs/background/boot-id.d.ts +12 -0
  68. package/src/runs/background/boot-id.js +47 -0
  69. package/src/runs/background/interrupted-elsewhere.d.ts +22 -0
  70. package/src/runs/background/interrupted-elsewhere.js +68 -0
  71. package/src/runs/background/notify.d.ts +2 -0
  72. package/src/runs/background/notify.js +13 -0
  73. package/src/runs/background/result-delivery-ownership.d.ts +6 -0
  74. package/src/runs/background/result-delivery-ownership.js +19 -1
  75. package/src/runs/background/result-watcher.d.ts +3 -1
  76. package/src/runs/background/result-watcher.js +24 -8
  77. package/src/runs/background/run-child-session.d.ts +1 -6
  78. package/src/runs/background/run-child-session.js +1 -1
  79. package/src/runs/background/run-status.js +2 -1
  80. package/src/runs/background/stale-run-reconciler.d.ts +25 -0
  81. package/src/runs/background/stale-run-reconciler.js +52 -13
  82. package/src/runs/background/subagent-runner-bootstrap.js +3 -0
  83. package/src/runs/background/subagent-runner.d.ts +4 -0
  84. package/src/runs/background/subagent-runner.js +13 -5
  85. package/src/runs/background/subagent-wait.d.ts +1 -1
  86. package/src/runs/background/subagent-wait.js +6 -1
  87. package/src/runs/background/terminal-run-index.d.ts +2 -0
  88. package/src/runs/background/terminal-run-index.js +44 -3
  89. package/src/runs/foreground/async-stop-action.js +3 -1
  90. package/src/runs/foreground/execution.js +6 -3
  91. package/src/runs/foreground/foreground-history.d.ts +16 -2
  92. package/src/runs/foreground/foreground-history.js +133 -31
  93. package/src/runs/foreground/subagent-executor.d.ts +11 -0
  94. package/src/runs/foreground/subagent-executor.js +277 -74
  95. package/src/runs/shared/child-launch.d.ts +2 -2
  96. package/src/runs/shared/child-session.d.ts +3 -2
  97. package/src/runs/shared/child-session.js +51 -8
  98. package/src/runs/shared/child-tool-plan.d.ts +7 -0
  99. package/src/runs/shared/child-tool-plan.js +21 -6
  100. package/src/runs/shared/herdr-connection.d.ts +17 -8
  101. package/src/runs/shared/herdr-connection.js +19 -7
  102. package/src/runs/shared/herdr-external-adapters.d.ts +3 -2
  103. package/src/runs/shared/herdr-external-adapters.js +1 -1
  104. package/src/runs/shared/herdr-machine.d.ts +12 -2
  105. package/src/runs/shared/herdr-machine.js +55 -9
  106. package/src/runs/shared/herdr-pane-host.d.ts +88 -0
  107. package/src/runs/shared/herdr-pane-host.js +155 -0
  108. package/src/runs/shared/herdr-placed-run.d.ts +27 -150
  109. package/src/runs/shared/herdr-placed-run.js +48 -395
  110. package/src/runs/shared/local-machine-access.d.ts +5 -0
  111. package/src/runs/shared/local-machine-access.js +28 -0
  112. package/src/runs/shared/orca-progress-tabs.d.ts +0 -1
  113. package/src/runs/shared/orca-progress-tabs.js +1 -24
  114. package/src/runs/shared/parallel-utils.d.ts +1 -1
  115. package/src/runs/shared/placed-run-owner.d.ts +49 -0
  116. package/src/runs/shared/placed-run-owner.js +93 -0
  117. package/src/runs/shared/placement-host.d.ts +99 -0
  118. package/src/runs/shared/placement-host.js +157 -0
  119. package/src/runs/shared/rex-machine.d.ts +25 -0
  120. package/src/runs/shared/rex-machine.js +83 -0
  121. package/src/runs/shared/rex-pane-host.d.ts +62 -0
  122. package/src/runs/shared/rex-pane-host.js +327 -0
  123. package/src/shared/completion-owner.d.ts +5 -0
  124. package/src/shared/completion-owner.js +5 -0
  125. package/src/shared/session-identity.d.ts +2 -0
  126. package/src/shared/session-identity.js +26 -0
  127. package/src/shared/types.d.ts +45 -6
  128. package/src/tui/fleet.d.ts +1 -0
  129. package/src/tui/fleet.js +25 -15
  130. package/src/tui/render.d.ts +6 -0
  131. package/src/tui/render.js +3 -3
  132. package/src/tui/subagent-messages.js +1 -0
  133. package/src/workflows/scripted-workflow.d.ts +1 -1
  134. package/src/workflows/workflow-auto-resume.d.ts +32 -0
  135. package/src/workflows/workflow-auto-resume.js +102 -0
  136. package/src/workflows/workflow-launch-record.d.ts +27 -0
  137. package/src/workflows/workflow-launch-record.js +48 -0
  138. package/src/workflows/workflow-resume-claim.d.ts +82 -0
  139. package/src/workflows/workflow-resume-claim.js +210 -0
  140. package/src/workflows/workflow-resume.d.ts +56 -0
  141. package/src/workflows/workflow-resume.js +106 -0
  142. package/src/workflows/workflow-reuse.d.ts +15 -9
  143. package/src/workflows/workflow-reuse.js +77 -14
  144. package/src/workflows/workflow-revival.d.ts +2 -0
  145. package/src/workflows/workflow-revival.js +2 -1
  146. package/src/workflows/workflow-stop-cause.d.ts +6 -0
  147. package/src/workflows/workflow-stop-cause.js +8 -0
  148. package/skills/pi-subagents/references/constraints-and-recipes.md +0 -74
  149. package/skills/pi-subagents/references/execution-controls.md +0 -563
  150. package/skills/pi-subagents/references/management-authoring-rpc.md +0 -165
  151. package/skills/pi-subagents/references/multi-lane-orchestration.md +0 -61
  152. package/skills/pi-subagents/references/review-and-validation.md +0 -73
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  requestAsyncStop
3
- } from "./chunk-BJN5LUQY.js";
3
+ } from "./chunk-OYF6AFDY.js";
4
4
  import "./chunk-NIXWDZZV.js";
5
- import "./chunk-ZBC44JJ3.js";
5
+ import "./chunk-CIZQXJ5Q.js";
6
6
  import "./chunk-5LFLVSTM.js";
7
7
  import "./chunk-YFCK7H2S.js";
8
8
  import "./chunk-Z7KVHQHL.js";
package/bundle/index.js CHANGED
@@ -17,7 +17,7 @@ function readInstalledPackageVersion() {
17
17
  var loadedPackageVersion = readInstalledPackageVersion();
18
18
 
19
19
  // index.ts
20
- var registerExtension = process.env[HERDR_PI_MODE_ENV] === "1" ? (await import("./chunk-V6MR5TOQ.js")).default : process.env.PI_SUBAGENT_CHILD === "1" ? void 0 : (await import("./chunk-V3BIUPLU.js")).default;
20
+ var registerExtension = process.env[HERDR_PI_MODE_ENV] === "1" ? (await import("./chunk-JYUKW2SY.js")).default : process.env.PI_SUBAGENT_CHILD === "1" ? void 0 : (await import("./chunk-IVAE5Z6Q.js")).default;
21
21
  function registerSubagentExtension(pi) {
22
22
  const installedVersion = readInstalledPackageVersion();
23
23
  if (installedVersion !== loadedPackageVersion) {
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  resolveIntercomSessionTarget
3
- } from "./chunk-ZP3HODFH.js";
3
+ } from "./chunk-XSWOTIA3.js";
4
4
  import "./chunk-7F6RKT6W.js";
5
- import "./chunk-ZBC44JJ3.js";
5
+ import "./chunk-CIZQXJ5Q.js";
6
6
  import "./chunk-5LFLVSTM.js";
7
7
  import "./chunk-YFCK7H2S.js";
8
8
  import "./chunk-Z7KVHQHL.js";
@@ -2,22 +2,22 @@ import {
2
2
  buildEffectiveSystemPrompt,
3
3
  canPreferForkFromSnapshot,
4
4
  resolveSubagentLaunchContext
5
- } from "./chunk-ARRKBB2B.js";
6
- import "./chunk-EYNJ6VL6.js";
5
+ } from "./chunk-GJECHSAR.js";
6
+ import "./chunk-PLCCBLPY.js";
7
7
  import {
8
8
  loadConfig
9
- } from "./chunk-WSBNENFS.js";
9
+ } from "./chunk-UCPP4GNU.js";
10
10
  import {
11
11
  nestedResultsPath,
12
12
  processTerminalCandidatePath,
13
13
  processTerminalPath,
14
14
  resultFilePath
15
- } from "./chunk-VJHOELQP.js";
15
+ } from "./chunk-46XKCPJR.js";
16
16
  import {
17
17
  applyIntercomBridgeToAgent,
18
18
  resolveIntercomBridge,
19
19
  validateIntercomBridgeConfig
20
- } from "./chunk-ZP3HODFH.js";
20
+ } from "./chunk-XSWOTIA3.js";
21
21
  import {
22
22
  AGENT_DEFINITION_PROJECTION_VERSION,
23
23
  resolveLaunchBinding,
@@ -26,7 +26,7 @@ import {
26
26
  import {
27
27
  applyThinkingSuffix,
28
28
  resolvePiLaunchToolPlan
29
- } from "./chunk-G5DKFLLI.js";
29
+ } from "./chunk-4SDU2BZX.js";
30
30
  import {
31
31
  assertRequiredChildExtensionsAdmitted,
32
32
  resolveRequiredChildExtensions
@@ -34,7 +34,7 @@ import {
34
34
  import {
35
35
  getArtifactPaths,
36
36
  getArtifactsDir
37
- } from "./chunk-3DC5KBVP.js";
37
+ } from "./chunk-5TYMSZX3.js";
38
38
  import {
39
39
  assertClaudeCodeModelScope,
40
40
  assertThinkingWithinCeiling,
@@ -61,7 +61,7 @@ import {
61
61
  resolveSkillsWithFallback,
62
62
  resolveStepBehavior,
63
63
  unknownAgentDiagnosticContext
64
- } from "./chunk-ZBC44JJ3.js";
64
+ } from "./chunk-CIZQXJ5Q.js";
65
65
  import {
66
66
  DIRS,
67
67
  SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
@@ -8,10 +8,10 @@ import {
8
8
  openProjectPane,
9
9
  projectPaneBindingPath,
10
10
  readProjectPaneBinding
11
- } from "./chunk-V2JWDB5U.js";
11
+ } from "./chunk-52UBALJL.js";
12
12
  import "./chunk-7J4ZXMY7.js";
13
- import "./chunk-3DC5KBVP.js";
14
- import "./chunk-ZBC44JJ3.js";
13
+ import "./chunk-5TYMSZX3.js";
14
+ import "./chunk-CIZQXJ5Q.js";
15
15
  import "./chunk-5LFLVSTM.js";
16
16
  import "./chunk-YFCK7H2S.js";
17
17
  import "./chunk-Z7KVHQHL.js";
package/docs/agents.md CHANGED
@@ -43,7 +43,7 @@ Builtins load at the lowest priority, so a user or project agent with the same n
43
43
  | `researcher` | Web/docs research with sources: official docs, specs, benchmarks, recent changes, and a concise research brief. |
44
44
  | `evidence-auditor` | Independent evidence review of important claims in an existing research brief. |
45
45
  | `worker` | Implementation work, including approved oracle handoffs. It edits files, validates, and escalates unapproved decisions instead of guessing. |
46
- | `reviewer` | Code review and small fixes. It checks the implementation against the task/plan, tests, edge cases, and simplicity. |
46
+ | `reviewer` | Read-only code review. It checks the implementation against the task/plan, tests, edge cases, and simplicity. |
47
47
  | `oracle` | A second opinion before acting. It challenges assumptions, catches drift, and recommends the safest next move without editing. |
48
48
  | `delegate` | A lightweight general delegate when you want a child agent that behaves close to the parent session. |
49
49
 
@@ -282,6 +282,36 @@ Placed external profiles are one-shot and stop-only: they cannot steer, resume,
282
282
 
283
283
  pi-subagents never clones, pulls, or checks out on the machine. Generic `external-cli` commands and managed worktrees are rejected before launch; saved-machine placement accepts native Pi and only the six code-owned external profiles.
284
284
 
285
+ ## Running a Pi child in a Rex pane on this machine
286
+
287
+ `machine: "local"` runs a native Pi child as a visible Pi in a new background tab of your own Rex session, labeled `subagent-<run id tail>`. It works wherever `machine` works: frontmatter, settings overrides, the `subagent` tool, workflow `runs.run`, chain, parallel, and dynamic-fanout steps. `local` is reserved and never looks in the Herdr catalog. The parent Pi must run inside Rex: with no `REX_SESSION`, or a session the Rex server does not confirm, the launch fails before anything starts.
288
+
289
+ The parent drives the child through the same bridge as a Herdr-placed Pi: prompt, steer, follow-up, abort, `contact_supervisor`, and results. The child Pi loads pi-subagents from its own extensions, so it must be installed at the same version. `cwd` is a directory on this machine; a relative path joins the launch directory. pi-subagents finds `rex` in `$REX_BIN_DIR`, then on `PATH`, then in the Rex server app.
290
+
291
+ A finished child keeps its tab open, with the idle Pi, until you close it; an aborted or stopped child's tab is closed. Limits: native Pi only (Claude Code, Codex, Cursor, and generic `external-cli` agents are rejected), fresh context only, and the same restrictions as a Herdr-placed Pi (no local extension paths, process environment, nested delegation, permission rules, or tool budgets).
292
+
293
+ ## Running a Pi child in a Rex pane on another Mac
294
+
295
+ Name a Mac you reach over SSH in your user settings (`~/.pi/agent/settings.json`), with its repo root:
296
+
297
+ ```json
298
+ {
299
+ "subagents": {
300
+ "machines": {
301
+ "workmac": { "rex": { "ssh": "100.82.67.118" }, "cwd": "~/dev/app" }
302
+ }
303
+ }
304
+ }
305
+ ```
306
+
307
+ `machine: "workmac"` then runs a native Pi child as a visible Pi in a new background tab of the Rex session labeled `subagents` on that Mac. pi-subagents creates the session the first time and reuses it after that; if two sessions there have that label, the launch fails until you close or rename one. Every `rex` command runs on that Mac over SSH, and the bridge socket comes back through an SSH forward, so SSH must work without a prompt (`ssh <target>` once to accept the host key). A name with a `rex` entry never looks in the Herdr catalog, so Herdr does not need to be installed.
308
+
309
+ Only user settings may name a Rex host: a `rex` entry in a project's `.pi/settings.json` fails the launch, so a cloned repo cannot choose where a task runs. `cwd` can come from project or user settings, as for Herdr machines: a relative step `cwd` joins it, and an absolute or `~` path is used as given. The other Mac needs Rex, Pi on its login shell's `PATH`, and pi-subagents installed at the same version. The child edits that Mac's disk, so its changed files come from that Mac's Git state, as for a Herdr-placed child.
310
+
311
+ Programs in a Rex tab run under the Rex app's macOS privacy permissions. If Pi on that Mac reads files in Desktop, Documents, or Downloads (for example a package path in its settings), allow Rex there first: open a Rex tab on that Mac, run `ls ~/Documents`, and accept the prompt. Until then Pi waits on the prompt and the launch times out.
312
+
313
+ To watch the tab, open the `subagents` session in Rex on that Mac. To watch it from this Mac, add that Mac's Rex server to your hosts here once (`rex hosts add workmac <endpoint>`; after `rex server tailscale on` there, `rex whoami` on that Mac shows its Tailscale address). Tab lifecycle and limits are the same as for `machine: "local"`.
314
+
285
315
  ## Sandboxing background children with a launcher
286
316
 
287
317
  A launcher wraps an agent's background runner in a command you choose, so that agent can run in a different sandbox from the parent session. Define the command in the user config key [`runnerLaunchers`](configuration.md#runnerlaunchers), then name it in the agent file:
@@ -512,6 +542,7 @@ How `tools` behaves:
512
542
  - `tools` omitted: the child session gets Pi's normal builtin tools.
513
543
  - `tools` present: regular tool names become an explicit allowlist.
514
544
  - `tools:` empty: the child session gets no tools.
545
+ - `tools: +codemode` or `tools: -write`: rejected. Pi's `--tools` and `defaultTools` accept `+name`/`-name` entries that edit the default tool set, but a child's `tools` list replaces that set, so name every tool the child needs, or omit `tools` and use `excludeTools` to drop one. A local agent with such an entry fails before launch. A Herdr- or Rex-placed child resolves its agent on that machine, so an entry only there fails when the pane bridge is configured, before the first prompt.
515
546
  - `allowNestedSubagents: true`: explicitly enables child-safe nested fanout without turning omitted `tools` into an allowlist. Depth and inherited capability ceilings still apply.
516
547
  - `allowedAgents: scout, reviewer`: if nesting is separately enabled, restricts this agent's descendant launches to those names. `allowedAgents:` denies all descendants and omission is unrestricted except for inherited/runtime policy.
517
548
 
@@ -619,11 +650,10 @@ The package bundles a `pi-subagents` skill that is automatically available to th
619
650
 
620
651
  What it covers:
621
652
 
622
- - **Delegation patterns**: how to select a bounded agent and single, parallel, scripted, or async shape after delegation is authorized, including fresh or forked context.
623
- - **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.
624
- - **Role-agent prompting guidance**: compact contract prompts instead of long scripts, what to include in role-specific meta prompts, and retrieval budgets for researchers.
625
- - **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.
626
- - **Intercom conventions**: when to ask vs send, and how parent-side supervisor/result delivery works through the native channel.
627
- - **Control and diagnostics**: attention signals, soft interrupts, status, and the `doctor` action.
653
+ - **Calls**: the common `subagent` calls, workflow script and resume shapes, and async waiting rules.
654
+ - **Delegation rules**: when to delegate at all, what every child brief contains, one writer per worktree, fresh or forked context, and what to do when a lane fails.
655
+ - **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: parallel review, review loop, parallel research, gather-context-and-clarify, parallel cleanup, and oracle consultation.
656
+ - **Orchestration**: splitting work into lanes, review loops, finding disposition, and gate-failure triage.
657
+ - **Lookups**: which `guide` section answers each rarer question, so the skill does not copy this reference.
628
658
 
629
659
  If you are writing an agent that has been asked to orchestrate 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; the README and prompt shortcuts encode the same workflows in user-facing form.
@@ -244,6 +244,14 @@ Set `enabled` to `false` (or remove the block) as a kill switch. In that state,
244
244
 
245
245
  Workflow script calls use background execution when the request omits `async`. Set `asyncByDefault` to `false` to restore foreground-by-default behavior for tool launches that still use the internal single-run primitive. Callers can still force foreground with `async: false` unless `forceTopLevelAsync` is enabled.
246
246
 
247
+ ## `autoResume`
248
+
249
+ ```json
250
+ { "autoResume": false }
251
+ ```
252
+
253
+ Default `true`. When a session is reopened (`pi -c`, `pi --session`, `/resume`) or reloaded (`/reload`), its own async workflows that a Pi exit or a reload interrupted in the last 24 hours are resumed once, without delaying session start; set `autoResume` to `false` to resume them only by hand. A one-shot `pi -p` run does not auto-resume, so it does not wait on the workflow. See [Workflows](workflows.md).
254
+
247
255
  ## `runnerLaunchers`
248
256
 
249
257
  ```json
@@ -387,8 +395,8 @@ Adds a short `active_subagents` section to the parent's system prompt while this
387
395
 
388
396
  `defaultTimeoutMs` sets the blocking window used when a `bg_wait` call omits `timeoutMs`; explicit call values win, followed by this setting, then the 30-minute fallback. `bg_wait` is the only registered wait tool. When the window elapses, the tool returns a non-error `window_elapsed` result with the still-active work identities, and that work keeps running. Set `enabled` to `false` to make direct calls return immediately instead of blocking. The default is enabled. You can also set `"waitTool": false`; set `PI_SUBAGENT_WAIT_TOOL_ENABLED=false` (or `0`, `off`, `disabled`) to override config for one process. The effective enabled and default-timeout values are passed explicitly to child runtimes. Headless `agent_end` auto-drain retains its own strict deadline and fails if required work remains unresolved. Invalid config or environment values fail instead of being coerced.
389
397
 
390
- Blocking `bg_wait({ id: "..." })` keeps the current tool call open until that run changes. By default it returns when a run needs attention. Use `bg_wait({ stopOnAttention: false })` only for run-to-completion flows that should wait through idle or long-thinking attention; supervisor/contact requests still stop the wait. A steer or follow-up the operator sends while a blocking wait is open also ends it, with a non-error `user_input` result listing the still-active work, so the message reaches the model without waiting out the window. In a long-lived interactive parent session, `bg_wait({ id: "...", nonBlocking: true })` instead resolves the prefix once, persists the exact run identity, returns a subscription token immediately, and wakes that session on completion, failure, attention, reconciliation failure, or timeout. Use it for provider, detached, or other background work without a native completion notification; ordinary async subagent runs notify the parent natively and do not need a wait subscription. Armed subscriptions appear in ordinary `subagent({ action: "status" })` output and are not counted as active child work. Native completion notifications wake the session through the Pi process that launched the run, while that process is still running; a session reopened in a new process does not get that wake and should read the result with `subagent({ action: "status" })`. `nonBlocking` subscriptions need a host with a UI context, such as interactive or RPC mode; plain SDK embedding without a UI context rejects them.
391
398
 
399
+ Blocking `bg_wait({ id: "..." })` keeps the current tool call open until that run changes. By default it returns when a run needs attention, even when the run is still working normally, for example a `bash` command open longer than `activeNoticeAfterMs`; the result then says the run is still running. Use `bg_wait({ stopOnAttention: false })` for run-to-completion flows: it waits through idle time, a tool held open, or repeated tool failures, and still ends for a supervisor/contact request, a finished run, the timeout, user input, or abort. A steer or follow-up the operator sends while a blocking wait is open also ends it, with a non-error `user_input` result listing the still-active work, so the message reaches the model without waiting out the window. In a long-lived interactive parent session, `bg_wait({ id: "...", nonBlocking: true })` instead resolves the prefix once, persists the exact run identity, returns a subscription token immediately, and wakes that session on completion, failure, attention, reconciliation failure, or timeout. Use it for provider, detached, or other background work without a native completion notification; ordinary async subagent runs notify the parent natively and do not need a wait subscription. Armed subscriptions appear in ordinary `subagent({ action: "status" })` output and are not counted as active child work. A native completion notification goes to the Pi process that launched the run while that process is running; once it has exited, the session gets the result the next time it is open in any Pi. `nonBlocking` subscriptions need a host with a UI context, such as interactive or RPC mode; plain SDK embedding without a UI context rejects them.
392
400
  This is different from `waitTool.enabled=false`, which returns immediately without registering any future wake. Provider items remain available only to blocking fleet-wide waits; non-blocking subscriptions require one async or remembered detached foreground run id.
393
401
 
394
402
  ## `resultScanLogging`
@@ -82,7 +82,7 @@ The `subagent` tool schema lists `agent`, `task`, `workflow`, `args`, `async`, `
82
82
  | `options.context` | `fresh \| fork \| profile` | global or per-agent default, else `fresh` | Explicit `fresh` or `fork` overrides every workflow child. `profile` requires the selected agent's declared `defaultContext` and ignores config `defaultSubagentContext`; missing agent defaults fail. When omitted, [`defaultSubagentContext`](configuration.md#defaultsubagentcontext) wins over each agent's `defaultContext`; implicit fork falls back to fresh without a persisted parent session and leaf. Explicit fork is strict. Packaged `worker` defaults to `fresh`; packaged `oracle` and `advisor` default to `fork`. |
83
83
  | `model` | string | agent default | An exact `provider/id`; bare ids resolve only if unique, and agent names are not model ids. An unknown or ambiguous model fails with up to 5 closest registry ids to copy; `{action:"models"}` lists them all. A suffix such as `provider/id:high` (`off/minimal/low/medium/high/xhigh/max`) overrides agent thinking. The `thinking` field is only for `watchdog.configure`, ignored on dispatch. On the `claude-code` and `claude-code-writer` adapters the model is Claude Code's own alias or id, and the same suffix becomes its `--effort`, bounded by `subagents.maxThinking` and by an enforced `subagents.modelScope`. |
84
84
  | `options.missionId` | string | - | Attach a workflow, including each fire of `schedule.create`, to an existing project mission. Scheduled attachment uses ordinary lifecycle and retention rules. |
85
- | `options.reuseFrom` | string | - | Exact id of an async workflow run stopped by a runtime replacement (`workflow.stopCause: "runtime-replaced"`). An async relaunch of the same script in the same cwd, from any session, reuses that run's finished children and waits for its running ones; see [Workflows](workflows.md). |
85
+ | `options.reuseFrom` | string | - | Exact id of an async workflow run stopped by a runtime replacement or whose Pi process exited (`workflow.stopCause: "runtime-replaced"` or `"owner-exited"`). An async relaunch of the same script in the same cwd, from any session, reuses that run's finished children and waits for its running ones; see [Workflows](workflows.md). |
86
86
  | `options.mission` | object/false | auto-create | Override the default enclosing mission with `{ title \| summary, objective?, goal?, budget?, labels? }`. Set exactly one non-empty `title` or `summary`; `objective` and `labels` are optional. `goal` may only be `true`, requires `budget.tokens`, and enables continuation notices. Pass `false` for an intentionally ephemeral workflow with no mission for it or its children and no `state` global. Explicit mission persistence failures are strict. |
87
87
  | `options.handoffPath` | string | - | Aggregate handoff manifest for `action: "worktree.discard"` or lane evidence actions, or optional explicit metadata for `action: "worktree.cleanup"`. |
88
88
  | `options.repo` | string | runtime cwd | Repository path for `action: "worktree.cleanup"`; required explicitly for apply. The configured worktree base filters candidates by their per-project folder under it but never discovers them. |
@@ -329,6 +329,7 @@ subagent({ action: "stop", id: "<run-id>" })
329
329
  subagent({ action: "resume", id: "<run-id>", message: "follow-up question after it pauses or finishes" })
330
330
  subagent({ action: "resume", id: "<run-id>", message: "follow-up for child 2", options: { index: 1 } })
331
331
  subagent({ action: "resume", id: "<nested-run-id>", message: "follow-up for a nested child" })
332
+ subagent({ action: "resume", id: "<stopped-workflow-run-id>" })
332
333
  subagent({ action: "steer", id: "<run-id>", message: "guidance for the running child" })
333
334
  subagent({ action: "steer", id: "<run-id>", message: "check this after the current turn", options: { mode: "follow_up" } })
334
335
  subagent({ action: "steer", id: "<run-id>", message: "guidance for child 2", options: { index: 1, mode: "auto" } })
@@ -379,6 +380,7 @@ Commands remain owned by the child session. Normal completion with unfinished co
379
380
  - Completed external-job runs, including nested runs, can use the same `resume` action as a provider follow-up when the registered provider exposes `followUp(input)`. Running external-job parents fail closed with guidance to wait for completion. Unsupported providers fail with an update/reload message.
380
381
  - Revive starts a new child session from the old session context; it does not resume the live session, and it requires the chosen child to have a persisted `.jsonl` session file.
381
382
  - Direct revival takes an exclusive cross-process lease on the canonical session file until the new child finishes. A concurrent attempt fails before Pi is spawned and identifies the owning revived run; dead-owner leases are reclaimed only when staleness can be proved.
383
+ - Without `message` (and without `index` or `chain`), `resume` on a top-level async workflow run that stopped because its session was replaced or its Pi process exited (`workflow.stopCause: "runtime-replaced"` or `"owner-exited"`) relaunches it once from the launch it saved, reusing its finished children, and its receipt starts with `Resumed workflow '<id>' as <new id>.`; a run that cannot be resumed is refused as `Cannot resume workflow '<id>': <reason>.` The session that owns the run also resumes it on its own when reopened or reloaded, unless [`autoResume`](configuration.md#autoresume) is off; see [Workflows](workflows.md).
382
384
 
383
385
  ### stop
384
386
 
package/docs/workflows.md CHANGED
@@ -14,6 +14,8 @@ Packaged `worker` defaults to fresh context so implementation starts from its as
14
14
 
15
15
  Launch children in the background (`async` follows `asyncByDefault`, normally true) and consume each result at the point a later step depends on it. Native completion wakes the parent session, so the parent returns control instead of sleeping or polling. Use `async: false` only when the parent must block, not for final reviews or gates. When an oracle or advisor reaches an unknown that needs a decision, it asks through supervisor dialogue; use a one-shot oracle call only when one was requested.
16
16
 
17
+ A background child awaited by an `async: false` workflow cannot receive a supervisor decision while its parent is blocked in that call. Its native `contact_supervisor` decision or interview request returns a tool error promptly, asking it to report the blocker and partial results and stop. The transport error is not a supervisor reply or approval. Use `async: true` for workflows whose children may need a decision. Progress updates remain non-blocking, and an explicit child `async: true` still returns its launch receipt without being awaited.
18
+
17
19
  Child-safety boundaries are enforced at runtime:
18
20
 
19
21
  - Child sessions do not receive the bundled `pi-subagents` skill.
@@ -31,8 +33,22 @@ Failed workflow details and async `status.json` include `workflow.failureKind` a
31
33
 
32
34
  When `/reload`, a session resume, or a pi-web project switch replaces the extension runtime, a running async workflow stops with `workflow.stopCause: "runtime-replaced"` in `status.json`, and its awaited async children keep running. Its in-process foreground children are stopped, including ones that detached to ask their supervisor. When the same workflow script is launched again with the same `args` in that session, a `runs.run` with the same key and params returns a child that already finished successfully without launching it, and waits for a child that is still running instead of starting another. Those results carry `reused: true`, their step and trace entry are marked `reused`, and the new run records `workflow.reusedFrom`. Failed and stopped children, and children that ran in-process, launch again. Reuse applies only when the newest run of that script and args in the session was stopped this way; a user stop or a completed run ends it. From another session, such as one that took over after a handoff, relaunch the same script as an async workflow with `options: { reuseFrom: "<stopped run id>" }`; the run must have stopped this way in the same cwd, and `args` may differ, because each child is still reused only when its key and params match.
33
35
 
36
+ When the Pi process that ran an async workflow exits before the workflow finishes (a crash, a kill, or a machine restart), the stale-run check that runs when its session reopens, or when `options.reuseFrom` names the run, marks it failed with `workflow.stopCause: "owner-exited"`, and a relaunch reuses its finished children the same way. On any relaunch, `runs.steer` and `runs.host` calls run again and only `runs.run` results are reused, so a replayed check such as "tests passed" can be stale.
37
+
38
+ A stopped run is continued by one relaunch only. While that relaunch exists, another relaunch of the same stopped run, by the same script or by `options.reuseFrom`, is refused with `workflow run '<id>' was resumed as <new id>; wait on it or stop it.` If that relaunch stops the same way, relaunch it instead: it carries the children of every run before it. If the Pi process that started the relaunch exits before the relaunch begins, the stopped run can be relaunched again.
39
+
40
+ To continue a stopped run without sending its script again, resume it by id from the session that owns it: `subagent({ action: "resume", id: "<stopped run id>" })` with no `message`. Every async top-level workflow saves its launch (the script or named resource, its `args` and options) when it starts, and the resume relaunches that launch with `options.reuseFrom` set to the stopped run, in the stopped run's cwd, with no more authority than it had. A named resource is resolved again and must still have the same script. The new run records `workflow.resumeOrigin: { sourceRunId, attempt }`, where `attempt` counts the resumes that followed a Pi exit. Another session cannot resume the run by id; reopen the session that started it, or relaunch the same script with `options.reuseFrom`. When the run cannot be resumed this way (it started before launches were saved, was launched from `tasks` or `chain`, or its resource changed), the refusal says so; relaunch the same script by hand with `options: { reuseFrom: "<stopped run id>" }`.
41
+
42
+ When the session that owns such a run is reopened or reloaded, the run is resumed this way automatically, once, if it was interrupted in the last 24 hours: for a Pi exit, measured from the last time the dead Pi process updated the run. Session start does not wait for the relaunch. A run that cannot be relaunched is named in its notice (`Not auto-resumed: …`, with how to continue by hand); a launch that fails after session start also posts one `Workflow <id> was not auto-resumed: <reason>.` message. Either way the run is not tried again. `/new` and forks do not resume the runs of the session they replaced. The `autoResume` setting turns this off; see [Configuration](configuration.md#autoresume).
43
+
44
+ Starting Pi in a folder where another session's subagent runs were cut off by its Pi dying in the last 24 hours shows one info line per such session, such as ``2 subagent runs were interrupted in another session. Reopen it to resume them: `pi --session <id>` ``; it only points to that session, changes nothing in it, and is not sent to the model.
45
+
46
+ The completion notice of a workflow stopped by a Pi exit or a runtime replacement has one line right after `Workflow run: <id>` that says what happens next: `Auto-resumed as <new id>.`, `Resumed as <new id>.` (resumed by id), `Relaunched as <new id>.` (relaunched with the same script or `options.reuseFrom`), `Not auto-resumed: <reason>.` followed by the way to continue by hand, or, when nothing continues it, `Resume by hand: subagent({ action: "resume", id: "<id>" })` (or the `options.reuseFrom` form when its launch cannot be resumed by id).
47
+
34
48
  After `/new`, `/resume`, or a fork in the same Pi process, the new session owns the async runs of the session it replaced, and of the sessions that one replaced. It can list, `bg_wait` on, steer, stop, and resume them, receives their completion notices, and answers their children's pending supervisor requests. Over RPC, a host can steer, interrupt, stop, resume, and inspect them, and sees them in the fleet and `subagent-async` snapshots. Startup and other Pi processes inherit nothing; `/reload` adds nothing new but keeps what the session already inherited. To relaunch a stopped workflow instead of controlling its children one by one, use `options.reuseFrom`.
35
49
 
50
+ Once the Pi process that started a background single, parallel, or chain run has exited, the run is reported once to a Pi window that has its session open, whether it finished while Pi was closed or finishes later. A workflow's children are reported through their workflow.
51
+
36
52
  Pi core may print a generic `pi -ne` extension-load hint; that out-of-repo hint is not protocol-approved fallback. A verified compaction abort may continue the retained child once on its already resolved model; it does not authorize an execution-mode or model switch.
37
53
 
38
54
  ## Prompt shortcuts
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "pi-subagents",
4
- "version": "0.81.0",
4
+ "version": "0.82.1",
5
5
  "description": "Pi extension for single-agent delegation and scripted multi-agent workflows",
6
6
  "author": "Nico Bailon",
7
7
  "license": "MIT",
@@ -20,7 +20,7 @@
20
20
  "@js-temporal/polyfill": "0.5.1",
21
21
  "acorn": "8.18.0",
22
22
  "jiti": "2.7.0",
23
- "undici": "8.10.2",
23
+ "undici": "8.12.3",
24
24
  "yaml": "2.8.3"
25
25
  },
26
26
  "peerDependencies": {
@@ -9,10 +9,7 @@ Council mode is parent-supervised advice for a material decision with real trade
9
9
 
10
10
  The parent selects the roster, relays only curated claims, decides validity, and writes the memo. Advisors stay read-only and do not see peer transcripts by default.
11
11
 
12
- Before launch, read:
13
-
14
- - `skills/pi-subagents/references/execution-controls.md`
15
- - `skills/council-mode/references/pass-contracts.md`
12
+ Before launch, read `skills/council-mode/references/pass-contracts.md`.
16
13
 
17
14
  ## Roster
18
15
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: pi-subagents
3
3
  description: |
4
- Technical guidance for operator-requested delegation to builtin or custom
5
- subagents: bounded handoffs, parallel review, scripted workflows, async work,
6
- forked context, isolation, and coordinated execution.
4
+ Delegate work to Pi subagents after the operator asks for it: one child,
5
+ parallel or scripted workflows, async runs, resume/steer/stop, review fanout,
6
+ and multi-lane or worktree orchestration.
7
7
  ---
8
8
 
9
9
  # Pi Subagents
@@ -14,111 +14,134 @@ instructions. Task size, complexity, risk, tool-call count, recipe fit, or an
14
14
  available specialist does not independently authorize delegation.
15
15
 
16
16
  Once authorized, choose the smallest bounded shape that earns its token and
17
- elapsed-time overhead through concrete evidence, independent review,
18
- specialization, useful parallelism, or needed isolation. A single child is
19
- valid; writer, challenge, and review stages must each earn their overhead rather
20
- than becoming default ceremony. The parent keeps user intent, constraints,
21
- routing, arbitration, decisions, final acceptance, and publication authority,
22
- and may perform the work directly where it is the most efficient owner.
17
+ elapsed-time overhead through evidence, independent review, specialization,
18
+ useful parallelism, or isolation. A single child is valid. The parent keeps
19
+ intent, routing, decisions, final acceptance, and publication authority, and
20
+ does the work itself where that is cheaper.
21
+
22
+ ## Calls
23
+
24
+ ```typescript
25
+ subagent({ agent: "worker", task: "<brief>" }) // one child; async by default
26
+ subagent({ workflow: "parallel", args: { tasks: [{ agent, task, cwd?, model? }] } }) // independent children
27
+ subagent({ workflow: true }) // runs the one ```js workflow block in this same reply
28
+ subagent({ workflow: "./lane.js", args }) // script file, path relative to the request cwd
29
+ subagent({ action: "validate", workflow: "./lane.js" }) // check a script without launching
30
+ subagent({ action: "status", id }) // options: { view: "fleet" } or { view: "transcript", index: 0 }
31
+ subagent({ action: "resume", id, message }) // completed or paused child; returns a new run id
32
+ subagent({ action: "steer", id, message }) // live async child
33
+ subagent({ action: "stop", id }) // ends the run; not resumable
34
+ subagent({ action: "interrupt", id }) // pauses the child's current turn
35
+ subagent({ action: "list" }) · subagent({ action: "models" })
36
+ subagent({ action: "guide", options: { topic: "<section address>" } })
37
+ ```
38
+
39
+ Launches are async by default. Set `async: false` only when the parent must
40
+ block; final reviews and gates stay async. After launching, keep doing safe
41
+ independent work, or yield: native completion wakes this session. Do not sleep,
42
+ poll, or call `bg_wait` for ordinary children. Use `bg_wait` only for provider
43
+ or detached work that has no native notification and whose result this turn
44
+ needs.
45
+
46
+ ## Workflow scripts
47
+
48
+ Use a script when later steps depend on earlier results, or for keyed,
49
+ retried, aggregated, or resumed children. Write one ```` ```js workflow ````
50
+ block in the reply and call `subagent({ workflow: true })` in the same reply.
51
+ For a long script, or when a `workflow: true` call reports the block missing,
52
+ write it to a file and pass `workflow: "./path.js"`. On Claude 5.x models (Opus
53
+ 5.5, Sonnet 5.5, Fable 5.1), use the file whenever the turn already made a tool
54
+ call: text after one reaches the session as a summary without the block. Calls in one reply run at
55
+ the same time, so write the file in one reply and `validate` or launch it in
56
+ the next.
57
+
58
+ ```js workflow
59
+ const scan = await runs.run("scan", { label: "Map auth flow", agent: "scout", task: "..." });
60
+ const reviews = await runs.all([
61
+ { key: "correctness", label: "Review auth correctness", agent: "reviewer", task: "... " + scan.output },
62
+ { key: "tests", label: "Review auth tests", agent: "reviewer", task: "..." },
63
+ ]);
64
+ return reviews.map((review) => review.output);
65
+ ```
66
+
67
+ - Scripts are statement bodies with an explicit `return`, top-level `await`,
68
+ and plain helpers. Nested async functions, arrows, and methods are rejected.
69
+ - Every `runs.run` / `runs.all` item needs a stable `key`. Add a short
70
+ verb + behavior `label` unless the user gave one.
71
+ - Bind files with `output: "plans/x.md"` (relative paths land in run
72
+ artifacts) and return `outputReference` or `artifactPaths`. A filename in
73
+ task text does not route output. Never send reports to the repo root.
74
+ - `runs.lanes([{ key, stages: [...] }])` runs a predeclared plan: first stages
75
+ together, later stages in order per lane.
76
+
77
+ Resuming a retained child:
78
+
79
+ ```js workflow
80
+ let child = await runs.run("fix-1", { agent: "worker", task: "..." });
81
+ child = await runs.run("fix-2", { resume: child.runId, task: "Apply these accepted findings: ..." });
82
+ return child.output;
83
+ ```
84
+
85
+ - Always resume the latest returned run id; every resume returns a new one.
86
+ - Use a new stable key for every resume pass.
87
+ - `resume` excludes `agent` and `gate`; the child keeps its agent, model, and tools.
88
+ - Resume a completed child; steer a live one. Top-level `{ action: "resume" }` is detached.
89
+
90
+ ## Briefs
91
+
92
+ Every child starts cold. Its task states: goal; repo, explicit `cwd`, and
93
+ ref; authority and edit boundary; relevant files, decisions, and evidence;
94
+ success criteria; validation; expected output; and when to stop or ask.
95
+ Make parallel briefs differ by seam, evidence, and decision, not just an item
96
+ number.
97
+
98
+ ## Rules
99
+
100
+ - One writer per cwd or worktree. Parallelize reading, review, and
101
+ validation. `worktree: true` needs a clean checkout (untracked files count;
102
+ `.pi/subagents/` does not). For Pi extension repos, put lane worktrees
103
+ outside `~/.pi/agent/extensions`, for example `~/.pi/agent/worktrees`.
104
+ - Reviewers use fresh context. Use `context: "fork"` only when the child needs
105
+ the parent's history; it requires a persisted parent session.
106
+ - Children do not spawn subagents unless the parent delegated fanout and their
107
+ resolved `tools` include `subagent`.
108
+ - A failed workflow, launch, prompt runtime, extension load, or child tool
109
+ setup blocks the lane. Stop, report the exact failure and run/worktree state,
110
+ verify a clean worktree or capture the partial diff, then retry the same way
111
+ once. Switching to `interactive_shell`, `pi -ne`, or another CLI needs owner
112
+ approval.
113
+ - As a conservative orchestration policy, do not pass a hard `toolBudget` or tight `usageBudget` to mutation-capable workers. The default tool budget blocks read/search tools rather than mutation tools. If interrupted after a tool call starts, checkpoint after the current tool returns with changed files, build/test state, and commit or PR state.
114
+ - Route workers and scouts to a fast capable tier, serious reviews to a strong
115
+ tier, and top reasoning only to bounded read-only critique. Exact model names
116
+ belong in user or project settings, not here.
117
+ - `subagent`, `subagents_enable`, `subagent_supervisor`, `contact_supervisor`, and `structured_output` are model-only: call them as ordinary model tool calls. Codemode scripts cannot reach them through `tools.*`, `ALL_TOOLS`, or `searchTools`.
118
+ - Receipts, CI, and review bots are evidence, not authority. Backlog, release,
119
+ and merge policy belong to the user's or project's own skill.
23
120
 
24
- Children do not spawn subagents unless the parent explicitly delegated fanout
25
- and their resolved `tools` allow `subagent`.
121
+ ## Look up the rest
26
122
 
27
- ## Launch shape
123
+ If only `subagents_enable` is visible, call it first; `subagent` and `guide`
124
+ work from the next request. Read one section, not a whole topic:
28
125
 
29
- | Need | Use |
30
- | --- | --- |
31
- | One bounded task for one child | direct `{ agent, task }` |
32
- | JavaScript control flow or data-dependent branching; sequence, fanout, retry, rolling fanout, or aggregation | a workflow script with `runs.run(...)` / `runs.all(...)` |
33
- | A broad plan split into visible narrow stages per lane | a workflow script with `runs.lanes([{ key, stages: [...] }])` |
34
- | Independent worktree or repository lanes | `references/multi-lane-orchestration.md` |
35
- | Council of advisors | `../council-mode/SKILL.md` |
36
- | Management, status, steering, authoring, or inspection | `action` |
37
-
38
- To launch a workflow script, write it as one ```` ```js workflow ```` fenced
39
- block in your reply, then call `subagent({ workflow: true, ... })` in the same
40
- reply. Use `workflow: "./path/to/script.js"` for a script file and
41
- `workflow: "<name>"` for a named resource.
42
-
43
- A workflow script is code-driven: `runs.run(...)` for keyed steps,
44
- `runs.all([...])` for fanout, plain JavaScript for branching and aggregation.
45
- Keep scripts portable: use top-level `await`, plain helpers, or explicit Promise
46
- chains, not nested async helpers. Legacy top-level `chain` / `tasks` inputs and
47
- durable `.chain.md` execution are inspection or migration material only, except
48
- that `disabledFeatures: ["workflow-scripts"]` replaces scripts with top-level
49
- `chain` and `tasks` (see [configuration](../../docs/configuration.md#chain-and-tasks-without-workflow-scripts)).
50
-
51
- Use `runs.lanes(...)` only inside a workflow script, not as a top-level mode,
52
- when a broad, predeclared plan benefits from visible per-lane stages; otherwise
53
- use ordinary `runs.run(...)` / `runs.all(...)`. See the [canonical staged-lane
54
- example](../../docs/workflows.md#parallel-sequential-lanes). Keep assignments
55
- bounded, but do not add stages or ceremony just to satisfy this skill.
56
-
57
- When composing `runs.run(...)`, `runs.all(...)`, or `runs.lanes(...)`, always
58
- supply a short verb + behavior display `label` derived from the task, unless
59
- the user supplied an explicit label; preserve that label. Keep the stable
60
- machine `key` independent (for example, `issue2011-writer` with
61
- `label: "Fix workflow steering"`). For `runs.lanes`, put labels on stage
62
- items, not lane objects. Use stage-appropriate labels for reviews and retained-child
63
- follow-ups too (for example, `Review workflow steering`). Generate labels in
64
- the orchestrator while composing the launch—no extra model call, runtime
65
- generator, or schema change. Native direct `{ agent, task }` calls have no
66
- top-level `label` parameter; do not invent one or wrap a tiny single task in
67
- a workflow just to label it.
68
-
69
- Use async/background by default. Set `async:false` only when the parent must
70
- block. Final reviews, validation gates, oracle checks, and publication checks
71
- stay async.
72
-
73
- In an ordinary interactive session, yield after launching or triaging useful
74
- async lanes and let Pi wake the parent on completion; ordinary async subagents
75
- already have native completion notifications, so do not call `bg_wait()` merely
76
- because a child is active. Use blocking `bg_wait()` only for provider,
77
- detached, or other background work without a native notification when a
78
- headless/run-to-completion contract or a required same-turn artifact makes the
79
- result necessary before this turn ends. For
80
- “continue/orchestrate/work until done,” keep the lane board moving while a safe
81
- immediate action remains; if only async lanes are running, record the revisit
82
- trigger and yield.
83
-
84
- Package agents appear in `subagent({ action: "list" })`. External CLI/job agents
85
- use their own runner contract. Do not pass native Pi child options to them unless
86
- that runner explicitly supports the option.
87
-
88
- ## Read the reference for the branch
89
-
90
- For exact API fields and worked examples, call `subagent({action:"guide",options:{topic:"tool-reference"}})` or `topic:"workflows"`. The compact tool definition is not the recipe catalog; use `topic:"missions"` for mission updates and schedules.
91
-
92
- | Branch | Read |
126
+ | Need | Guide section |
93
127
  | --- | --- |
94
- | Delegate or choose roles, prompts, models, or slash commands | `references/prompting-and-roles.md` |
95
- | Execute single, scripted, async, scheduled, mission, forked, watchdog, oracle, or intercom workflows | `references/execution-controls.md` |
96
- | Review, validate, triage gate failures, or prepare delivery | `references/review-and-validation.md` |
97
- | Coordinate lanes, worktrees, repositories, or writer waves | `references/multi-lane-orchestration.md` |
98
- | List, create, edit, disable, eject, or expose agents/RPC | `references/management-authoring-rpc.md` |
99
- | Check safety constraints, recipes, or error handling | `references/constraints-and-recipes.md` |
100
-
101
- For an authorized complex delegated workflow, read `prompting-and-roles.md` and
102
- `execution-controls.md`, then load `review-and-validation.md` and
103
- `constraints-and-recipes.md` before launch or review.
104
-
105
- ## Operating rules
106
-
107
- - Avoid duplicate scouts, overlapping writers, and vague prompts without a concrete deliverable.
108
- - Call `subagent`, `subagents_enable`, `subagent_supervisor`, `contact_supervisor`, and `structured_output` as ordinary model tool calls. They are model-only, so codemode scripts cannot reach them through `tools.*`, `ALL_TOOLS`, or `searchTools`.
109
- - Keep the parent on the ordinary strong default model. Route workers/scouts to a fast capable tier, serious reviews to a strong tier, and top reasoning to bounded read-only critique.
110
- - Exact model names are deployment policy. Put them in user/project settings or profiles, not package guidance.
111
- - Give every child a compact meta-prompt checklist: objective; repo/cwd/ref; authority/edit boundary; relevant files/contracts and constraints; success/acceptance criteria; validation; expected output/report; and stop/ask conditions. See `references/prompting-and-roles.md`.
112
- - Before launching a writer for substantial mutation work, classify it as single-seam or multi-seam and partition multi-seam work across exclusive component owners, gates, and durable handoffs before an integration-only owner. See `references/multi-lane-orchestration.md`.
113
- - For mutation work, use an isolated lane/worktree when isolation, overlap, or concurrent juggling matters; keep one writer per cwd/worktree. `worktree: true` refuses to launch unless the source checkout is clean (untracked files count; `.pi/subagents/` does not), so commit your own changes first or plan the lane without managed isolation. See `references/multi-lane-orchestration.md` for lane mechanics.
114
- - Keep long/high-output validation out of chat: prefer `interactive_shell` dispatch/background monitors, bounded logs, or subagent-owned reports; return a concise summary plus report path unless same-turn output is required. Do not use `interactive_shell` as an implicit fallback for a failed `subagent` lane; see `references/execution-controls.md`.
115
- - Treat subagent workflow, child launch, prompt runtime, extension load, and child tooling setup failures as lane infrastructure blockers. Stop, report the exact failure and run/worktree state, verify a clean worktree or capture a partial diff, and use only a clear same-protocol retry or an owner-approved execution-mode fallback.
116
- - For cross-codebase work, record the repo, explicit `cwd`, authority boundary, and expected output before launch.
117
- - Make parallel prompts distinct by source seam, evidence, and decision. Do not clone prompts with only item numbers swapped.
118
- - Prefer fresh-context review/validation fanout, then synthesize and apply fixes in the parent.
119
- - For Pi extension repos under `~/.pi/agent/extensions`, put lane worktrees outside extension auto-discovery, such as `~/.pi/agent/worktrees`.
120
- - Preserve capability ceilings, including child tool limits and allowed-agent restrictions.
121
- - Preserve parent authority and escalate unresolved choices.
122
- - Treat receipts, CI, review bots, and external-run records as evidence, not authority.
123
- - For backlog maintenance, releases, merge queues, or other public-repo mutation policy, load the matching user/project skill. This package defines delegation primitives, not private policy.
124
- - As a conservative orchestration policy, do not pass a hard `toolBudget` or tight `usageBudget` to mutation-capable workers. The default tool budget blocks read/search tools rather than mutation tools. If interrupted after a tool call starts, checkpoint after the current tool returns with changed files, build/test state, and commit or PR state.
128
+ | Script API: `runs.*`, `state`, limits | `workflows/scripted-workflows` |
129
+ | Typed gates, host commands, rolling fanout | `workflows/typed-post-run-checks-and-typed-steps`, `workflows/host-command-steps`, `workflows/advanced-rolling-child-runs` |
130
+ | Budgets, timeouts, `baseRef`, `gate`, `output` | `tool-reference/execution-parameters`, `tool-reference/output-mode-details` |
131
+ | Fresh or forked context | `tool-reference/fork-context-details` |
132
+ | Resume, steer modes, stop, status | `tool-reference/retained-children`, `tool-reference/resume`, `tool-reference/steer`, `tool-reference/stop`, `tool-reference/status` |
133
+ | Acceptance and review gates | `tool-reference/acceptance-gates` |
134
+ | Worktrees and handoffs | `workflows/worktree-isolation` |
135
+ | Child asks the parent (`contact_supervisor`) | `workflows/supervisor-coordination-child-asks-parent` |
136
+ | Agent create, update, eject, disable, refine | `tool-reference/management-actions`, `agents/frontmatter-reference` |
137
+ | Missions and schedules | `missions/missions`, `missions/schedules` |
138
+ | Watchdog | `watchdog/when-it-runs`, `watchdog/choosing-a-model` |
139
+ | Model overrides and profiles | `models/setting-defaults-and-overrides` |
140
+ | Other projects in panes | `tool-reference/herdr-project-panes` |
141
+ | Setup looks wrong | `subagent({ action: "doctor" })` |
142
+
143
+ ## References
144
+
145
+ - Choosing roles, writing prompts, review/research/cleanup techniques, oracle → [prompting-and-roles.md](references/prompting-and-roles.md)
146
+ - Several lanes, worktrees, repositories, staged fixes, review loops, finding and gate triage → [orchestration.md](references/orchestration.md)
147
+ - Advisor council → [../council-mode/SKILL.md](../council-mode/SKILL.md)