pi-subagents 0.73.0 → 0.74.0

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 (245) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +1 -1
  3. package/docs/agents.md +18 -12
  4. package/docs/configuration.md +66 -9
  5. package/docs/extension-api.md +5 -4
  6. package/docs/missions.md +13 -13
  7. package/docs/models.md +2 -2
  8. package/docs/observability.md +2 -2
  9. package/docs/tool-reference.md +63 -86
  10. package/docs/workflows.md +165 -171
  11. package/package.json +2 -2
  12. package/prompts/review-loop.md +1 -1
  13. package/skills/council-mode/SKILL.md +1 -1
  14. package/skills/pi-subagents/SKILL.md +12 -5
  15. package/skills/pi-subagents/references/constraints-and-recipes.md +3 -3
  16. package/skills/pi-subagents/references/execution-controls.md +68 -67
  17. package/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
  18. package/skills/pi-subagents/references/multi-lane-orchestration.md +1 -1
  19. package/skills/pi-subagents/references/prompting-and-roles.md +45 -48
  20. package/src/agents/advertised-agent-prompt.d.ts +6 -4
  21. package/src/agents/advertised-agent-prompt.d.ts.map +1 -1
  22. package/src/agents/advertised-agent-prompt.js +16 -30
  23. package/src/agents/advertised-agent-prompt.js.map +1 -1
  24. package/src/agents/agent-management.js +2 -2
  25. package/src/agents/agent-management.js.map +1 -1
  26. package/src/agents/agents.d.ts +1 -0
  27. package/src/agents/agents.d.ts.map +1 -1
  28. package/src/agents/agents.js +8 -0
  29. package/src/agents/agents.js.map +1 -1
  30. package/src/api/preflight.d.ts +5 -1
  31. package/src/api/preflight.d.ts.map +1 -1
  32. package/src/api/preflight.js +2 -1
  33. package/src/api/preflight.js.map +1 -1
  34. package/src/extension/config.d.ts.map +1 -1
  35. package/src/extension/config.js +12 -4
  36. package/src/extension/config.js.map +1 -1
  37. package/src/extension/control-notices.d.ts +2 -0
  38. package/src/extension/control-notices.d.ts.map +1 -1
  39. package/src/extension/control-notices.js +2 -0
  40. package/src/extension/control-notices.js.map +1 -1
  41. package/src/extension/doctor.d.ts.map +1 -1
  42. package/src/extension/doctor.js +1 -0
  43. package/src/extension/doctor.js.map +1 -1
  44. package/src/extension/fanout-child.d.ts.map +1 -1
  45. package/src/extension/fanout-child.js +13 -3
  46. package/src/extension/fanout-child.js.map +1 -1
  47. package/src/extension/herdr-pi-bridge.d.ts.map +1 -1
  48. package/src/extension/herdr-pi-bridge.js +2 -0
  49. package/src/extension/herdr-pi-bridge.js.map +1 -1
  50. package/src/extension/index.d.ts +1 -1
  51. package/src/extension/index.d.ts.map +1 -1
  52. package/src/extension/index.js +71 -169
  53. package/src/extension/index.js.map +1 -1
  54. package/src/extension/public-execution.d.ts +10 -1
  55. package/src/extension/public-execution.d.ts.map +1 -1
  56. package/src/extension/public-execution.js +69 -35
  57. package/src/extension/public-execution.js.map +1 -1
  58. package/src/extension/reply-workflow-script.d.ts +12 -0
  59. package/src/extension/reply-workflow-script.d.ts.map +1 -0
  60. package/src/extension/reply-workflow-script.js +61 -0
  61. package/src/extension/reply-workflow-script.js.map +1 -0
  62. package/src/extension/rpc.d.ts +2 -0
  63. package/src/extension/rpc.d.ts.map +1 -1
  64. package/src/extension/rpc.js +33 -10
  65. package/src/extension/rpc.js.map +1 -1
  66. package/src/extension/schemas.d.ts +3 -117
  67. package/src/extension/schemas.d.ts.map +1 -1
  68. package/src/extension/schemas.js +38 -125
  69. package/src/extension/schemas.js.map +1 -1
  70. package/src/extension/tool-activation.d.ts +2 -4
  71. package/src/extension/tool-activation.d.ts.map +1 -1
  72. package/src/extension/tool-activation.js +54 -104
  73. package/src/extension/tool-activation.js.map +1 -1
  74. package/src/extension/tool-description.d.ts +8 -5
  75. package/src/extension/tool-description.d.ts.map +1 -1
  76. package/src/extension/tool-description.js +51 -27
  77. package/src/extension/tool-description.js.map +1 -1
  78. package/src/extension/upgrade-notice.d.ts +7 -0
  79. package/src/extension/upgrade-notice.d.ts.map +1 -0
  80. package/src/extension/upgrade-notice.js +37 -0
  81. package/src/extension/upgrade-notice.js.map +1 -0
  82. package/src/integrations/herdr-status.d.ts +3 -0
  83. package/src/integrations/herdr-status.d.ts.map +1 -1
  84. package/src/integrations/herdr-status.js +17 -3
  85. package/src/integrations/herdr-status.js.map +1 -1
  86. package/src/intercom/native-supervisor-channel.d.ts.map +1 -1
  87. package/src/intercom/native-supervisor-channel.js +4 -1
  88. package/src/intercom/native-supervisor-channel.js.map +1 -1
  89. package/src/runs/background/async-execution.d.ts +3 -0
  90. package/src/runs/background/async-execution.d.ts.map +1 -1
  91. package/src/runs/background/async-execution.js +6 -2
  92. package/src/runs/background/async-execution.js.map +1 -1
  93. package/src/runs/background/async-job-tracker.d.ts.map +1 -1
  94. package/src/runs/background/async-job-tracker.js +65 -22
  95. package/src/runs/background/async-job-tracker.js.map +1 -1
  96. package/src/runs/background/async-retention.d.ts +1 -1
  97. package/src/runs/background/async-retention.d.ts.map +1 -1
  98. package/src/runs/background/async-retention.js +47 -15
  99. package/src/runs/background/async-retention.js.map +1 -1
  100. package/src/runs/background/await-async-run.d.ts +23 -0
  101. package/src/runs/background/await-async-run.d.ts.map +1 -0
  102. package/src/runs/background/await-async-run.js +80 -0
  103. package/src/runs/background/await-async-run.js.map +1 -0
  104. package/src/runs/background/chain-root-attachment.d.ts +1 -0
  105. package/src/runs/background/chain-root-attachment.d.ts.map +1 -1
  106. package/src/runs/background/chain-root-attachment.js +3 -3
  107. package/src/runs/background/chain-root-attachment.js.map +1 -1
  108. package/src/runs/background/control-channel.d.ts +4 -0
  109. package/src/runs/background/control-channel.d.ts.map +1 -1
  110. package/src/runs/background/control-channel.js +16 -1
  111. package/src/runs/background/control-channel.js.map +1 -1
  112. package/src/runs/background/notify.d.ts +3 -0
  113. package/src/runs/background/notify.d.ts.map +1 -1
  114. package/src/runs/background/notify.js +3 -0
  115. package/src/runs/background/notify.js.map +1 -1
  116. package/src/runs/background/run-child-session.d.ts.map +1 -1
  117. package/src/runs/background/run-child-session.js +4 -1
  118. package/src/runs/background/run-child-session.js.map +1 -1
  119. package/src/runs/background/run-status.d.ts.map +1 -1
  120. package/src/runs/background/run-status.js +6 -0
  121. package/src/runs/background/run-status.js.map +1 -1
  122. package/src/runs/background/runner-child-launch.d.ts +1 -0
  123. package/src/runs/background/runner-child-launch.d.ts.map +1 -1
  124. package/src/runs/background/runner-child-launch.js +2 -0
  125. package/src/runs/background/runner-child-launch.js.map +1 -1
  126. package/src/runs/background/scheduled-runs.js +5 -5
  127. package/src/runs/background/scheduled-runs.js.map +1 -1
  128. package/src/runs/background/subagent-runner.d.ts +3 -0
  129. package/src/runs/background/subagent-runner.d.ts.map +1 -1
  130. package/src/runs/background/subagent-runner.js +13 -1
  131. package/src/runs/background/subagent-runner.js.map +1 -1
  132. package/src/runs/foreground/async-stop-action.d.ts.map +1 -1
  133. package/src/runs/foreground/async-stop-action.js +19 -3
  134. package/src/runs/foreground/async-stop-action.js.map +1 -1
  135. package/src/runs/foreground/execution.d.ts.map +1 -1
  136. package/src/runs/foreground/execution.js +8 -1
  137. package/src/runs/foreground/execution.js.map +1 -1
  138. package/src/runs/foreground/subagent-executor.d.ts +6 -5
  139. package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  140. package/src/runs/foreground/subagent-executor.js +293 -182
  141. package/src/runs/foreground/subagent-executor.js.map +1 -1
  142. package/src/runs/shared/child-launch.d.ts +5 -1
  143. package/src/runs/shared/child-launch.d.ts.map +1 -1
  144. package/src/runs/shared/child-launch.js +15 -1
  145. package/src/runs/shared/child-launch.js.map +1 -1
  146. package/src/runs/shared/child-session.d.ts +9 -0
  147. package/src/runs/shared/child-session.d.ts.map +1 -1
  148. package/src/runs/shared/child-session.js +90 -4
  149. package/src/runs/shared/child-session.js.map +1 -1
  150. package/src/runs/shared/child-tool-plan.d.ts +4 -0
  151. package/src/runs/shared/child-tool-plan.d.ts.map +1 -1
  152. package/src/runs/shared/child-tool-plan.js +11 -4
  153. package/src/runs/shared/child-tool-plan.js.map +1 -1
  154. package/src/runs/shared/dynamic-fanout.js +1 -1
  155. package/src/runs/shared/dynamic-fanout.js.map +1 -1
  156. package/src/runs/shared/mcp-config-sources.d.ts +1 -0
  157. package/src/runs/shared/mcp-config-sources.d.ts.map +1 -1
  158. package/src/runs/shared/mcp-config-sources.js +1 -1
  159. package/src/runs/shared/mcp-config-sources.js.map +1 -1
  160. package/src/runs/shared/mcp-direct-tool-allowlist.d.ts +28 -0
  161. package/src/runs/shared/mcp-direct-tool-allowlist.d.ts.map +1 -1
  162. package/src/runs/shared/mcp-direct-tool-allowlist.js +78 -2
  163. package/src/runs/shared/mcp-direct-tool-allowlist.js.map +1 -1
  164. package/src/runs/shared/model-resolution.d.ts +10 -0
  165. package/src/runs/shared/model-resolution.d.ts.map +1 -1
  166. package/src/runs/shared/model-resolution.js +30 -9
  167. package/src/runs/shared/model-resolution.js.map +1 -1
  168. package/src/runs/shared/model-scope.d.ts +2 -1
  169. package/src/runs/shared/model-scope.d.ts.map +1 -1
  170. package/src/runs/shared/model-scope.js +26 -10
  171. package/src/runs/shared/model-scope.js.map +1 -1
  172. package/src/runs/shared/parallel-utils.d.ts +2 -0
  173. package/src/runs/shared/parallel-utils.d.ts.map +1 -1
  174. package/src/runs/shared/parallel-utils.js.map +1 -1
  175. package/src/runs/shared/pi-spawn.d.ts +1 -10
  176. package/src/runs/shared/pi-spawn.d.ts.map +1 -1
  177. package/src/runs/shared/pi-spawn.js +7 -86
  178. package/src/runs/shared/pi-spawn.js.map +1 -1
  179. package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
  180. package/src/runs/shared/subagent-prompt-runtime.js +2 -0
  181. package/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
  182. package/src/runs/shared/worktree.d.ts +1 -1
  183. package/src/runs/shared/worktree.d.ts.map +1 -1
  184. package/src/runs/shared/worktree.js +1 -1
  185. package/src/runs/shared/worktree.js.map +1 -1
  186. package/src/shared/disabled-features.d.ts +92 -0
  187. package/src/shared/disabled-features.d.ts.map +1 -0
  188. package/src/shared/disabled-features.js +113 -0
  189. package/src/shared/disabled-features.js.map +1 -0
  190. package/src/shared/extension-context.d.ts +9 -0
  191. package/src/shared/extension-context.d.ts.map +1 -1
  192. package/src/shared/extension-context.js +7 -0
  193. package/src/shared/extension-context.js.map +1 -1
  194. package/src/shared/settings.d.ts +1 -1
  195. package/src/shared/types.d.ts +20 -0
  196. package/src/shared/types.d.ts.map +1 -1
  197. package/src/shared/types.js.map +1 -1
  198. package/src/slash/prompt-template-bridge.js +2 -2
  199. package/src/slash/prompt-template-bridge.js.map +1 -1
  200. package/src/slash/slash-commands.d.ts +2 -0
  201. package/src/slash/slash-commands.d.ts.map +1 -1
  202. package/src/slash/slash-commands.js +2 -2
  203. package/src/slash/slash-commands.js.map +1 -1
  204. package/src/tui/render.d.ts.map +1 -1
  205. package/src/tui/render.js +55 -17
  206. package/src/tui/render.js.map +1 -1
  207. package/src/watchdog/diff-tool.d.ts +3 -1
  208. package/src/watchdog/diff-tool.d.ts.map +1 -1
  209. package/src/watchdog/diff-tool.js +20 -11
  210. package/src/watchdog/diff-tool.js.map +1 -1
  211. package/src/watchdog/register-child.js +2 -2
  212. package/src/watchdog/register-child.js.map +1 -1
  213. package/src/watchdog/register-main.js +2 -2
  214. package/src/watchdog/register-main.js.map +1 -1
  215. package/src/watchdog/review.d.ts +1 -1
  216. package/src/watchdog/review.d.ts.map +1 -1
  217. package/src/watchdog/review.js +1 -1
  218. package/src/watchdog/review.js.map +1 -1
  219. package/src/watchdog/turn-delta.js +1 -1
  220. package/src/watchdog/turn-delta.js.map +1 -1
  221. package/src/workflows/chat-progress.js +2 -2
  222. package/src/workflows/chat-progress.js.map +1 -1
  223. package/src/workflows/scripted-workflow.d.ts +8 -0
  224. package/src/workflows/scripted-workflow.d.ts.map +1 -1
  225. package/src/workflows/scripted-workflow.js +10 -2
  226. package/src/workflows/scripted-workflow.js.map +1 -1
  227. package/src/workflows/structured-workflow-scripts.d.ts +10 -0
  228. package/src/workflows/structured-workflow-scripts.d.ts.map +1 -0
  229. package/src/workflows/structured-workflow-scripts.js +166 -0
  230. package/src/workflows/structured-workflow-scripts.js.map +1 -0
  231. package/src/workflows/workflow-receipt.d.ts.map +1 -1
  232. package/src/workflows/workflow-receipt.js +8 -2
  233. package/src/workflows/workflow-receipt.js.map +1 -1
  234. package/src/workflows/workflow-resources.d.ts +9 -0
  235. package/src/workflows/workflow-resources.d.ts.map +1 -1
  236. package/src/workflows/workflow-resources.js +39 -12
  237. package/src/workflows/workflow-resources.js.map +1 -1
  238. package/src/workflows/workflow-reuse.d.ts +51 -0
  239. package/src/workflows/workflow-reuse.d.ts.map +1 -0
  240. package/src/workflows/workflow-reuse.js +103 -0
  241. package/src/workflows/workflow-reuse.js.map +1 -0
  242. package/src/workflows/workflow-revival.d.ts +32 -0
  243. package/src/workflows/workflow-revival.d.ts.map +1 -0
  244. package/src/workflows/workflow-revival.js +111 -0
  245. package/src/workflows/workflow-revival.js.map +1 -0
@@ -9,7 +9,7 @@ Agent files can live in:
9
9
  - `.pi/agents/**/*.md` — canonical project scope
10
10
  - legacy `.agents/**/*.md` — still read for compatibility, but `.pi/agents/` wins on conflicts
11
11
 
12
- Saved chain files may still be discovered for management and existing durable run state, but they are not a public execution surface. Author new orchestration with `workflowScript`.
12
+ Saved chain files may still be discovered for management and existing durable run state, but they are not a public execution surface. Author new orchestration as a workflow script.
13
13
 
14
14
  Precedence is by parsed runtime name:
15
15
  1. project scope
@@ -45,16 +45,16 @@ subagent({
45
45
 
46
46
  Use direct single-agent execution for one bounded task when no stable key,
47
47
  branching, retained-child lookup, or aggregate workflow result is needed. Use a
48
- `workflowScript` when the parent needs JavaScript control flow or data-dependent
48
+ workflow script when the parent needs JavaScript control flow or data-dependent
49
49
  branching, or when the run is part of a larger coordinated wave or a later step
50
50
  must resume it by key.
51
51
 
52
52
  ### Forked context
53
53
 
54
- ```typescript
55
- subagent({
56
- workflowScript: `return runs.run("oracle-check", { agent: "oracle", task: "Review my current direction and challenge assumptions.", context: "fork" })`
57
- })
54
+ Write this block in the reply, then call `subagent({ workflow: true })` (see [Scripted workflows](#scripted-workflows)):
55
+
56
+ ```js workflow
57
+ return runs.run("oracle-check", { agent: "oracle", task: "Review my current direction and challenge assumptions.", context: "fork" });
58
58
  ```
59
59
 
60
60
  `context: "fork"` creates a branched child session from the current persisted
@@ -68,7 +68,7 @@ its resolved launch context as `[fresh]` or `[fork]`. Aggregate headers show
68
68
 
69
69
  ### Scripted workflows
70
70
 
71
- `workflowScript` is the public composition surface when the parent needs
71
+ A workflow script is the public composition surface when the parent needs
72
72
  JavaScript control flow or data-dependent branching. Use
73
73
  `runs.run(key, { agent, task, ... })` for keyed children, `runs.all([...])` for
74
74
  parallel children, and ordinary JavaScript for sequence, filtering, retries,
@@ -80,17 +80,25 @@ workflow whenever the parent is starting a coordinated wave, such as multiple
80
80
  reviews, review plus gate monitor, worker then monitor setup, cross-repo prep
81
81
  lanes, or a fanout that the parent will consume together.
82
82
 
83
+ Write the script as one ```` ```js workflow ```` fenced block in the reply, then
84
+ call `subagent({ workflow: true, ... })` in the same reply. The block is plain
85
+ text, so it needs no JSON string escaping; a line containing only ```` ``` ````
86
+ (three or more backticks) ends it. A reply carries one block and one
87
+ `workflow: true` call. Use `workflow: "./path/to/script.js"` for a script file.
88
+ Later examples that show only a ```` ```js workflow ```` block run with
89
+ `subagent({ workflow: true })`.
90
+
91
+ ```js workflow
92
+ const scan = await runs.run("scan", { label: "Map target behavior", agent: "scout", task: "Map the target" });
93
+ const reviews = await runs.all([
94
+ { key: "correctness", label: "Review target correctness", agent: "reviewer", task: "Review correctness: " + scan.output },
95
+ { key: "tests", label: "Review target test coverage", agent: "reviewer", task: "Review tests: " + scan.output }
96
+ ]);
97
+ return reviews.map(result => result.output);
98
+ ```
99
+
83
100
  ```js
84
- subagent({
85
- workflowScript: `
86
- const scan = await runs.run("scan", { label: "Map target behavior", agent: "scout", task: "Map the target" });
87
- const reviews = await runs.all([
88
- { key: "correctness", label: "Review target correctness", agent: "reviewer", task: "Review correctness: " + scan.output },
89
- { key: "tests", label: "Review target test coverage", agent: "reviewer", task: "Review tests: " + scan.output }
90
- ]);
91
- return reviews.map(result => result.output);
92
- `
93
- })
101
+ subagent({ workflow: true, async: true })
94
102
  ```
95
103
 
96
104
  Scripts run in a timed worker with only `runs.run`, `runs.all`, `runs.status`, `runs.ref/refs`, `emit`, captured `console`, and standard JavaScript. Pass explicit task text to `runs.run`. Mission-attached workflows also get `await state.get(key)` and `await state.set(key, value)` for durable JSON state shared across workflows on the same mission; `mission: false` workflows have no `state` global. Stable keys are required. Child launches follow ordinary single-agent execution controls. Give each child a distinct decision and output path when reports must outlive the workflow, then consume the aggregate workflow result before opening individual reports. Do not ask children to write `reports/...` or other repo-root scratch paths in task text.
@@ -103,7 +111,7 @@ For a typed post-run check, pass the object form `gate: { command, output: "json
103
111
 
104
112
  If omitted, acceptance is inferred from role, mode, and risk. Use `level: "checked"` for ordinary writer evidence and `level: "verified"` when the runtime should run explicit validation commands. Independent review is orthogonal: use `review: { required: true, agent: "reviewer" }`; reviewer/read-only calls omit `acceptance`. `review-required` means evidence passed but review is pending; `reviewed` means an independent review found no blockers. Never request `level: "reviewed"`; it is recognized only so preflight can return an actionable correction. Disable gates with `{ level: "none", reason: "..." }`; bare `"none"` is rejected and `false` is only a deprecated shorthand. Child-reported command success is evidence, not runtime verification.
105
113
 
106
- Completed workflow children from this parent session stay addressable as retained children. `subagent({ action: "children.list" })` lists up to the last 10 with run ids and reports each row as `resumable` or `not resumable` with a reason. This workflow-only roster is not an exhaustive list of direct native children. Resume only rows reported `resumable`. When the exact run id of an intended direct child is known, inspect it with `subagent({ action: "status", id: "<run-id>" })`; if status identifies the candidate, attempt `subagent({ action: "resume", id: "<run-id>", message: "..." })`. Resume performs the authoritative eligibility check and may reject the attempt. For a retained-child challenge, use `resume` instead of `steer` when the child is complete. Launch a same-role fallback challenge, labeled as fallback, only when no known candidate exists or resume rejects eligibility. A later workflow continues a resumable child with `runs.run(key, { resume: "<run-id>", task: "follow-up" })`. Inside `workflowScript`, awaiting that call waits for the revived child to finish and returns its completed output and new `runId`; top-level `{ action: "resume" }` remains detached. Pass explicit follow-up task text. Assign each returned child result back to the loop variable because every resume can return a new retained `runId`; always resume the latest returned id. `resume` and `agent` are mutually exclusive, the revived child keeps its stored agent/model/tool contract, and `gate` is rejected on retained resume items.
114
+ Completed workflow children from this parent session stay addressable as retained children. `subagent({ action: "children.list" })` lists up to the last 10 with run ids and reports each row as `resumable` or `not resumable` with a reason. This workflow-only roster is not an exhaustive list of direct native children. Resume only rows reported `resumable`. When the exact run id of an intended direct child is known, inspect it with `subagent({ action: "status", id: "<run-id>" })`; if status identifies the candidate, attempt `subagent({ action: "resume", id: "<run-id>", message: "..." })`. Resume performs the authoritative eligibility check and may reject the attempt. For a retained-child challenge, use `resume` instead of `steer` when the child is complete. Launch a same-role fallback challenge, labeled as fallback, only when no known candidate exists or resume rejects eligibility. A later workflow continues a resumable child with `runs.run(key, { resume: "<run-id>", task: "follow-up" })`. Inside a workflow script, awaiting that call waits for the revived child to finish and returns its completed output and new `runId`; top-level `{ action: "resume" }` remains detached. Pass explicit follow-up task text. Assign each returned child result back to the loop variable because every resume can return a new retained `runId`; always resume the latest returned id. `resume` and `agent` are mutually exclusive, the revived child keeps its stored agent/model/tool contract, and `gate` is rejected on retained resume items.
107
115
 
108
116
  Each workflow key identifies one result lane: use a new stable workflow key for every distinct retained resume pass; same-key calls are reused only when launch parameters are identical, and incompatible parameters are rejected.
109
117
 
@@ -122,7 +130,7 @@ Keyed resume reads that one exact receipt and revalidates the retained run at la
122
130
  ### Parallel sequential lanes
123
131
 
124
132
  For a broad plan with a known set of narrow, visible stages per lane, use
125
- `runs.lanes(...)` inside a `workflowScript`; it is a nested helper, not a
133
+ `runs.lanes(...)` inside a workflow script; it is a nested helper, not a
126
134
  top-level `subagent` mode. Give each lane and stage a stable key; give stage
127
135
  items a short verb + behavior `label`, preserving explicit user labels. The first
128
136
  stage from every lane is launched together, then later stages sequence per lane.
@@ -184,25 +192,26 @@ fleet. If `PI_SUBAGENT_WAIT_TOOL_ENABLED` disables blocking, direct waits return
184
192
  immediately, but headless `agent_end` auto-drain still surfaces provider,
185
193
  reconciliation, or timeout failures.
186
194
 
195
+ ```js workflow
196
+ return runs.run("main", { agent: "worker", task: "Run the full test suite" });
197
+ ```
198
+
187
199
  ```typescript
188
- subagent({
189
- workflowScript: `return runs.run("main", { agent: "worker", task: "Run the full test suite" })`,
190
- async: true
191
- })
200
+ subagent({ workflow: true, async: true })
192
201
  ```
193
202
 
194
- File-only output mode works for workflowScript child launches. Use relative child output paths for scratch reports so the runtime stores them under the run artifact directory and age-based cleanup can remove them. Use absolute paths only for user-approved durable destinations, such as session memory, a docs folder outside the repo, or a known handoff path. For cross-codebase waves, include the repo slug or lane key in each output path so reports from different repositories cannot collide.
203
+ File-only output mode works for workflow script child launches. Use relative child output paths for scratch reports so the runtime stores them under the run artifact directory and age-based cleanup can remove them. Use absolute paths only for user-approved durable destinations, such as session memory, a docs folder outside the repo, or a known handoff path. For cross-codebase waves, include the repo slug or lane key in each output path so reports from different repositories cannot collide.
195
204
 
196
205
  The `output` field is the API binding; a filename mentioned in task text is only instruction and does not override runtime routing. When a later workflow step or parent needs a durable file, set `output` on `runs.run`/`runs.all` and return the child’s `outputReference`, `outputPathMapping`, or `artifactPaths`; arbitrary literal strings returned by workflow JavaScript are not rewritten. Omitted child output may use a managed aggregate-derived sibling path.
197
206
 
198
207
  For review fanout where the parent continues a local audit:
199
208
 
209
+ ```js workflow
210
+ return runs.run("correctness", { agent: "reviewer", task: "Review the current diff for correctness issues. Do not edit files." });
211
+ ```
212
+
200
213
  ```typescript
201
- const run = subagent({
202
- workflowScript: `return runs.run("correctness", { agent: "reviewer", task: "Review the current diff for correctness issues. Do not edit files." })`,
203
- async: true,
204
- context: "fresh"
205
- })
214
+ const run = subagent({ workflow: true, async: true, context: "fresh" })
206
215
  // Continue local inspection, then later call status with the returned id.
207
216
  ```
208
217
 
@@ -265,11 +274,11 @@ A cooperating terminal runtime can register read-only external records through `
265
274
  Schedules are durable project records under `.pi/subagents/schedules/`. They are enabled by default; set `{ "scheduledRuns": { "enabled": false } }` in `~/.pi/agent/extensions/subagent/config.json` to disable them. Only schedule explicit work the user asked for. To keep schedules outside the project repository, set `{ "scheduledRuns": { "storeRoot": "~/.pi/subagent-schedules" } }` in the same config: `storeRoot` accepts an absolute path or a `~/`-prefixed path, and records land under `<storeRoot>/<sha256(path.resolve(cwd)) first 20 hex>/<scheduleId>/`.
266
275
 
267
276
  ```typescript
268
- // One-shot reviewer
269
- subagent({ action: "schedule.create", id: "evening-review", name: "Evening review", at: "+30m", workflowScript: "return runs.run('main', { agent: 'reviewer', task: 'Review the diff.' })" })
277
+ // One-shot reviewer, after a ```js workflow block with the script
278
+ subagent({ action: "schedule.create", id: "evening-review", name: "Evening review", at: "+30m", workflow: true })
270
279
 
271
- // Fixed recurring workflow
272
- subagent({ action: "schedule.create", id: "backlog", every: "6h", catchUp: "latest", workflowScript: "..." })
280
+ // Fixed recurring workflow from a script file
281
+ subagent({ action: "schedule.create", id: "backlog", every: "6h", catchUp: "latest", workflow: "./.pi/workflows/backlog.js" })
273
282
 
274
283
  subagent({ action: "schedule.list" })
275
284
  subagent({ action: "schedule.show", id: "backlog" })
@@ -281,7 +290,7 @@ subagent({ action: "schedule.run-due" })
281
290
  subagent({ action: "schedule.delete", id: "backlog" })
282
291
  ```
283
292
 
284
- `schedule.create` accepts exactly one target, `workflowScript`, and exactly one trigger (`at`, or a fixed `every` interval using `m`, `h`, `d`, or `w`). Runs always launch async with fresh context and no automatic mission; mission attachment is deferred from this first slice. `overlap` is currently `skip`; `catchUp` supports `latest` and `none`. `schedule.run-due` is the headless external-launcher seam. Calendar recurrence, cron, and the schedule inspector are deferred from this first safe slice. Definitions, bounded history, append-only events, and per-run receipts remain project-scoped across Pi sessions.
293
+ `schedule.create` accepts exactly one target, a workflow script (`workflow: true` or a script path; the script text is stored at creation), and exactly one trigger (`at`, or a fixed `every` interval using `m`, `h`, `d`, or `w`). Runs always launch async with fresh context and no automatic mission; mission attachment is deferred from this first slice. `overlap` is currently `skip`; `catchUp` supports `latest` and `none`. `schedule.run-due` is the headless external-launcher seam. Calendar recurrence, cron, and the schedule inspector are deferred from this first safe slice. Definitions, bounded history, append-only events, and per-run receipts remain project-scoped across Pi sessions.
285
294
 
286
295
  Humans can use `/subagents-doctor` for the same read-only report. It checks runtime paths, discovery counts, async support, current session context, and intercom bridge state.
287
296
 
@@ -308,17 +317,15 @@ A soft interrupt cancels the current child turn and leaves the run paused. It do
308
317
 
309
318
  Per-run control thresholds can be overridden when a task legitimately runs without observable output for longer than usual:
310
319
 
311
- ```typescript
312
- subagent({
313
- workflowScript: `return runs.run("slow-tests", {
314
- agent: "worker",
315
- task: "Run the slow migration test suite",
316
- control: {
317
- needsAttentionAfterMs: 300000,
318
- notifyOn: ["needs_attention"]
319
- }
320
- })`
321
- })
320
+ ```js workflow
321
+ return runs.run("slow-tests", {
322
+ agent: "worker",
323
+ task: "Run the slow migration test suite",
324
+ control: {
325
+ needsAttentionAfterMs: 300000,
326
+ notifyOn: ["needs_attention"]
327
+ }
328
+ });
322
329
  ```
323
330
 
324
331
  If the run already has an active intercom bridge target, needs-attention notifications can also prepare a compact intercom ping for the orchestrator. When a child route is available, the ping tells the orchestrator which agent needs attention and includes the exact `intercom({ action: "send", to: "..." })` target for a nudge. Do not invent a target or ask the child to self-report when no bridge exists.
@@ -400,7 +407,7 @@ Use `mission.update` while work runs to record decisions, artifacts, labels, sum
400
407
 
401
408
  ### Mission use policy
402
409
 
403
- - **Keep the default.** Every ordinary `workflowScript` launch with a task creates one enclosing mission automatically. All workflow children share it and never get their own. Do not add `mission: {...}` boilerplate. Pass it only to set the title, objective, labels, or to enable `goal` with `budget`.
410
+ - **Keep the default.** Every ordinary workflow script launch with a task creates one enclosing mission automatically. All workflow children share it and never get their own. Do not add `mission: {...}` boilerplate. Pass it only to set the title, objective, labels, or to enable `goal` with `budget`.
404
411
  - **Use `mission: false` for noise.** Use it for trivial one-shot lookups, scouts, disposable probes, and quick validation where a recovery record is noise. It removes the mission and the `state` global for the whole workflow, so do not use it for monitors or multi-workflow loops that coordinate through `state`. Scheduled runs already launch without automatic missions.
405
412
  - **Use `missionId` for follow-up work.** Attach later work to an existing objective with `missionId`; attachment re-marks the mission active. `missionId` and `mission` are mutually exclusive. Explicit attachment fails before launch if the mission is missing, while automatic missions degrade to `details.missionWarning` without blocking the run.
406
413
  - **Keep `state` small.** Mission `state` is JSON coordination across workflows on the same mission. Keys use the same format as run keys, values must be JSON, and the whole state file is capped at 256 KiB. Each `set` merges one key under a file lock. Put large content in artifact files and store paths in state. In goal missions, write `state.set("nextReadyAction", "...")` so the next idle-turn notice names the exact ready step.
@@ -413,15 +420,15 @@ After compaction, restart, or confusing history, recover from durable state firs
413
420
  Routing rule:
414
421
  - Same project: ordinary mission-backed subagents.
415
422
  - Different project, small/bounded task: ordinary async subagent with explicit `cwd`, an authority boundary, and durable output.
416
- - Several projects with independent work: one async `workflowScript` whose child keys include repo slugs and whose child calls set explicit `cwd`; keep publication and merge decisions serial per repo.
423
+ - Several projects with independent work: one async workflow script whose child keys include repo slugs and whose child calls set explicit `cwd`; keep publication and merge decisions serial per repo.
417
424
  - Different project, substantial or long-running work: open a project-owned Herdr pane rooted there when a separate visible project session is useful, then give that project Pi session a narrow mission/result contract. Do not model it as ordinary child nesting, and do not expect existing headless runs to move into the pane.
418
425
 
419
426
  Project panes run a separate Pi session from the target directory. Subagents launched inside that pane use that project's config, agents, skills, files, git state, and mission records. The pane binding lives under `<projectRoot>/.pi/subagents/project-panes/herdr.json`. When Pi runs inside Herdr, the owning pane reports compact active-work status and title suffixes, and the parent inline status counts opened project panes. Use Herdr itself or `project.status` / `project.close` for pane-level follow-up. For ordinary headless delegation to another repo, prefer explicit `cwd` first; reserve project panes for visible or persistent project ownership.
420
427
 
421
428
  ```typescript
422
429
  subagent({ action: "mission.create", mission: { title: "Ship auth refresh", objective: "Implement and validate refresh handling" } })
423
- subagent({ workflowScript: `return runs.run("main", { agent: "worker", task: "Implement the approved plan" })`, missionId: "<mission-id>" })
424
- subagent({ workflowScript: `return runs.run("main", { agent: "scout", task: "Quickly answer whether this file exists" })`, mission: false })
430
+ subagent({ workflow: true, missionId: "<mission-id>" }) // after a ```js workflow block
431
+ subagent({ workflow: true, mission: false }) // after a ```js workflow block
425
432
  subagent({ action: "mission.list", missionScope: "global" })
426
433
  subagent({ action: "mission.resolve-decision", missionId: "<mission-id>", id: "<decision-id>", summary: "Settled: ship the v2 API; no schema freeze needed." })
427
434
  subagent({ action: "project.open", cwd: "/path/to/other-repo", message: "Own this mission for the project and report back with receipts." })
@@ -435,16 +442,12 @@ subagent({ action: "mission.close", missionId: "<mission-id>", missionStatus: "c
435
442
  When multiple agents might write concurrently, use worktrees instead of letting
436
443
  them share one filesystem view.
437
444
 
438
- ```typescript
439
- subagent({
440
- workflowScript: `
441
- const results = await runs.all([
442
- { key: "feature-a", agent: "worker", task: "Implement feature A", worktree: true },
443
- { key: "feature-b", agent: "worker", task: "Implement feature B", worktree: true }
444
- ]);
445
- return results.map(({ key, artifactPaths }) => ({ key, artifactPaths }));
446
- `
447
- })
445
+ ```js workflow
446
+ const results = await runs.all([
447
+ { key: "feature-a", agent: "worker", task: "Implement feature A", worktree: true },
448
+ { key: "feature-b", agent: "worker", task: "Implement feature B", worktree: true }
449
+ ]);
450
+ return results.map(({ key, artifactPaths }) => ({ key, artifactPaths }));
448
451
  ```
449
452
 
450
453
  `worktree: true` on a `runs.run` / `runs.all` item gives that child its own git
@@ -487,16 +490,14 @@ The intended oracle loop is:
487
490
  4. the main agent decides what direction to approve
488
491
  5. only then should `worker` implement
489
492
 
490
- ```typescript
493
+ ```js workflow
491
494
  // Advisory review in a branched thread. Oracle defaults to forked context.
492
- subagent({
493
- workflowScript: `return runs.run("oracle-check", { agent: "oracle", task: "Review my current direction, challenge assumptions, and propose the best next move." })`
494
- })
495
+ return runs.run("oracle-check", { agent: "oracle", task: "Review my current direction, challenge assumptions, and propose the best next move." });
496
+ ```
495
497
 
496
- // Implementation only after explicit approval. Worker defaults to fresh context.
497
- subagent({
498
- workflowScript: `return runs.run("implementation", { agent: "worker", task: "Implement the approved approach: ..." })`
499
- })
498
+ ```js workflow
499
+ // Implementation only after explicit approval, in a later reply. Worker defaults to fresh context.
500
+ return runs.run("implementation", { agent: "worker", task: "Implement the approved approach: ..." });
500
501
  ```
501
502
 
502
503
  `oracle` is not a fresh-context reviewer in the Cognition article sense. It is
@@ -85,7 +85,7 @@ subagent({ action: "reset", agent: "reviewer" })
85
85
  Use management actions when the system needs to create or edit subagents on
86
86
  demand without dropping into raw file editing.
87
87
 
88
- Management actions create or update user/project agent files. `config.name` is the local frontmatter name; optional `config.package` registers and looks up the runtime name as `{package}.{name}`. Use the dotted runtime name for `get`, `update`, `delete`, slash commands, and scripted workflow steps. For small agent changes such as a model swap, prefer `subagents.agentOverrides` in settings. Durable `.chain.md` definitions are legacy records, not a current authoring target; use `workflowScript` or `/prompt-workflow` for repeatable orchestration.
88
+ Management actions create or update user/project agent files. `config.name` is the local frontmatter name; optional `config.package` registers and looks up the runtime name as `{package}.{name}`. Use the dotted runtime name for `get`, `update`, `delete`, slash commands, and scripted workflow steps. For small agent changes such as a model swap, prefer `subagents.agentOverrides` in settings. Durable `.chain.md` definitions are legacy records, not a current authoring target; use a workflow script file (`workflow: "./path.js"`) or `/prompt-workflow` for repeatable orchestration.
89
89
 
90
90
  ## Creating and Editing Agents by File
91
91
 
@@ -158,4 +158,4 @@ Additional user prompt templates can delegate into `pi-subagents` through the na
158
158
 
159
159
  Other Pi extensions can call `pi-subagents` through the in-process event bus. The RPC channels are `subagents:rpc:v1:ready`, `subagents:rpc:v1:request`, and per-request replies at `subagents:rpc:v1:reply:<requestId>`. Envelopes use `{ version: 1, requestId, method, params }`, and replies use `{ version: 1, requestId, success, data | error }`. `ping` advertises the exact process-local async completion event as `events.asyncComplete` for RPC-spawn consumers.
160
160
 
161
- Methods: `ping`, `status`, `manage`, `spawn`, `steer`, `interrupt`, `resume`, `stop`, and `cost`. `ping` capability metadata advertises optional projections: `capabilities.fleetStatus: { version: 1 }` adds bounded current-session `data.fleet` records (opaque reconciliation `key`, resolved `agent`, optional `role`, `model`, `effort`, caller-facing `goal`, `startedAt`, split `{ input, output, total }` tokens, plus `totalActive`/`omitted` overflow counts) to successful `status` replies; `capabilities.launchResolvedExtensions` advertises parent-resolved opaque launch-extension identifiers in status details; `capabilities.runtimeAcknowledgedExtensions` advertises the best-effort child-runtime acknowledgement projection fed by cooperating extensions emitting `subagent:acknowledge-extension`; `capabilities.cost: { version: 1 }` advertises parent-plus-child accounting as data. Foreground `details.results[]` rows carry a stable numeric `index`; correlate children by `(runId, index)` rather than row position. Consumers should read status/result artifacts and RPC projections instead of scraping terminal output and must ignore unknown fields. `spawn` accepts either `{ agent, task? }`, an inline `workflowScript`, or `workflowScriptPath`; it is async-only and rejects management actions, `async: false`, or `clarify: true`. It reuses the normal executor, so discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status are shared with the `subagent` tool. `manage` accepts only the schedule actions advertised by `ping.capabilities.managementActions`. `status`, acknowledged async `steer`, and `interrupt` map to the normal control actions. RPC steer disables pause-and-revive recovery and advertises `capabilities.nonRecoveringSteer`, preserving the caller's authority over the exact spawned child. `resume` requires a target plus non-empty message and delegates to the package-owned revival path; it may set a caller-owned `file-only` output path but cannot override the persisted child model, tools, budgets, session ownership, or exclusive session lease. For retained-child workflows, resume only roster rows reported `resumable`; because that workflow-only roster is not exhaustive, inspect the exact status of a known direct-run candidate and attempt the authoritative resume when status identifies it. Start a labeled same-role fallback only when there is no known candidate or resume rejects eligibility. `stop` targets running async runs through the existing timeout control channel. `pi.events` is process-local, so separate Pi processes and child subagents need lifecycle artifact files or `pi-intercom` instead.
161
+ Methods: `ping`, `status`, `manage`, `spawn`, `steer`, `interrupt`, `resume`, `stop`, and `cost`. `ping` capability metadata advertises optional projections: `capabilities.fleetStatus: { version: 1 }` adds bounded current-session `data.fleet` records (opaque reconciliation `key`, resolved `agent`, optional `role`, `model`, `effort`, caller-facing `goal`, `startedAt`, split `{ input, output, total }` tokens, plus `totalActive`/`omitted` overflow counts) to successful `status` replies; `capabilities.launchResolvedExtensions` advertises parent-resolved opaque launch-extension identifiers in status details; `capabilities.runtimeAcknowledgedExtensions` advertises the best-effort child-runtime acknowledgement projection fed by cooperating extensions emitting `subagent:acknowledge-extension`; `capabilities.cost: { version: 1 }` advertises parent-plus-child accounting as data. Foreground `details.results[]` rows carry a stable numeric `index`; correlate children by `(runId, index)` rather than row position. Consumers should read status/result artifacts and RPC projections instead of scraping terminal output and must ignore unknown fields. `spawn` accepts either `{ agent, task? }`, inline script text as `script`, or `workflow` with a script path (containing `/`) or a named workflow resource; `workflow: true` is rejected because RPC has no assistant reply to read. It is async-only and rejects management actions, `async: false`, or `clarify: true`. It reuses the normal executor, so discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status are shared with the `subagent` tool. `manage` accepts only the schedule actions advertised by `ping.capabilities.managementActions`. `status`, acknowledged async `steer`, and `interrupt` map to the normal control actions. RPC steer disables pause-and-revive recovery and advertises `capabilities.nonRecoveringSteer`, preserving the caller's authority over the exact spawned child. `resume` requires a target plus non-empty message and delegates to the package-owned revival path; it may set a caller-owned `file-only` output path but cannot override the persisted child model, tools, budgets, session ownership, or exclusive session lease. For retained-child workflows, resume only roster rows reported `resumable`; because that workflow-only roster is not exhaustive, inspect the exact status of a known direct-run candidate and attempt the authoritative resume when status identifies it. Start a labeled same-role fallback only when there is no known candidate or resume rejects eligibility. `stop` targets running async runs through the existing timeout control channel. `pi.events` is process-local, so separate Pi processes and child subagents need lifecycle artifact files or `pi-intercom` instead.
@@ -34,7 +34,7 @@ Partition fanout by repository, source seam, decision, or review angle. Each run
34
34
 
35
35
  Every child packet must stand alone: include the goal, exact repository/cwd/ref, authority and edit boundary, relevant context/evidence, success criteria, validation, expected output, and stop/escalation rules. Do not rely on parent history, an issue number, or a broad glob alone. An orchestration audit by a top-reasoning critic model is read-only and returns at most three cited omissions; use high thinking only as an explicit parent/user escalation, never as an autonomous root or a parallel placeholder.
36
36
 
37
- Use one async `workflowScript` for a coordinated wave. Use `runs.all` for independent lanes and `runs.run` for dependent lane stages. Give cross-repository runs explicit `cwd` values and lane-qualified outputs. Use `outputMode: "file-only"` when a report must survive the run or feed a later stage. Keep scratch outputs relative so they live under subagent artifacts; use absolute paths only for durable memory, approved docs paths, or final handoff files.
37
+ Use one async workflow script (`subagent({ workflow: true, async: true })` after a ```` ```js workflow ```` block) for a coordinated wave. Use `runs.all` for independent lanes and `runs.run` for dependent lane stages. Give cross-repository runs explicit `cwd` values and lane-qualified outputs. Use `outputMode: "file-only"` when a report must survive the run or feed a later stage. Keep scratch outputs relative so they live under subagent artifacts; use absolute paths only for durable memory, approved docs paths, or final handoff files.
38
38
 
39
39
  ## Keep independent work moving
40
40
 
@@ -25,10 +25,10 @@ they do not authorize a launch.
25
25
 
26
26
  ## Tool vs Slash Commands
27
27
 
28
- Agents use the `subagent(...)` tool for execution, management, status, and control. Direct `{ agent, task }` execution is enough for one bounded child task; use `workflowScript` when the parent needs JavaScript control flow or data-dependent branching, keyed, parallel, sequential, retry, retained-resume, aggregate, or explicit staged-lane behavior (`runs.lanes`). Humans often use the slash-command layer instead:
28
+ Agents use the `subagent(...)` tool for execution, management, status, and control. Direct `{ agent, task }` execution is enough for one bounded child task; use a workflow script (one ```` ```js workflow ```` block in the reply plus `subagent({ workflow: true })`) when the parent needs JavaScript control flow or data-dependent branching, keyed, parallel, sequential, retry, retained-resume, aggregate, or explicit staged-lane behavior (`runs.lanes`). Humans often use the slash-command layer instead:
29
29
 
30
30
  - `/run` — launch a single agent
31
- - `workflowScript` — the sole public surface for sequence, parallelism, branching, retries, and aggregation
31
+ - `subagent({ workflow: ... })` — the workflow-script surface for sequence, parallelism, branching, retries, and aggregation; with `disabledFeatures: ["workflow-scripts"]`, top-level `chain` and `tasks` replace it (see [configuration](../../../docs/configuration.md#chain-and-tasks-without-workflow-scripts))
32
32
  - `/subagents` — interactive admin for inspecting agents and editing model, thinking, or system prompt
33
33
  - `/subagents-stop [run-id]` — stop a current-session top-level async run; opens a selector when no id is given
34
34
  - `/subagents-detach [run-id]` — detach an active foreground single-subagent run without terminating its child
@@ -39,7 +39,7 @@ Agents use the `subagent(...)` tool for execution, management, status, and contr
39
39
  - `/subagents-doctor` — diagnose setup, discovery, async paths, and intercom bridge state
40
40
  - `/subagents-models [agent]` — show the live runtime-loaded builtin model mapping
41
41
  - `/subagents-profiles`, `/subagents-load-profile`, `/subagents-refresh-provider-models`, `/subagents-generate-profiles`, `/subagents-check-profile` — manage model profiles and provider catalogs
42
- - `/prompt-workflow` — run a prompt template through native workflowScript execution
42
+ - `/prompt-workflow` — run a prompt template as a native workflow script
43
43
 
44
44
  Prefer the tool when you are writing agent logic. Prefer the slash commands when
45
45
  you are guiding a human through an interactive flow.
@@ -83,22 +83,21 @@ Default guardrails:
83
83
 
84
84
  Example shape:
85
85
 
86
+ ```js workflow
87
+ const results = await runs.all([
88
+ { key: "deslop", agent: "reviewer", task: "Apply the available 'deslop' skill to review the current diff for concrete cleanup findings only. Do not modify files.", skill: "deslop" },
89
+ { key: "accessibility", agent: "reviewer", task: "Apply the available 'accessibility' skill to review the UI changes for concrete issues only. Do not modify files.", skill: "accessibility" }
90
+ ]);
91
+ return results.map(result => result.output);
92
+ ```
93
+
86
94
  ```typescript
87
- subagent({
88
- workflowScript: `
89
- const results = await runs.all([
90
- { key: "deslop", agent: "reviewer", task: "Apply the available 'deslop' skill to review the current diff for concrete cleanup findings only. Do not modify files.", skill: "deslop" },
91
- { key: "accessibility", agent: "reviewer", task: "Apply the available 'accessibility' skill to review the UI changes for concrete issues only. Do not modify files.", skill: "accessibility" }
92
- ]);
93
- return results.map(result => result.output);
94
- `,
95
- context: "fresh"
96
- })
95
+ subagent({ workflow: true, context: "fresh" })
97
96
  ```
98
97
 
99
98
  ### Review-loop technique
100
99
 
101
- Use this when the user wants implementation or current diff review to continue until reviewers stop finding fixes worth doing now. Keep the loop in the parent session: one async `worker` implements or fixes, fresh-context `reviewer` agents inspect the actual repo and diff, the parent synthesizes accepted fixes, and one async forked `worker` applies them. The parent can express the sequence up front as an async/background `workflowScript` when the workflow is known, or continue with explicit follow-up workflowScript runs after each async completion. For an initial workflow, pass `async: true` so the main chat is unblocked. Treat an async implementation worker handoff as an intermediate state, not final completion, unless the user explicitly asked for worker-only work, review-only output, or to stop after implementation. Stop when reviewers find no P0 blockers or P1 fixes worth doing now, remaining P2 feedback is optional or deferred, an unapproved product/scope/architecture decision appears, or the max review-round cap is reached. Default to 3 review rounds unless the user sets a different cap. Do not loop for optional polish, and do not let children launch subagents or decide the loop outcome.
100
+ Use this when the user wants implementation or current diff review to continue until reviewers stop finding fixes worth doing now. Keep the loop in the parent session: one async `worker` implements or fixes, fresh-context `reviewer` agents inspect the actual repo and diff, the parent synthesizes accepted fixes, and one async forked `worker` applies them. The parent can express the sequence up front as an async/background workflow script when the workflow is known, or continue with explicit follow-up workflow script runs after each async completion. For an initial workflow, pass `async: true` so the main chat is unblocked. Treat an async implementation worker handoff as an intermediate state, not final completion, unless the user explicitly asked for worker-only work, review-only output, or to stop after implementation. Stop when reviewers find no P0 blockers or P1 fixes worth doing now, remaining P2 feedback is optional or deferred, an unapproved product/scope/architecture decision appears, or the max review-round cap is reached. Default to 3 review rounds unless the user sets a different cap. Do not loop for optional polish, and do not let children launch subagents or decide the loop outcome.
102
101
 
103
102
  As a conservative orchestration policy, do not pass a hard `toolBudget` to an implementation worker, fix worker, reviewer with edit authority, or other mutation-capable child. The default tool budget blocks read/search tools rather than mutation tools, but count limits still do not measure delivery safety. Use a narrow task plus an outer elapsed deadline with enough margin, then request a checkpoint after the current tool returns. The checkpoint should report changed files, build/test state, remaining work, and commit or PR state. An elapsed timeout is not a mutation-safe boundary and must not be used as the checkpoint trigger.
104
103
 
@@ -118,10 +117,10 @@ Use this after implementation when the user or applicable instructions request d
118
117
 
119
118
  ### Staged fix orchestration technique
120
119
 
121
- Use this when a broad diff has known reviewer findings across several items and the user wants the parent to “orchestrate subagents like a boss.” Keep mutation ownership explicit in the `workflowScript`:
120
+ Use this when a broad diff has known reviewer findings across several items and the user wants the parent to “orchestrate subagents like a boss.” Keep mutation ownership explicit in the workflow script:
122
121
 
123
122
  When staged seams are available, a low-tier writer should not receive the
124
- end-to-end issue. Use `runs.lanes` inside `workflowScript` to keep stages narrow:
123
+ end-to-end issue. Use `runs.lanes` inside the workflow script to keep stages narrow:
125
124
  a scout/red test, helper-only change, one render seam, validation, minimality
126
125
  challenge, or fresh review. Give the writer only its assigned implementation
127
126
  stage; keep sequencing and synthesis with the parent.
@@ -137,39 +136,37 @@ When one child returns a structured target list, use ordinary JavaScript to vali
137
136
 
138
137
  Single-seam example shape (the lane board records that these are review angles on one tightly coupled deployment-lifecycle diff, not independent implementation contracts):
139
138
 
139
+ ```js workflow
140
+ // Stage 1: parallel read-only review angles on one recorded single seam
141
+ const plans = await runs.all([
142
+ { key: "correctness-plan", agent: "reviewer", phase: "Planning", label: "Review lifecycle correctness", task: "Plan correctness fixes for the same deployment-lifecycle diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/correctness.md", outputMode: "file-only" },
143
+ { key: "regression-plan", agent: "reviewer", phase: "Planning", label: "Review lifecycle regressions", task: "Plan regression coverage for the same deployment-lifecycle diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/regressions.md", outputMode: "file-only" },
144
+ { key: "minimality-plan", agent: "reviewer", phase: "Planning", label: "Review lifecycle minimality", task: "Plan minimality fixes for the same deployment-lifecycle diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/minimality.md", outputMode: "file-only" }
145
+ ]);
146
+
147
+ // Stage 2: one writer for this lane-board-recorded single seam.
148
+ // Under outputMode "file-only" the awaited .output is the saved-output
149
+ // reference, so pass those managed artifact references to the writer.
150
+ const worker = await runs.run("apply-fixes", {
151
+ agent: "worker",
152
+ phase: "Implementation",
153
+ label: "Apply accepted fixes",
154
+ task: "Apply only the accepted fixes to the one deployment-lifecycle seam. The lane board records that splitting this existing diff would create overlapping ownership. You are the sole writer for this seam. Run focused validation and report changed files, commands, failures, and remaining issues.\n\nCorrectness plan: " + plans[0].output + "\n\nRegression plan: " + plans[1].output + "\n\nMinimality plan: " + plans[2].output,
155
+ output: "worker/fixes.md",
156
+ outputMode: "file-only"
157
+ });
158
+
159
+ // Stage 3: parallel read-only validation fanout
160
+ const validations = await runs.all([
161
+ { key: "validate-behavior", agent: "reviewer", phase: "Validation", label: "Validate lifecycle behavior", task: "Validate behavior in the post-worker deployment-lifecycle diff. Start from the worker result: " + worker.output + ". Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "validation/behavior.md", outputMode: "file-only" },
162
+ { key: "validate-minimality", agent: "reviewer", phase: "Validation", label: "Validate lifecycle minimality", task: "Validate minimality in the same post-worker deployment-lifecycle diff. Start from the worker result: " + worker.output + ". Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "validation/minimality.md", outputMode: "file-only" }
163
+ ]);
164
+
165
+ return { worker: worker.output, validations: validations.map(v => v.output) };
166
+ ```
167
+
140
168
  ```typescript
141
- subagent({
142
- async: true,
143
- context: "fresh",
144
- workflowScript: `
145
- // Stage 1: parallel read-only review angles on one recorded single seam
146
- const plans = await runs.all([
147
- { key: "correctness-plan", agent: "reviewer", phase: "Planning", label: "Review lifecycle correctness", task: "Plan correctness fixes for the same deployment-lifecycle diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/correctness.md", outputMode: "file-only" },
148
- { key: "regression-plan", agent: "reviewer", phase: "Planning", label: "Review lifecycle regressions", task: "Plan regression coverage for the same deployment-lifecycle diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/regressions.md", outputMode: "file-only" },
149
- { key: "minimality-plan", agent: "reviewer", phase: "Planning", label: "Review lifecycle minimality", task: "Plan minimality fixes for the same deployment-lifecycle diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/minimality.md", outputMode: "file-only" }
150
- ]);
151
-
152
- // Stage 2: one writer for this lane-board-recorded single seam.
153
- // Under outputMode "file-only" the awaited .output is the saved-output
154
- // reference, so pass those managed artifact references to the writer.
155
- const worker = await runs.run("apply-fixes", {
156
- agent: "worker",
157
- phase: "Implementation",
158
- label: "Apply accepted fixes",
159
- task: "Apply only the accepted fixes to the one deployment-lifecycle seam. The lane board records that splitting this existing diff would create overlapping ownership. You are the sole writer for this seam. Run focused validation and report changed files, commands, failures, and remaining issues.\\n\\nCorrectness plan: " + plans[0].output + "\\n\\nRegression plan: " + plans[1].output + "\\n\\nMinimality plan: " + plans[2].output,
160
- output: "worker/fixes.md",
161
- outputMode: "file-only"
162
- });
163
-
164
- // Stage 3: parallel read-only validation fanout
165
- const validations = await runs.all([
166
- { key: "validate-behavior", agent: "reviewer", phase: "Validation", label: "Validate lifecycle behavior", task: "Validate behavior in the post-worker deployment-lifecycle diff. Start from the worker result: " + worker.output + ". Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "validation/behavior.md", outputMode: "file-only" },
167
- { key: "validate-minimality", agent: "reviewer", phase: "Validation", label: "Validate lifecycle minimality", task: "Validate minimality in the same post-worker deployment-lifecycle diff. Start from the worker result: " + worker.output + ". Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "validation/minimality.md", outputMode: "file-only" }
168
- ]);
169
-
170
- return { worker: worker.output, validations: validations.map(v => v.output) };
171
- `
172
- })
169
+ subagent({ workflow: true, async: true, context: "fresh" })
173
170
  ```
174
171
 
175
172
  ## Builtin Agents
@@ -1,8 +1,10 @@
1
1
  import type { ResolvedSubagentCapabilityCeiling } from "../runs/shared/capability-ceiling.ts";
2
2
  import type { AgentConfig } from "./agents.ts";
3
+ /**
4
+ * The catalog body without its `<advertised_subagents>` wrapper, for Pi's structured
5
+ * prompt sections, which add the tag from the section key. The byte budget applies to
6
+ * the wrapped form, so both deliveries carry the same entries.
7
+ */
8
+ export declare function buildAdvertisedAgentCatalog(agents: readonly AgentConfig[], capabilityCeiling?: ResolvedSubagentCapabilityCeiling): string | undefined;
3
9
  export declare function buildAdvertisedAgentPrompt(agents: readonly AgentConfig[], capabilityCeiling?: ResolvedSubagentCapabilityCeiling): string | undefined;
4
- export declare function appendAdvertisedAgentPrompt(systemPrompt: string, advertisedPrompt: string | undefined): string;
5
- export declare function appendAdvertisedAgentPrompt(systemPrompt: string[], advertisedPrompt: string | undefined): string[];
6
- export declare function appendAdvertisedAgentPrompt(systemPrompt: undefined, advertisedPrompt: string | undefined): string | undefined;
7
- export declare function appendAdvertisedAgentPrompt(systemPrompt: string | string[] | undefined, advertisedPrompt: string | undefined): string | string[] | undefined;
8
10
  //# sourceMappingURL=advertised-agent-prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"advertised-agent-prompt.d.ts","sourceRoot":"","sources":["../../../src/agents/advertised-agent-prompt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,sCAAsC,CAAC;AAE9F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAwB/C,wBAAgB,0BAA0B,CACzC,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,iBAAiB,CAAC,EAAE,iCAAiC,GACnD,MAAM,GAAG,SAAS,CA2BpB;AAED,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAChH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,gBAAgB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAAC;AACpH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAC/H,wBAAgB,2BAA2B,CAC1C,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,EAC3C,gBAAgB,EAAE,MAAM,GAAG,SAAS,GAClC,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC"}
1
+ {"version":3,"file":"advertised-agent-prompt.d.ts","sourceRoot":"","sources":["../../../src/agents/advertised-agent-prompt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,sCAAsC,CAAC;AAE9F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA6B/C;;;;GAIG;AACH,wBAAgB,2BAA2B,CAC1C,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,iBAAiB,CAAC,EAAE,iCAAiC,GACnD,MAAM,GAAG,SAAS,CAyBpB;AAED,wBAAgB,0BAA0B,CACzC,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,iBAAiB,CAAC,EAAE,iCAAiC,GACnD,MAAM,GAAG,SAAS,CAGpB"}
@@ -3,7 +3,6 @@ import { isAgentAllowedByCapabilityCeiling } from "../runs/shared/capability-cei
3
3
  const MAX_ADVERTISED_AGENTS = 16;
4
4
  const MAX_CATALOG_BYTES = 12_288;
5
5
  const MAX_DESCRIPTION_BYTES = 512;
6
- const ADVERTISED_AGENTS_BLOCK = /\n*<advertised_subagents>\n[\s\S]*?\n<\/advertised_subagents>/gu;
7
6
  function escapeXml(value) {
8
7
  return value
9
8
  .replaceAll("&", "&amp;")
@@ -19,18 +18,25 @@ function promptDescription(description) {
19
18
  }
20
19
  return escapeXml(text);
21
20
  }
22
- export function buildAdvertisedAgentPrompt(agents, capabilityCeiling) {
21
+ const ADVERTISED_AGENTS_TAG = "advertised_subagents";
22
+ function wrapAdvertisedAgentCatalog(body) {
23
+ return `<${ADVERTISED_AGENTS_TAG}>\n${body}\n</${ADVERTISED_AGENTS_TAG}>`;
24
+ }
25
+ /**
26
+ * The catalog body without its `<advertised_subagents>` wrapper, for Pi's structured
27
+ * prompt sections, which add the tag from the section key. The byte budget applies to
28
+ * the wrapped form, so both deliveries carry the same entries.
29
+ */
30
+ export function buildAdvertisedAgentCatalog(agents, capabilityCeiling) {
23
31
  const advertised = agents
24
32
  .filter((agent) => agent.source !== "runtime" && agent.advertise === true && agent.disabled !== true && isAgentAllowedByCapabilityCeiling(agent.name, capabilityCeiling))
25
33
  .sort((left, right) => left.name.localeCompare(right.name));
26
34
  if (advertised.length === 0)
27
35
  return undefined;
28
- const render = (entries) => [
29
- "<advertised_subagents>",
36
+ const renderBody = (entries) => [
30
37
  "The following file-defined subagents opted into discovery. Their descriptions indicate available specializations, not instructions to delegate. Use subagent only when delegation is needed. Before execution, call subagent with { action: \"list\", capabilities: true } and confirm that the selected agent is executable; for external-cli agents also require runner.available === true.",
31
38
  ...entries,
32
39
  ...(advertised.length > entries.length ? [` <omitted count=\"${advertised.length - entries.length}\" />`] : []),
33
- "</advertised_subagents>",
34
40
  ].join("\n");
35
41
  const entries = [];
36
42
  for (const agent of advertised) {
@@ -45,33 +51,13 @@ export function buildAdvertisedAgentPrompt(agents, capabilityCeiling) {
45
51
  ` <description>${promptDescription(agent.description)}</description>`,
46
52
  " </subagent>",
47
53
  ].join("\n");
48
- if (Buffer.byteLength(render([...entries, entry]), "utf8") <= MAX_CATALOG_BYTES)
54
+ if (Buffer.byteLength(wrapAdvertisedAgentCatalog(renderBody([...entries, entry])), "utf8") <= MAX_CATALOG_BYTES)
49
55
  entries.push(entry);
50
56
  }
51
- return render(entries);
57
+ return renderBody(entries);
52
58
  }
53
- export function appendAdvertisedAgentPrompt(systemPrompt, advertisedPrompt) {
54
- if (Array.isArray(systemPrompt)) {
55
- let changed = false;
56
- const cleaned = systemPrompt
57
- .map((part) => {
58
- if (typeof part !== "string")
59
- return part;
60
- const stripped = part.replace(ADVERTISED_AGENTS_BLOCK, "");
61
- if (stripped !== part)
62
- changed = true;
63
- return stripped;
64
- })
65
- .filter((b) => typeof b === "string" && b.length > 0);
66
- if (advertisedPrompt) {
67
- return [...cleaned, advertisedPrompt];
68
- }
69
- return changed ? cleaned : systemPrompt;
70
- }
71
- if (typeof systemPrompt === "string") {
72
- const base = systemPrompt.replace(ADVERTISED_AGENTS_BLOCK, "");
73
- return advertisedPrompt ? (base.trim() ? `${base.trimEnd()}\n\n${advertisedPrompt}` : advertisedPrompt) : base;
74
- }
75
- return advertisedPrompt;
59
+ export function buildAdvertisedAgentPrompt(agents, capabilityCeiling) {
60
+ const body = buildAdvertisedAgentCatalog(agents, capabilityCeiling);
61
+ return body === undefined ? undefined : wrapAdvertisedAgentCatalog(body);
76
62
  }
77
63
  //# sourceMappingURL=advertised-agent-prompt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"advertised-agent-prompt.js","sourceRoot":"","sources":["../../../src/agents/advertised-agent-prompt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"advertised-agent-prompt.js","sourceRoot":"","sources":["../../../src/agents/advertised-agent-prompt.ts"],"names":[],"mappings":"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"}
@@ -1217,7 +1217,7 @@ export function handleCreate(params, ctx) {
1217
1217
  return result("config.scope must be 'user' or 'project'.", true);
1218
1218
  const scope = scopeRaw;
1219
1219
  if (hasKey(cfg, "steps"))
1220
- return result("Durable chain definitions were removed; use workflowScript or /prompt-workflow for repeatable workflows.", true);
1220
+ return result("Durable chain definitions were removed; use a workflow script or /prompt-workflow for repeatable workflows.", true);
1221
1221
  const d = discoverCatalog(ctx);
1222
1222
  const projectConfigDir = getProjectConfigDir(ctx.cwd);
1223
1223
  const targetDir = scope === "user" ? d.userDir : d.projectDir ?? path.join(projectConfigDir, "agents");
@@ -1269,7 +1269,7 @@ export function handleUpdate(params, ctx) {
1269
1269
  return result("config required for update.", true);
1270
1270
  const cfg = parsedConfig.value;
1271
1271
  if (hasKey(cfg, "steps"))
1272
- return result("Durable chain definitions were removed; use workflowScript or /prompt-workflow for repeatable workflows.", true);
1272
+ return result("Durable chain definitions were removed; use a workflow script or /prompt-workflow for repeatable workflows.", true);
1273
1273
  const warnings = [];
1274
1274
  const scopeHint = asDisambiguationScope(params.agentScope);
1275
1275
  const targetOrError = resolveTarget(params.agent, findAgents(params.agent, ctx, scopeHint ?? "both"), ctx.cwd, ctx, scopeHint);