pi-subagents 0.70.1 → 0.72.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 (275) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/README.md +4 -2
  3. package/agents/worker.md +2 -2
  4. package/docs/agents.md +1 -1
  5. package/docs/configuration.md +18 -2
  6. package/docs/extension-api.md +67 -3
  7. package/docs/models.md +1 -1
  8. package/docs/observability.md +17 -13
  9. package/docs/tool-reference.md +14 -10
  10. package/docs/workflows.md +3 -1
  11. package/package.json +11 -4
  12. package/prompts/council.md +6 -3
  13. package/skills/pi-subagents/references/constraints-and-recipes.md +5 -2
  14. package/skills/pi-subagents/references/execution-controls.md +3 -3
  15. package/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
  16. package/src/agents/agent-management.d.ts +2 -1
  17. package/src/agents/agent-management.d.ts.map +1 -1
  18. package/src/agents/agent-management.js +32 -29
  19. package/src/agents/agent-management.js.map +1 -1
  20. package/src/agents/agents.d.ts +7 -3
  21. package/src/agents/agents.d.ts.map +1 -1
  22. package/src/agents/agents.js +16 -15
  23. package/src/agents/agents.js.map +1 -1
  24. package/src/agents/global-npm-root.d.ts +7 -0
  25. package/src/agents/global-npm-root.d.ts.map +1 -0
  26. package/src/agents/global-npm-root.js +58 -0
  27. package/src/agents/global-npm-root.js.map +1 -0
  28. package/src/agents/proactive-skills.d.ts +1 -0
  29. package/src/agents/proactive-skills.d.ts.map +1 -1
  30. package/src/agents/proactive-skills.js +3 -1
  31. package/src/agents/proactive-skills.js.map +1 -1
  32. package/src/agents/skills.d.ts +2 -0
  33. package/src/agents/skills.d.ts.map +1 -1
  34. package/src/agents/skills.js +41 -8
  35. package/src/agents/skills.js.map +1 -1
  36. package/src/api/delegation.d.ts +14 -0
  37. package/src/api/delegation.d.ts.map +1 -1
  38. package/src/api/inspectors.d.ts +21 -0
  39. package/src/api/inspectors.d.ts.map +1 -0
  40. package/src/api/inspectors.js +12 -0
  41. package/src/api/inspectors.js.map +1 -0
  42. package/src/extension/fanout-child.d.ts.map +1 -1
  43. package/src/extension/fanout-child.js +9 -0
  44. package/src/extension/fanout-child.js.map +1 -1
  45. package/src/extension/index.d.ts.map +1 -1
  46. package/src/extension/index.js +76 -29
  47. package/src/extension/index.js.map +1 -1
  48. package/src/extension/rpc.d.ts +1 -1
  49. package/src/extension/rpc.d.ts.map +1 -1
  50. package/src/extension/rpc.js +11 -1
  51. package/src/extension/rpc.js.map +1 -1
  52. package/src/extension/schemas.js +5 -5
  53. package/src/extension/schemas.js.map +1 -1
  54. package/src/extension/subagent-guide.d.ts +1 -1
  55. package/src/extension/subagent-guide.d.ts.map +1 -1
  56. package/src/extension/subagent-guide.js +11 -4
  57. package/src/extension/subagent-guide.js.map +1 -1
  58. package/src/extension/tool-activation.d.ts +9 -0
  59. package/src/extension/tool-activation.d.ts.map +1 -0
  60. package/src/extension/tool-activation.js +182 -0
  61. package/src/extension/tool-activation.js.map +1 -0
  62. package/src/extension/tool-description.d.ts +4 -4
  63. package/src/extension/tool-description.d.ts.map +1 -1
  64. package/src/extension/tool-description.js +1 -1
  65. package/src/inspectors/plugins.d.ts +7 -2
  66. package/src/inspectors/plugins.d.ts.map +1 -1
  67. package/src/inspectors/plugins.js +78 -3
  68. package/src/inspectors/plugins.js.map +1 -1
  69. package/src/intercom/intercom-bridge.d.ts.map +1 -1
  70. package/src/intercom/intercom-bridge.js +2 -0
  71. package/src/intercom/intercom-bridge.js.map +1 -1
  72. package/src/intercom/native-supervisor-channel.d.ts.map +1 -1
  73. package/src/intercom/native-supervisor-channel.js +3 -1
  74. package/src/intercom/native-supervisor-channel.js.map +1 -1
  75. package/src/runs/background/active-async-capacity.d.ts.map +1 -1
  76. package/src/runs/background/active-async-capacity.js +4 -33
  77. package/src/runs/background/active-async-capacity.js.map +1 -1
  78. package/src/runs/background/async-execution.d.ts.map +1 -1
  79. package/src/runs/background/async-execution.js +7 -33
  80. package/src/runs/background/async-execution.js.map +1 -1
  81. package/src/runs/background/async-job-tracker.d.ts.map +1 -1
  82. package/src/runs/background/async-job-tracker.js +26 -39
  83. package/src/runs/background/async-job-tracker.js.map +1 -1
  84. package/src/runs/background/async-resume.d.ts +1 -1
  85. package/src/runs/background/async-resume.d.ts.map +1 -1
  86. package/src/runs/background/async-resume.js +7 -2
  87. package/src/runs/background/async-resume.js.map +1 -1
  88. package/src/runs/background/async-status.d.ts +1 -0
  89. package/src/runs/background/async-status.d.ts.map +1 -1
  90. package/src/runs/background/async-status.js +1 -0
  91. package/src/runs/background/async-status.js.map +1 -1
  92. package/src/runs/background/binary-bootstrap.d.ts.map +1 -1
  93. package/src/runs/background/binary-bootstrap.js +34 -6
  94. package/src/runs/background/binary-bootstrap.js.map +1 -1
  95. package/src/runs/background/fleet-view.d.ts.map +1 -1
  96. package/src/runs/background/fleet-view.js +26 -7
  97. package/src/runs/background/fleet-view.js.map +1 -1
  98. package/src/runs/background/notify.d.ts +11 -0
  99. package/src/runs/background/notify.d.ts.map +1 -1
  100. package/src/runs/background/notify.js +73 -3
  101. package/src/runs/background/notify.js.map +1 -1
  102. package/src/runs/background/pid-namespace.d.ts +3 -0
  103. package/src/runs/background/pid-namespace.d.ts.map +1 -0
  104. package/src/runs/background/pid-namespace.js +20 -0
  105. package/src/runs/background/pid-namespace.js.map +1 -0
  106. package/src/runs/background/process-terminal-candidate.d.ts +18 -0
  107. package/src/runs/background/process-terminal-candidate.d.ts.map +1 -0
  108. package/src/runs/background/process-terminal-candidate.js +97 -0
  109. package/src/runs/background/process-terminal-candidate.js.map +1 -0
  110. package/src/runs/background/process-terminal.d.ts +3 -15
  111. package/src/runs/background/process-terminal.d.ts.map +1 -1
  112. package/src/runs/background/process-terminal.js +19 -96
  113. package/src/runs/background/process-terminal.js.map +1 -1
  114. package/src/runs/background/retained-children.d.ts.map +1 -1
  115. package/src/runs/background/retained-children.js +3 -2
  116. package/src/runs/background/retained-children.js.map +1 -1
  117. package/src/runs/background/run-child-session.d.ts +2 -0
  118. package/src/runs/background/run-child-session.d.ts.map +1 -1
  119. package/src/runs/background/run-child-session.js +2 -0
  120. package/src/runs/background/run-child-session.js.map +1 -1
  121. package/src/runs/background/run-status.d.ts.map +1 -1
  122. package/src/runs/background/run-status.js +5 -1
  123. package/src/runs/background/run-status.js.map +1 -1
  124. package/src/runs/background/runner-aliases.d.ts.map +1 -1
  125. package/src/runs/background/runner-aliases.js +2 -1
  126. package/src/runs/background/runner-aliases.js.map +1 -1
  127. package/src/runs/background/runner-startup-failure.d.ts +14 -0
  128. package/src/runs/background/runner-startup-failure.d.ts.map +1 -0
  129. package/src/runs/background/runner-startup-failure.js +47 -0
  130. package/src/runs/background/runner-startup-failure.js.map +1 -0
  131. package/src/runs/background/stale-run-reconciler.d.ts +1 -0
  132. package/src/runs/background/stale-run-reconciler.d.ts.map +1 -1
  133. package/src/runs/background/stale-run-reconciler.js +18 -3
  134. package/src/runs/background/stale-run-reconciler.js.map +1 -1
  135. package/src/runs/background/subagent-runner-bootstrap.d.ts +14 -0
  136. package/src/runs/background/subagent-runner-bootstrap.d.ts.map +1 -0
  137. package/src/runs/background/subagent-runner-bootstrap.js +277 -0
  138. package/src/runs/background/subagent-runner-bootstrap.js.map +1 -0
  139. package/src/runs/background/subagent-runner.d.ts +4 -2
  140. package/src/runs/background/subagent-runner.d.ts.map +1 -1
  141. package/src/runs/background/subagent-runner.js +58 -180
  142. package/src/runs/background/subagent-runner.js.map +1 -1
  143. package/src/runs/background/workflow-terminal-proof.d.ts +18 -0
  144. package/src/runs/background/workflow-terminal-proof.d.ts.map +1 -0
  145. package/src/runs/background/workflow-terminal-proof.js +68 -0
  146. package/src/runs/background/workflow-terminal-proof.js.map +1 -0
  147. package/src/runs/foreground/execution.d.ts.map +1 -1
  148. package/src/runs/foreground/execution.js +43 -14
  149. package/src/runs/foreground/execution.js.map +1 -1
  150. package/src/runs/foreground/prompt-audit.d.ts.map +1 -1
  151. package/src/runs/foreground/prompt-audit.js +2 -6
  152. package/src/runs/foreground/prompt-audit.js.map +1 -1
  153. package/src/runs/foreground/subagent-executor.d.ts +2 -1
  154. package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  155. package/src/runs/foreground/subagent-executor.js +228 -24
  156. package/src/runs/foreground/subagent-executor.js.map +1 -1
  157. package/src/runs/shared/child-launch.d.ts.map +1 -1
  158. package/src/runs/shared/child-launch.js +3 -0
  159. package/src/runs/shared/child-launch.js.map +1 -1
  160. package/src/runs/shared/child-runtime-config.d.ts +4 -0
  161. package/src/runs/shared/child-runtime-config.d.ts.map +1 -1
  162. package/src/runs/shared/child-runtime-config.js.map +1 -1
  163. package/src/runs/shared/child-session.d.ts +1 -0
  164. package/src/runs/shared/child-session.d.ts.map +1 -1
  165. package/src/runs/shared/child-session.js +1 -0
  166. package/src/runs/shared/child-session.js.map +1 -1
  167. package/src/runs/shared/child-tool-plan.d.ts.map +1 -1
  168. package/src/runs/shared/child-tool-plan.js +4 -6
  169. package/src/runs/shared/child-tool-plan.js.map +1 -1
  170. package/src/runs/shared/external-cli-runner.d.ts.map +1 -1
  171. package/src/runs/shared/external-cli-runner.js +3 -1
  172. package/src/runs/shared/external-cli-runner.js.map +1 -1
  173. package/src/runs/shared/external-job-bridge.d.ts +7 -0
  174. package/src/runs/shared/external-job-bridge.d.ts.map +1 -1
  175. package/src/runs/shared/external-job-bridge.js +63 -0
  176. package/src/runs/shared/external-job-bridge.js.map +1 -1
  177. package/src/runs/shared/git-environment.d.ts +3 -0
  178. package/src/runs/shared/git-environment.d.ts.map +1 -0
  179. package/src/runs/shared/git-environment.js +28 -0
  180. package/src/runs/shared/git-environment.js.map +1 -0
  181. package/src/runs/shared/mcp-config-sources.d.ts +3 -0
  182. package/src/runs/shared/mcp-config-sources.d.ts.map +1 -1
  183. package/src/runs/shared/mcp-config-sources.js.map +1 -1
  184. package/src/runs/shared/mcp-direct-tool-allowlist.js +1 -1
  185. package/src/runs/shared/mcp-direct-tool-allowlist.js.map +1 -1
  186. package/src/runs/shared/mcp-direct-tool-grant.d.ts +3 -1
  187. package/src/runs/shared/mcp-direct-tool-grant.d.ts.map +1 -1
  188. package/src/runs/shared/mcp-direct-tool-grant.js +19 -5
  189. package/src/runs/shared/mcp-direct-tool-grant.js.map +1 -1
  190. package/src/runs/shared/model-resolution.d.ts.map +1 -1
  191. package/src/runs/shared/model-resolution.js +7 -1
  192. package/src/runs/shared/model-resolution.js.map +1 -1
  193. package/src/runs/shared/pi-spawn.d.ts +10 -1
  194. package/src/runs/shared/pi-spawn.d.ts.map +1 -1
  195. package/src/runs/shared/pi-spawn.js +86 -7
  196. package/src/runs/shared/pi-spawn.js.map +1 -1
  197. package/src/runs/shared/single-output.js +1 -1
  198. package/src/runs/shared/single-output.js.map +1 -1
  199. package/src/runs/shared/structured-output.d.ts +7 -0
  200. package/src/runs/shared/structured-output.d.ts.map +1 -1
  201. package/src/runs/shared/structured-output.js +74 -0
  202. package/src/runs/shared/structured-output.js.map +1 -1
  203. package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
  204. package/src/runs/shared/subagent-prompt-runtime.js +23 -7
  205. package/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
  206. package/src/runs/shared/tool-availability.js +2 -2
  207. package/src/runs/shared/tool-availability.js.map +1 -1
  208. package/src/runs/shared/worktree.d.ts.map +1 -1
  209. package/src/runs/shared/worktree.js +9 -3
  210. package/src/runs/shared/worktree.js.map +1 -1
  211. package/src/shared/child-session-name.d.ts.map +1 -1
  212. package/src/shared/child-session-name.js +4 -2
  213. package/src/shared/child-session-name.js.map +1 -1
  214. package/src/shared/fork-context.d.ts +4 -0
  215. package/src/shared/fork-context.d.ts.map +1 -1
  216. package/src/shared/fork-context.js +9 -4
  217. package/src/shared/fork-context.js.map +1 -1
  218. package/src/shared/pruned-fork.d.ts.map +1 -1
  219. package/src/shared/pruned-fork.js +68 -56
  220. package/src/shared/pruned-fork.js.map +1 -1
  221. package/src/shared/types.d.ts +31 -3
  222. package/src/shared/types.d.ts.map +1 -1
  223. package/src/shared/types.js +2 -0
  224. package/src/shared/types.js.map +1 -1
  225. package/src/slash/delegation-adapters.d.ts +7 -1
  226. package/src/slash/delegation-adapters.d.ts.map +1 -1
  227. package/src/slash/delegation-adapters.js +17 -0
  228. package/src/slash/delegation-adapters.js.map +1 -1
  229. package/src/slash/prompt-template-bridge.d.ts.map +1 -1
  230. package/src/slash/prompt-template-bridge.js +14 -1
  231. package/src/slash/prompt-template-bridge.js.map +1 -1
  232. package/src/slash/prompt-workflows.d.ts.map +1 -1
  233. package/src/slash/prompt-workflows.js +16 -2
  234. package/src/slash/prompt-workflows.js.map +1 -1
  235. package/src/slash/slash-commands.d.ts.map +1 -1
  236. package/src/slash/slash-commands.js +7 -253
  237. package/src/slash/slash-commands.js.map +1 -1
  238. package/src/slash/subagent-cost.d.ts +30 -0
  239. package/src/slash/subagent-cost.d.ts.map +1 -0
  240. package/src/slash/subagent-cost.js +307 -0
  241. package/src/slash/subagent-cost.js.map +1 -0
  242. package/src/tui/fleet-status.d.ts +2 -0
  243. package/src/tui/fleet-status.d.ts.map +1 -1
  244. package/src/tui/fleet-status.js +25 -2
  245. package/src/tui/fleet-status.js.map +1 -1
  246. package/src/tui/fleet.d.ts +1 -1
  247. package/src/tui/fleet.d.ts.map +1 -1
  248. package/src/tui/fleet.js +5 -1
  249. package/src/tui/fleet.js.map +1 -1
  250. package/src/tui/render.d.ts.map +1 -1
  251. package/src/tui/render.js +8 -4
  252. package/src/tui/render.js.map +1 -1
  253. package/src/watchdog/diff-tool.d.ts +2 -1
  254. package/src/watchdog/diff-tool.d.ts.map +1 -1
  255. package/src/watchdog/diff-tool.js +9 -3
  256. package/src/watchdog/diff-tool.js.map +1 -1
  257. package/src/watchdog/permission-arbiter.d.ts.map +1 -1
  258. package/src/watchdog/permission-arbiter.js +2 -7
  259. package/src/watchdog/permission-arbiter.js.map +1 -1
  260. package/src/watchdog/register-child.d.ts +3 -1
  261. package/src/watchdog/register-child.d.ts.map +1 -1
  262. package/src/watchdog/register-child.js +12 -3
  263. package/src/watchdog/register-child.js.map +1 -1
  264. package/src/watchdog/review.d.ts +1 -1
  265. package/src/watchdog/review.d.ts.map +1 -1
  266. package/src/watchdog/review.js +2 -7
  267. package/src/watchdog/review.js.map +1 -1
  268. package/src/watchdog/runtime.d.ts +1 -1
  269. package/src/watchdog/runtime.d.ts.map +1 -1
  270. package/src/watchdog/runtime.js +2 -1
  271. package/src/watchdog/runtime.js.map +1 -1
  272. package/src/watchdog/turn-delta.d.ts +5 -1
  273. package/src/watchdog/turn-delta.d.ts.map +1 -1
  274. package/src/watchdog/turn-delta.js +9 -5
  275. package/src/watchdog/turn-delta.js.map +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,93 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.72.0] - 2026-09-26
6
+
7
+ ### Highlights
8
+
9
+ - Pi starts faster with pi-subagents installed: startup no longer waits on global agent discovery, and the executor and Fleet load the first time you use them.
10
+ - The package no longer bundles its own copy of TypeBox, so installs are smaller and Pi stops warning about the manifest.
11
+ - Models from complete provider extensions now work everywhere pi-subagents calls a model, including the watchdog, permission checks, and Prompt Audit.
12
+ - Other extensions can plug their own inspectors into Fleet.
13
+ - Async runs are more dependable: child sessions can start and resume their own external jobs, `/subagent-cost` counts every async launch, and live runs are no longer marked failed when containers share a temp directory.
14
+
15
+ ### Added
16
+
17
+ - Extensions can register their own inspector providers with the `pi-subagents/inspectors` helper or the `pi-subagents:inspector-register:v1` event. Fleet uses them for inspector actions, while the built-in inspectors and runner controls keep working as before. Thanks to [@ninjapenguin](https://github.com/ninjapenguin) for [#2482](https://github.com/nicobailon/pi-subagents/pull/2482).
18
+
19
+ ### Changed
20
+
21
+ - Pi starts faster with pi-subagents enabled. The foreground executor and the Fleet view now load on first use, which cuts the extension's own startup modules from 264 to 199. Tools, commands, and prompts are registered exactly as before. Thanks to [@h4yfans](https://github.com/h4yfans) for the measurements in [#2480](https://github.com/nicobailon/pi-subagents/issues/2480).
22
+ - TypeBox is now provided by Pi instead of bundled with the package. Pi no longer warns about the manifest, and the extension, its children, and background runners all use Pi's copy. Thanks to [@felipemm](https://github.com/felipemm) for [#2454](https://github.com/nicobailon/pi-subagents/issues/2454) and [#2455](https://github.com/nicobailon/pi-subagents/pull/2455).
23
+
24
+ ### Fixed
25
+
26
+ - The watchdog, permission checks, and Prompt Audit now reach models from complete provider extensions (`pi.registerProvider(provider)`). They used an older lookup that only knew config-style providers, so these calls failed even though ordinary children could use the same model. Thanks to [@chem](https://github.com/chem) for [#2496](https://github.com/nicobailon/pi-subagents/issues/2496).
27
+ - Model names such as `openrouter/auto-beta` now resolve when the provider's own model id already starts with the provider name. They used to fail with `Unknown subagent model`. Thanks to [@schmlblk](https://github.com/schmlblk) for [#2487](https://github.com/nicobailon/pi-subagents/issues/2487).
28
+ - `fast: true` accepts any `openai-codex/*` model instead of only two named models, so newer Codex models no longer fail before launch. Other providers are still rejected. Thanks to [@jtabke](https://github.com/jtabke) for [#2452](https://github.com/nicobailon/pi-subagents/issues/2452).
29
+ - Async status shows a child's real context limit once its session starts, including a limit raised by an extension. Thanks to [@johnhenaot](https://github.com/johnhenaot) for [#2448](https://github.com/nicobailon/pi-subagents/pull/2448).
30
+ - Session startup no longer freezes while pi-subagents looks for globally installed agents. The first agent prompt and `subagents_enable` still wait until discovery finishes. Thanks to [@trading-bl](https://github.com/trading-bl) for [#2474](https://github.com/nicobailon/pi-subagents/issues/2474).
31
+ - `subagents_enable` ignores extra arguments instead of rejecting the call. DeepSeek V4.1 Flash sends `subagents_enable({ action: "enable" })`, which used to fail every time. Thanks to [@crusaderky](https://github.com/crusaderky) for [#2483](https://github.com/nicobailon/pi-subagents/issues/2483).
32
+ - An older `pi-ai` installed next to the package no longer turns off on-demand tool loading, so `subagent` stays hidden behind `subagents_enable` until it is needed. Thanks to [@abdwhb-png](https://github.com/abdwhb-png) for [#2471](https://github.com/nicobailon/pi-subagents/pull/2471).
33
+ - `/council` works when Pi runs with `--no-skills`. It now loads its instructions through `subagent({ action: "guide", topic: "council" })`. Thanks to [@felipemm](https://github.com/felipemm) for [#2467](https://github.com/nicobailon/pi-subagents/issues/2467).
34
+ - External-job runs that a child session launches now start instead of staying queued. Thanks to [@juanpprieto](https://github.com/juanpprieto) for [#2449](https://github.com/nicobailon/pi-subagents/issues/2449).
35
+ - A child session can follow up its own external-job runs with `resume`, and a repeated resume no longer sends the follow-up twice. Thanks to [@juanpprieto](https://github.com/juanpprieto) for [#2465](https://github.com/nicobailon/pi-subagents/issues/2465).
36
+ - A background run that is still working is no longer reported failed when Pi processes in different containers share one `PI_SUBAGENTS_TEMP_ROOT`. Pi could not see the runner's process from another container and treated it as gone. Such runs now fall back to the usual 24-hour stale check. Thanks to [@zeezooz](https://github.com/zeezooz) for [#2494](https://github.com/nicobailon/pi-subagents/issues/2494) and [#2495](https://github.com/nicobailon/pi-subagents/issues/2495).
37
+ - `/subagent-cost` includes async single, chain, and parallel launches, which it used to report as having no child usage. Thanks to [@zeezooz](https://github.com/zeezooz) for [#2484](https://github.com/nicobailon/pi-subagents/issues/2484).
38
+ - Awaited workflow children send the `subagent:async-complete` event without an extra child notification. Thanks to [@mmarabel](https://github.com/mmarabel) for [#2456](https://github.com/nicobailon/pi-subagents/issues/2456).
39
+ - Worktree labels stay within 256 bytes when shortened in the middle of a multi-byte character, so async status stays readable. Thanks to [@chenhaoxiang](https://github.com/chenhaoxiang) for [#2446](https://github.com/nicobailon/pi-subagents/pull/2446).
40
+ - A launch blocked by the session's capability ceiling now fails before any fork work starts. It used to branch the parent session or prepare the fork summary first. Thanks to [@antonioc-cl](https://github.com/antonioc-cl) for [#2481](https://github.com/nicobailon/pi-subagents/pull/2481).
41
+ - The `subagent` schema and guides describe preflight, timeout aliases, budget limits, and child extension bindings accurately, and an empty `usageBudget` is now rejected. Thanks to [@amchen2310](https://github.com/amchen2310) for [#2473](https://github.com/nicobailon/pi-subagents/issues/2473).
42
+ - The async workflow widget no longer flickers while the inline Fleet roster is open. Thanks to [@gustavo-neiva](https://github.com/gustavo-neiva) for [#2468](https://github.com/nicobailon/pi-subagents/pull/2468).
43
+ - `subagent_supervisor` `pending` shows each request's question, so you can answer a request after missing its notice ([#2460](https://github.com/nicobailon/pi-subagents/issues/2460)).
44
+
45
+ ## [0.71.0] - 2026-09-23
46
+
47
+ ### Highlights
48
+
49
+ - Other extensions can read subagent spend and follow async workflow progress as data, without scraping terminal output.
50
+ - Workflow status can now confirm that every child process has actually exited.
51
+ - Child sessions keep readable names such as `worker: fix auth refresh` in `/resume` and Herdr.
52
+ - The full `subagent` tool loads only when a request needs it, which keeps unrelated prompts smaller.
53
+ - Background runners, reviewers, and Bun, pnpm, and symlinked installs are more reliable.
54
+
55
+ ### Added
56
+
57
+ - In-process RPC `cost` method. It returns the same parent-plus-child spend that `/subagent-cost` shows, as versioned data (`{ version: 1, parent, children, childTotal, total, unresolvedAsyncChildren }`). `ping.capabilities.cost` advertises `{ version: 1 }`. `/subagent-cost` output is unchanged. Thanks to [@raymondtri](https://github.com/raymondtri) for [#2378](https://github.com/nicobailon/pi-subagents/pull/2378).
58
+ - Async `workflowScript` runs and the children they launch now emit public lifecycle events, so companion UIs can follow them without scraping terminal output. Thanks to [@navidemad](https://github.com/navidemad) for [#2382](https://github.com/nicobailon/pi-subagents/pull/2382).
59
+ - Status for an async workflow now includes `details.workflowTerminalProof`. It reports `observed`, with each child's exit evidence, only after the workflow has stopped launching children and every async child has exited or failed to start. Otherwise it reports `pending` or `unknown` with a reason, including when the saved child list is missing. A finished workflow frees its capacity slot using the same check, so the two always agree. Thanks to [@alexei-led](https://github.com/alexei-led) for [#2436](https://github.com/nicobailon/pi-subagents/issues/2436) and [#2442](https://github.com/nicobailon/pi-subagents/pull/2442).
60
+
61
+ ### Changed
62
+
63
+ - Packaged `worker` agents now start with fresh context instead of forking the parent's conversation. You can still request fork context per call or set it globally. Thanks to [@eduardopicolo-cb](https://github.com/eduardopicolo-cb) for [#2384](https://github.com/nicobailon/pi-subagents/issues/2384).
64
+ - The full `subagent` tool stays hidden until a request activates it through the small `subagents_enable` loader, which keeps unrelated prompt context smaller. Direct commands, RPC, the TUI, and nested children work as before. Thanks to [@Knimoms](https://github.com/Knimoms) for [#2380](https://github.com/nicobailon/pi-subagents/pull/2380).
65
+ - Child sessions keep a readable name (for example `worker: fix auth refresh`) in session lists, `/resume`, and Herdr while the intercom bridge is active. Nested children now reach their supervisor through the child's intercom ID instead of its session name. This needs a pi-intercom version that supports the `intercom:session-identity` claim; with an older pi-intercom, children keep the previous naming so routing still works. Thanks to [@Q-xuan](https://github.com/Q-xuan) for raising the problem in [#2432](https://github.com/nicobailon/pi-subagents/pull/2432).
66
+ - The optional `@earendil-works/pi-ai` peer dependency now requires 0.86.1 or later, matching the oldest supported Pi host. Thanks to [@samuela](https://github.com/samuela) for [#2373](https://github.com/nicobailon/pi-subagents/issues/2373).
67
+ - When a child's `structured_output` call is rejected, the result now includes a short summary of the validation errors. The missing-structured-output error is used only when the child never called the tool. Thanks to [@rtbe](https://github.com/rtbe) for [#2407](https://github.com/nicobailon/pi-subagents/issues/2407).
68
+
69
+ ### Fixed
70
+
71
+ - `subagent` is available again after switching from an inactive session branch to one where it was activated.
72
+ - Background runners and external CLI agents no longer inherit Git's repository variables (`GIT_DIR`, `GIT_WORK_TREE`, `GIT_INDEX_FILE`, `GIT_CONFIG_*`, and the rest of `git rev-parse --local-env-vars`). When Pi was started from a Git hook or with `git --git-dir`, these made a child's Git commands act on the parent's repository instead of the child's working directory. Other variables such as `GIT_AUTHOR_*` still pass through, and an external agent's explicit environment allowlist is unchanged. Thanks to [@alexei-led](https://github.com/alexei-led) for [#2437](https://github.com/nicobailon/pi-subagents/issues/2437) and [#2440](https://github.com/nicobailon/pi-subagents/pull/2440).
73
+ - Retained background runs no longer time out while the packaged runner is still starting. Thanks to [@muermaru](https://github.com/muermaru) for [#2403](https://github.com/nicobailon/pi-subagents/issues/2403), and to [@qsgy-edge](https://github.com/qsgy-edge) for the independent diagnosis and timing evidence in [#2415](https://github.com/nicobailon/pi-subagents/pull/2415).
74
+ - When a background runner exits without writing a result, the failure notice now includes its exit code and signal. Thanks to [@grahama1970](https://github.com/grahama1970) for [#2423](https://github.com/nicobailon/pi-subagents/issues/2423).
75
+ - A child that produced valid structured output keeps it as evidence when a later provider error or abort fails the run. Thanks to [@grahama1970](https://github.com/grahama1970) for [#2411](https://github.com/nicobailon/pi-subagents/issues/2411).
76
+ - Completion notifications are no longer sent twice when the extension is registered more than once for the same session. Thanks to [@hongchu098](https://github.com/hongchu098) for [#2389](https://github.com/nicobailon/pi-subagents/issues/2389).
77
+ - The bundled reviewer works in directories without Git: `watchdog_diff` reports that no baseline is available instead of failing the review. Thanks to [@matthewmathistrellys](https://github.com/matthewmathistrellys) for [#2422](https://github.com/nicobailon/pi-subagents/issues/2422).
78
+ - The bundled reviewer's `watchdog_diff` counts as read-only, so a reviewer given a single output path returns its full report for the runtime to save, as introduced in [#426](https://github.com/nicobailon/pi-subagents/issues/426), with thanks to Alexander Gerdes ([@Avg8888](https://github.com/Avg8888)). Thanks to [@riskywhat](https://github.com/riskywhat) for [#2405](https://github.com/nicobailon/pi-subagents/issues/2405).
79
+ - Watchdog reviews and permission checks work again on the Pi 0.86.1 package layout. Thanks to [@zieglar](https://github.com/zieglar) for the reproduction and version comparison in [#2377](https://github.com/nicobailon/pi-subagents/issues/2377).
80
+ - A workflow child with no `agent` now fails with an error that names it (`Workflow child 'r1' has no agent…`) instead of the generic "Provide exactly one mode" message. Thanks to [@matthewmathistrellys](https://github.com/matthewmathistrellys) for raising the confusing error in [#2422](https://github.com/nicobailon/pi-subagents/issues/2422).
81
+ - `/prompt-workflow` finds prompt files that are symlinks (as installed by dotfile managers such as GNU Stow or homeshick) and skips broken links instead of failing. Thanks to [@nietaki](https://github.com/nietaki) for [#2430](https://github.com/nicobailon/pi-subagents/issues/2430).
82
+ - Completed retained agents can resume even when their own list of allowed child agents excludes them. Parent authority and that restriction both still apply; older retained children without the needed recovery data fail closed. Thanks to [@riskywhat](https://github.com/riskywhat) for [#2379](https://github.com/nicobailon/pi-subagents/issues/2379), building on the allowlist work in [#2338](https://github.com/nicobailon/pi-subagents/pull/2338) credited to [@shkrabov](https://github.com/shkrabov).
83
+ - Guidance now says the list of retained workflow children is not complete: when you know a run's exact id, check its status and try resuming it before falling back to a labeled agent with the same role. Thanks to [@riskywhat](https://github.com/riskywhat) for [#2406](https://github.com/nicobailon/pi-subagents/issues/2406).
84
+ - Skills marked `disable-model-invocation: true` are no longer shown to child agents, even when requested by name, and are no longer suggested to the model. Thanks to [@toRolex](https://github.com/toRolex) for [#2400](https://github.com/nicobailon/pi-subagents/pull/2400).
85
+ - Pi hosts compiled with Bun are found from Pi's package directory or its bundled `share/pi-coding-agent` layout, while unrelated extension dependencies still cannot turn on dynamic tools. Thanks to [@fmoda3](https://github.com/fmoda3) for [#2417](https://github.com/nicobailon/pi-subagents/issues/2417).
86
+ - pnpm installs follow npm-hosted peer aliases through their symlinks to the real package, so the package is not loaded twice. Thanks to [@henriquebastos](https://github.com/henriquebastos) for [#2409](https://github.com/nicobailon/pi-subagents/pull/2409).
87
+ - npm and git installs detect dynamic tool support from the running Pi installation and keep the compact `subagents_enable` loader instead of an always-loaded `subagent` tool. Thanks to [@qsgy-edge](https://github.com/qsgy-edge) for [#2398](https://github.com/nicobailon/pi-subagents/pull/2398).
88
+ - MCP direct tool names now match what pi-mcp-adapter registers, including servers whose tool names already start with the server name, the adapter's `mcp` prefix mode, and per-server `toolPrefix`. Thanks to [@qsgy-edge](https://github.com/qsgy-edge) for [#2395](https://github.com/nicobailon/pi-subagents/pull/2395).
89
+ - Logs from running and failed external CLI agents can be viewed in Fleet, tool status, and the TUI. Thanks to [@Shujakuinkuraudo](https://github.com/Shujakuinkuraudo) for [#2375](https://github.com/nicobailon/pi-subagents/issues/2375).
90
+ - Structured delegation updates report cumulative usage and no longer count missing provider cache numbers as zero. Thanks to [@bioShaun](https://github.com/bioShaun) for [#2374](https://github.com/nicobailon/pi-subagents/pull/2374).
91
+ - Forked sessions keep Pi 0.87 context edits, including replaced content and signed Anthropic thinking blocks.
5
92
  ## [0.70.1] - 2026-09-20
6
93
 
7
94
  ### Highlights
package/README.md CHANGED
@@ -44,7 +44,9 @@ Pi is the parent session. A subagent is a focused child Pi session with its own
44
44
 
45
45
  When you ask for a subagent, Pi starts the child, gives it the task, and brings the result back. Foreground children run as sessions inside the parent Pi process and stream in the conversation. Background children run as sessions inside a detached runner process that keeps working and can be checked later.
46
46
 
47
- Installing the extension does not start an automatic reviewer in the background. It gives Pi a delegation tool. If you want every implementation reviewed, say so in your prompt or project instructions:
47
+ Installing the extension does not start an automatic reviewer in the background. Fresh parent sessions initially expose the small `subagents_enable` loader instead of the full `subagent` schema. When your request or applicable instructions authorize delegation, Pi can call the loader itself; the unchanged `subagent` tool is available on the next model request. Complexity alone does not authorize delegation. `bg_wait` and supervisor replies remain available without activation.
48
+
49
+ If you want every implementation reviewed, say so in your prompt or project instructions:
48
50
 
49
51
  ```text
50
52
  When you finish implementing, run a reviewer subagent before summarizing.
@@ -108,7 +110,7 @@ For bounded orchestration, `maxSubagentSpawnsPerRun` limits cumulative logical c
108
110
 
109
111
  or ask: "Check whether subagents and intercom are set up correctly."
110
112
 
111
- For installed-version help, use `/subagents-guide [topic]` or `subagent({ action: "guide", topic: "workflows" })`. The default topic is `overview`; available topics are `overview`, `workflows`, `agents`, `missions`, `observability`, `tool-reference`, `configuration`, `models`, `watchdog`, and `extension-api`.
113
+ For installed-version help, use `/subagents-guide [topic]` or `subagent({ action: "guide", topic: "workflows" })`. The default topic is `overview`; available topics are `overview`, `workflows`, `agents`, `missions`, `observability`, `tool-reference`, `configuration`, `models`, `watchdog`, `extension-api`, and `council`.
112
114
 
113
115
  ## Documentation
114
116
 
package/agents/worker.md CHANGED
@@ -8,7 +8,7 @@ systemPromptMode: replace
8
8
  inheritProjectContext: true
9
9
  inheritSkills: false
10
10
  tools: read, grep, find, ls, bash, edit, write, contact_supervisor
11
- defaultContext: fork
11
+ defaultContext: fresh
12
12
  defaultReads: context.md, plan.md
13
13
  defaultProgress: true
14
14
  ---
@@ -17,7 +17,7 @@ You are `worker`: the implementation subagent.
17
17
 
18
18
  You are the single writer thread. Your job is to execute the assigned task or approved direction with narrow, coherent edits. The main agent and user remain the decision authority.
19
19
 
20
- Use the provided tools directly. First read the inherited context, supplied files, plan, task paths, and named seams. Then implement carefully and minimally. Use broad search only to verify or expand from that starting point.
20
+ Use the provided tools directly. First read the provided context, supplied files, plan, task paths, and named seams. Then implement carefully and minimally. Use broad search only to verify or expand from that starting point.
21
21
 
22
22
  The builtin worker uses a strict tool allowlist. It does not inherit ambient extension tools from the parent session. To use an extension tool, configure a custom agent with the tool name explicitly listed in `tools` and load its provider through `extensions` or `subagentOnlyExtensions`.
23
23
 
package/docs/agents.md CHANGED
@@ -460,7 +460,7 @@ Examples:
460
460
  - `allowNestedSubagents: true` with `tools` omitted: normal builtin tools (and, for background children, ambient extensions) remain inherited, and the child-safe nested `subagent` runtime is added.
461
461
  - `tools: read, fixture_search` plus `subagentOnlyExtensions: ./tools/fixture-search.ts`: the provider loads only in this agent's child sessions, and the registered `fixture_search` name survives the strict allowlist.
462
462
 
463
- Direct MCP tools require [pi-mcp-adapter](https://github.com/nicobailon/pi-mcp-adapter). Subagents only receive direct MCP tools when `mcp:` entries are listed in their frontmatter; global `directTools: true` in `mcp.json` is not enough by itself. The generic `mcp` proxy tool can still be used for discovery when available. The adapter caches tool metadata at startup, so after connecting a new MCP server for the first time, restart Pi before relying on direct tools. Server `includeTools` and `excludeTools` policies are enforced while resolving cached metadata for children: both accept exact names and `*`/`?` glob patterns against raw, generated-resource, and server/short/none-prefixed names, with `excludeTools` taking precedence. `mcp:` entries must name servers from the adapter's configuration files. A server that exists only in the adapter's runtime snapshot (registered at runtime, not persisted) cannot be provided to a child: children are pi sessions inside the parent or the runner process, not `pi` processes that could receive an MCP config argument, so such a launch fails with an error saying that MCP tools must come from an ambient adapter extension in a background child. An `mcp:` entry named `subagent` does not authorize nested fanout; declare the builtin `subagent` tool or set `allowNestedSubagents: true`. If a resolved direct MCP name is missing from the child registry, pi-subagents keeps the launch failed under the strict allowlist and identifies the condition as a host/pi-mcp-adapter registration problem; verify that the adapter registers the selected tools before child startup.
463
+ Direct MCP tools require [pi-mcp-adapter](https://github.com/nicobailon/pi-mcp-adapter). Subagents only receive direct MCP tools when `mcp:` entries are listed in their frontmatter; global `directTools: true` in `mcp.json` is not enough by itself. The generic `mcp` proxy tool can still be used for discovery when available. The adapter caches tool metadata at startup, so after connecting a new MCP server for the first time, restart Pi before relying on direct tools. Server `includeTools` and `excludeTools` policies are enforced while resolving cached metadata for children: both accept exact names and `*`/`?` glob patterns against raw, generated-resource, and server/short/mcp/none-prefixed names, with `excludeTools` taking precedence. `mcp:` entries must name servers from the adapter's configuration files. A server that exists only in the adapter's runtime snapshot (registered at runtime, not persisted) cannot be provided to a child: children are pi sessions inside the parent or the runner process, not `pi` processes that could receive an MCP config argument, so such a launch fails with an error saying that MCP tools must come from an ambient adapter extension in a background child. An `mcp:` entry named `subagent` does not authorize nested fanout; declare the builtin `subagent` tool or set `allowNestedSubagents: true`. If a resolved direct MCP name is missing from the child registry, pi-subagents keeps the launch failed under the strict allowlist and reports the registration mismatch; check the resolved names against what the host or pi-mcp-adapter actually registers before child startup.
464
464
 
465
465
  `extensions` controls child extension loading:
466
466
 
@@ -76,6 +76,14 @@ For a native Pi `model_verification_failed` where your proxy accepts `claude-hai
76
76
 
77
77
  Replace `YOUR_PROVIDER` with the resolved Pi provider ID. Keep the outgoing model alias unchanged. This native remedy already exists in v0.65.1; it does not infer equivalence from provider prefixes or dates. The built-in external `claude-code` adapter does not invoke this verifier or use this setting. If an external run shows this diagnostic, identify the installed version, resolved runner kind/adapter, and error location before applying a native remedy. Thanks to [sixtus](https://github.com/sixtus) for the concrete request-ID/response-ID example in [#1922](https://github.com/nicobailon/pi-subagents/issues/1922).
78
78
 
79
+ ## Tool activation lifecycle
80
+
81
+ On Pi 0.86.1 or newer, a fresh unrestricted parent starts with `subagents_enable`, `bg_wait`, and `subagent_supervisor` active while `subagent` stays registered but inactive. Calling `subagents_enable({})` preserves unrelated active tools and exposes `subagent` on the next model request. It does not launch a child or infer authority from prompt keywords.
82
+
83
+ The recorded native `subagent` selection is restored on resume, reload, and tree navigation, so an activated session stays activated and a cold session stays cold. Older history without tool-selection records keeps eager `subagent` availability. If Pi's allowlist or exclusions remove the loader, the extension does not hide `subagent`; if they remove `subagent`, the loader reports it unavailable. Hosts older than the verified dynamic-tool baseline keep eager behavior and log one compatibility warning.
84
+
85
+ Some providers fix the tool list for a whole prompt, for example bridges that hand Pi's tools to another agent SDK. There `subagent` appears only on the next user prompt, not the next model request. Start Pi with `--exclude-tools subagents_enable` to keep `subagent` active from the start.
86
+
79
87
  ## `toolDescriptionMode`
80
88
 
81
89
  ```json
@@ -400,7 +408,7 @@ Routes relative `output` paths for single-agent `/run` calls under this director
400
408
  { "maxSubagentDepth": 1 }
401
409
  ```
402
410
 
403
- Controls nested delegation when no stricter limit is inherited from the launching child's runtime config. Per-agent `maxSubagentDepth` can tighten the limit for that agent's child runs, but cannot relax an inherited stricter limit. This applies even to children that explicitly declare `tools: subagent` or `allowNestedSubagents: true`; at the cap, execution fanout is blocked instead of silently hiding nested work.
411
+ Controls nested delegation when no stricter limit is inherited from the launching child's runtime config. The default is 2 when neither the runtime limit, `PI_SUBAGENT_MAX_DEPTH`, nor this setting supplies a limit. Per-agent `maxSubagentDepth` can tighten the limit for that agent's child runs, but cannot relax an inherited stricter limit. This applies even to children that explicitly declare `tools: subagent` or `allowNestedSubagents: true`; at the cap, execution fanout is blocked instead of silently hiding nested work.
404
412
 
405
413
  ## `PI_SUBAGENT_PI_BINARY`
406
414
 
@@ -412,13 +420,21 @@ Overrides the `pi` command pi-subagents spawns for project panes and the profile
412
420
 
413
421
  Foreground children remain sessions inside the parent. Npm background children retain their Node runner and host-package peer aliases; this variable does not turn npm Pi into a binary-backed runner. See [Standalone background execution](standalone-background.md) for the official tested target.
414
422
 
423
+ ## `PI_PACKAGE_DIR`
424
+
425
+ ```bash
426
+ export PI_PACKAGE_DIR=/path/to/pi-coding-agent-package
427
+ ```
428
+
429
+ Pi's own package/assets root is also authoritative when pi-subagents verifies the running host for dynamic tool activation. Host discovery prefers a package root owned by the real `process.argv[1]`, then a nonblank `PI_PACKAGE_DIR`, then `PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT`. For a proven Bun-compiled Pi process with a virtual argv entry, it can finally validate package assets adjacent to the canonical executable or in the installed `<prefix>/share/pi-coding-agent` layout. Every selected root must contain a `package.json` whose name is exactly `@earendil-works/pi-coding-agent`; an invalid explicit root fails closed rather than selecting another installation. Empty or whitespace-only values are ignored.
430
+
415
431
  ## `PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT`
416
432
 
417
433
  ```bash
418
434
  export PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT=/path/to/pi-coding-agent-package
419
435
  ```
420
436
 
421
- Overrides host-package discovery for spawned children. Foreground CLI resolution uses this root to locate the `pi` CLI script, and the detached background runner uses it for jiti host resolution and peer-package aliases, so both child kinds agree on one host. It is consulted when argv-based automatic discovery cannot identify the host, such as a wrapper install or a non-standard layout. The value must be the root of a canonical `@earendil-works/pi-coding-agent` installation (the directory containing its `package.json`, with that package name); both child kinds still validate the package name and its peer packages from that install tree, so a package whose manifest carries a different name is rejected even with the override set. Empty or whitespace-only values are ignored.
437
+ Overrides host-package discovery for spawned children. Foreground CLI resolution uses this root to locate the `pi` CLI script, and the detached background runner uses it for jiti host resolution and peer-package aliases, so both child kinds agree on one host. For running-host activation verification it follows argv ownership and Pi's own `PI_PACKAGE_DIR`, and precedes inferred Bun image layouts. The value must be the root of a canonical `@earendil-works/pi-coding-agent` installation (the directory containing its `package.json`, with that package name); both child kinds still validate the package name and its peer packages from that install tree, so a package whose manifest carries a different name is rejected even with the override set. Empty or whitespace-only values are ignored.
422
438
 
423
439
  The default in-process child session loader consults the same discovery. Before falling back to a bare `@earendil-works/pi-coding-agent` import, it resolves the host package root (the running pi process's location, then this override, then pi-subagents' own install tree as a last fallback) and imports the host's entry file directly, so children share the host's single SDK instance instead of a second copy. Roots whose `package.json` name is not `@earendil-works/pi-coding-agent` are rejected. When this override is selected, an unimportable root is reported instead of falling back to a bare import from a different tree.
424
440
 
@@ -114,7 +114,7 @@ pi.events.emit("subagents:rpc:v1:request", {
114
114
  });
115
115
  ```
116
116
 
117
- The RPC methods are `ping`, `status`, `manage`, `spawn`, `steer`, `interrupt`, `stop`, and `resume`. `status`, `manage`, `steer`, `interrupt`, and `resume` reuse normal package-owned actions.
117
+ The RPC methods are `ping`, `status`, `manage`, `spawn`, `steer`, `interrupt`, `stop`, `resume`, and `cost`. `status`, `manage`, `steer`, `interrupt`, and `resume` reuse normal package-owned actions.
118
118
 
119
119
  Method notes:
120
120
 
@@ -122,6 +122,7 @@ Method notes:
122
122
  - `spawn` accepts structured single-child execution (`agent`, `task?`), inline `workflowScript`, or `workflowScriptPath` and is async-only: omit `async` or set `async: true`, omit `clarify`, and do not pass management `action` values. Relative script paths resolve against the request `cwd`. It goes through the same executor as the `subagent` tool, so agent discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status all behave the same.
123
123
  - `steer` requires an async run `id` (plus optional child `index`) and a non-empty `message`; its reply preserves the normal acknowledged-delivery result. Optional `mode` values are `steer` (default), `follow_up`, and `auto`, and receipts include `deliveryStatus: "delivered" | "queued"`. RPC steering disables the direct tool's pause-and-revive recovery in every mode so an extension keeps authority over the exact child it spawned; `ping.capabilities.nonRecoveringSteer` advertises this guarantee.
124
124
  - `resume` requires a run target and non-empty `message`. It delegates to the existing revival path, which validates current-session ownership, persisted session/recovery metadata, stopped/live state, capability ceilings, and the exclusive session lease before returning the new async run details. Callers may request a `file-only` output path for the revived result without overriding its model, tools, or budgets. `ping.capabilities.resume` advertises this seam.
125
+ - `cost` returns the same parent-plus-child accounting `/subagent-cost` renders, as data: `{ version: 1, parent, children, childTotal, total, unresolvedAsyncChildren }`, where each usage is `{ input, output, cacheRead, cacheWrite, cost, turns }` and each child carries `label`, `agent`, `runId`, `usage`, and `sessionFile` when known. It is read-only and walks the current session branch plus existing run artifacts, so request it on your own turn boundaries (for example after `agent_settled` or an async completion wake), not on a timer. `unresolvedAsyncChildren` counts async children whose metadata could not be read; treat `childTotal` as a lower bound when it is non-zero, exactly as documented for `/subagent-cost` in [observability.md](observability.md). `ping.capabilities.cost` advertises `{ version: 1 }`.
125
126
  - `stop` targets current-session top-level async runs through the stop control channel and records a `stopped` lifecycle instead of reporting a timeout.
126
127
  - `status` keeps targeted and rich requests on the executor-backed path. A request with no `id`, `runId`, `dir`, `index`, `view`, or `lines` may use the restored in-memory projections and a short summary; when the live state is missing, stale, session-mismatched, or not restored, it falls back to normal executor status. Status `view`, `lines`, and `index` are forwarded for targeted transcript/fleet requests. Successful replies retain `text`, `details`, `fleet`, and `asyncSnapshot`; the short summary intentionally omits canonical filesystem details, wait subscriptions, and budget annotations.
127
128
 
@@ -136,6 +137,7 @@ Capability advertisements on `ping`:
136
137
  - `resume` — the revival seam described above.
137
138
  - `statusProjection: { version: 1, untargeted: "in-memory-when-ready", targeted: "executor" }` — untargeted status may use restored bounded projections; targeted or rich status remains executor-backed.
138
139
  - `fleetStatus: { version: 1 }` — successful `status` replies additionally include `data.fleet`.
140
+ - `cost: { version: 1 }` — the `cost` method is available and returns the versioned report shape above.
139
141
 
140
142
  Structured delegation progress updates carry `runId` as soon as foreground execution allocates it, so a caller can retain the package-owned revival target even if its own tool turn is interrupted before the terminal response. Foreground `details.results[]` rows also include a numeric `index` that is unique within the run and stable across partial progress snapshots and the final result; use `(runId, index)` instead of row position to correlate single, counted parallel, and chain children.
141
143
 
@@ -435,7 +437,7 @@ The provider returns handles with `providerJobId`, `state`, optional `handleUrl`
435
437
 
436
438
  `followUp(input)` is optional. When it is present, a completed external-job run can be continued with `subagent({ action: "resume", id: "<run>", message: "..." })`. Pi sends the completed parent provider job id plus a stable `requestId` and `requestDigest`. The provider must continue that parent conversation or fail closed. It must not open a fresh thread when the parent conversation is missing.
437
439
 
438
- The async runner process does not import provider internals. It writes operation requests into its async run directory. The parent Pi process services those requests against the registered provider and writes operation responses. If the provider is not registered, the bridge fails closed with an actionable error. If a run is recovered after provider job metadata exists, the runner calls `reattach` and `result`; it does not call `start` or `follow-up` again.
440
+ The async runner process does not import provider internals. It writes operation requests into its async run directory. The Pi process of the session that launched the run services those requests against the registered provider and writes operation responses. A child session services the external-job runs it launches. Register the provider in that child too, for example through the child agent's `extensions`. If the provider is not registered, the bridge fails closed with an actionable error. If a run is recovered after provider job metadata exists, the runner calls `reattach` and `result`; it does not call `start` or `follow-up` again.
439
441
 
440
442
  ## Inspect integration
441
443
 
@@ -448,7 +450,69 @@ subagent({ action: "inspector.status", id: "<run-id>", index: 0 })
448
450
  subagent({ action: "inspector.close", id: "<run-id>", index: 0 })
449
451
  ```
450
452
 
451
- `inspector.command` returns a standalone runner command without contacting a host or writing a binding. `inspector.open` selects an available bundled inspector plugin. `status` and `close` select the plugin that owns the run binding and report clearly when that plugin does not support the requested lifecycle action. Without an available plugin, `open` fails closed with an actionable message; ordinary launches remain headless. Closing an inspector never stops the run.
453
+ `inspector.command` returns a standalone runner command without contacting a host or writing a binding. `inspector.open` selects an available built-in or externally registered inspector plugin. `status` and `close` select the plugin that owns the run binding and report clearly when that plugin does not support the requested lifecycle action. Without an available plugin, `open` fails closed with an actionable message; ordinary launches remain headless. Closing an inspector never stops the run.
454
+
455
+ ### Register an external inspector
456
+
457
+ A loaded Pi extension can add an inspector through the synchronous
458
+ `pi-subagents:inspector-register:v1` event. This lets terminal integrations use
459
+ Fleet's existing Enter/H actions without modifying pi-subagents. Registration
460
+ adds no runner, tool, or configuration option.
461
+
462
+ ```ts
463
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
464
+ import type { InspectorRegistration, InspectorRegistrationRequest } from "pi-subagents/inspectors";
465
+ import { myInspector } from "./my-inspector.ts"; // Your InspectorPlugin implementation.
466
+
467
+ export default function (pi: ExtensionAPI) {
468
+ let registration: InspectorRegistration | undefined;
469
+ pi.on("session_start", () => {
470
+ registration?.dispose();
471
+ const request: InspectorRegistrationRequest = { version: 1, plugin: myInspector };
472
+ pi.events.emit("pi-subagents:inspector-register:v1", request);
473
+ if (!request.result) throw new Error("pi-subagents inspector registration is unavailable.");
474
+ if (!request.result.ok) throw request.result.error;
475
+ registration = request.result.registration;
476
+ });
477
+ pi.on("session_shutdown", () => registration?.dispose());
478
+ }
479
+ ```
480
+
481
+ `pi-subagents/inspectors` exports the event name as `INSPECTOR_REGISTER_EVENT`,
482
+ the request and registration types, and the existing `InspectorPlugin`,
483
+ `InspectorContext`, `InspectorLaunch`, `InspectorParams`, and `InspectorTarget`
484
+ types. When pi-subagents is a resolvable dependency, `registerInspector(pi, plugin)`
485
+ emits the same request and returns the registration or throws. Independently
486
+ installed extensions can use the event directly; type-only imports need only a
487
+ development dependency and create no runtime module dependency.
488
+
489
+ An `InspectorPlugin` supplies:
490
+
491
+ - `name`: 1–128 letters, digits, dots, underscores, or hyphens, starting with a letter or digit.
492
+ - `available(context)`: whether this terminal host can open an inspector; may be async.
493
+ - `open(context, launch, params)`: open the supplied inspector command and return an `AgentToolResult<Details>`, like the built-in plugins. `launch.executable` and `launch.argv` carry the existing runner, target, trusted session roots, and steer/stop permission flags. Preserve these arguments and respect `params.focus`.
494
+ - `owns(context)`: synchronously check whether the provider owns an inspector binding for this target.
495
+ - Optional `status(context)` and `close(context)`: inspect or close that binding, returning the same result type. Closing an inspector must not stop the subagent.
496
+
497
+ The existing dispatcher tries Herdr, then Ghostty, then external providers in
498
+ registration order. Names are case-sensitive; duplicate names and the built-in
499
+ names `herdr` and `ghostty` are rejected. A selected provider's failure is not
500
+ retried through another provider. Status/close use the first provider whose
501
+ `owns` returns true; unavailable lifecycle methods remain explicit errors.
502
+ Providers own their pane bindings and must verify ownership before closing one.
503
+
504
+ Registrations belong to the pi-subagents runtimes listening on the Pi event bus,
505
+ not the consumer module; they survive runtime replacement, are isolated from
506
+ child runtimes and other Pi instances, and are cleared when the last owner shuts
507
+ down or reloads. Disposal is idempotent, removes callbacks without closing panes,
508
+ and takes effect even while Fleet is open because it resolves providers per
509
+ action. Providers receive the current action context, so do not capture a stale
510
+ session context; dispose before re-registering on session changes. Unsupported
511
+ versions and malformed plugins return `{ ok: false, error }`, and the first owner
512
+ to fill `result` handles the request.
513
+
514
+ This is a trusted-code integration, not a sandbox. Registration does not change
515
+ run resolution, child-safe restrictions, authority policy, or supervisor routing.
452
516
 
453
517
  ### Herdr inspector plugin
454
518
 
package/docs/models.md CHANGED
@@ -88,7 +88,7 @@ For a persistent role override:
88
88
 
89
89
  Set `fast: true` on a run, in agent frontmatter, or in `subagents.agentOverrides.<name>.fast` to request the OpenAI priority service tier for supported native OpenAI-Codex children. This can use a higher quota tier or cost more. It is off by default.
90
90
 
91
- Fast mode fails before launch unless the resolved model is on the allowlist. The current allowlist is `openai-codex/gpt-5.6-luna` and `openai-codex/gpt-5.6-sol`. External runners, Anthropic models, and other providers do not use fast mode.
91
+ Fast mode fails before launch unless the resolved model is a native `openai-codex/*` model. External runners, Anthropic models, and other providers do not use fast mode.
92
92
 
93
93
  ## Recommended model tiering (optional)
94
94
 
@@ -31,7 +31,7 @@ Or ask naturally: "Show me the current async runs."
31
31
 
32
32
  Run `/subagent-cost` for the parent session's combined parent and child token usage and cost. It includes completed async workflow children when their persisted receipts and metadata remain available. Missing child metadata is reported as unavailable when the receipt identifies that child. If the workflow receipt itself is missing, unreadable, invalid, or non-terminal, affected children can be omitted from the total without an unavailable count, so treat the result as a lower bound when run artifacts are unavailable.
33
33
 
34
- Pi's built-in session totals do not automatically include child usage delivered only by an async completion notification. Those notifications are custom messages, and Pi's public custom-message API does not carry accounted usage. `/subagent-cost` is therefore the supported accounting view for async child usage; do not infer child totals from Pi's footer or `/session` alone.
34
+ Pi's built-in session totals do not automatically include child usage delivered only by an async completion notification. Those notifications are custom messages, and Pi's public custom-message API does not carry accounted usage. `/subagent-cost` is therefore the supported accounting view for async child usage; do not infer child totals from Pi's footer or `/session` alone. Other extensions can read the same report as data through the in-process RPC `cost` method (see [extension-api.md](extension-api.md#in-process-event-bus-rpc)) instead of scraping the slash output.
35
35
 
36
36
  The under-editor async widget gives a short view while work runs. Its expand key follows your Pi keybinding:
37
37
 
@@ -206,16 +206,20 @@ Nested fanout status is stored as compact sidecar event/registry metadata and me
206
206
 
207
207
  Consumers should read these JSON files instead of scraping terminal output. Unknown fields and event types should be ignored for forward compatibility.
208
208
 
209
- RPC hosts that need low-latency child-stop UI hints can subscribe to the
210
- `subagent:child-status` event advertised by RPC `ping` as `events.childStatus`.
211
- The payload uses `type: "subagent.child-status"`, `version: 1`, `runId`,
212
- `childId`, `status` (`"stopping"` or `"stopped"`), `ts`, and optional child
213
- metadata such as `stepIndex`, `agent`, `childRunId`, `workflowKey`, `phase`, and
214
- `label`. These events are observer hints only. They can duplicate across RPC and
215
- async replay paths, and they are not replayed after a host restart. Status
216
- snapshots remain authoritative for recovery and final state. Child stop control
217
- still uses the normal `stop` request with `childId`; there is no separate child
218
- stop API.
209
+ Companion UIs and RPC hosts that need low-latency child lifecycle hints can
210
+ subscribe to the `subagent:child-status` event advertised by RPC `ping` as
211
+ `events.childStatus`. The payload uses `type: "subagent.child-status"`,
212
+ `version: 1`, `runId`, `childId`, `status` (`"started"`, `"stopping"`, or
213
+ `"stopped"`), `ts`, and optional child metadata such as `asyncDir`, `stepIndex`,
214
+ `agent`, `childRunId`, `workflowKey`, `phase`, and `label`. Async
215
+ `workflowScript` roots emit `"started"` once the keyed child has a concrete
216
+ launch identity; `childId` and `workflowKey` are the stable workflow key, while
217
+ `stepIndex` is only a convenience projection for the current status snapshot.
218
+ These events are observer hints only. They can duplicate across the live event
219
+ bus and async replay paths, and they are not replayed after a host restart.
220
+ Status snapshots remain authoritative for recovery and final state. Child stop
221
+ control still uses the normal `stop` request with `childId`; there is no separate
222
+ child stop API.
219
223
 
220
224
  ### Status and result fields
221
225
 
@@ -296,7 +300,7 @@ Session files are stored under a per-run session directory. With `context: "fork
296
300
 
297
301
  ## Completion notifications
298
302
 
299
- Async completions belong only to the originating session. The result watcher emits `subagent:async-complete`, and the extension consumes that event to record completion state.
303
+ Async completions belong only to the originating session. The result watcher emits `subagent:async-complete` for detached runs. Awaited workflow children emit it when they settle, with `awaitedByWorkflow: true`, `parentWorkflowRunId`, and `triggerTurn: false`. They do not send a separate child notification or turn.
300
304
 
301
305
  Successful sibling completions are held briefly and delivered as a quiet grouped completion when they finish within a short window (see `completionBatch` in [configuration.md](configuration.md)), avoiding unread markers on inactive tabs. Failed and paused completions remain visible and fire immediately.
302
306
 
@@ -307,7 +311,7 @@ Async events:
307
311
  - `subagent:async-started`
308
312
  - `subagent:async-complete`
309
313
 
310
- The `subagent:async-started` payload includes `task`, the backwards-compatible first child task truncated to 50 characters, and `goal`, the workflow-level caller task truncated to 120 characters (falling back to the first child task). Companion UI extensions can combine `goal`, `workflowGraph`, and the live lifecycle artifacts under `asyncDir` without scraping terminal output.
314
+ For regular async starts, the `subagent:async-started` payload includes redacted `task` and `goal` prompt fields. Async `workflowScript` roots emit the same event with `mode: "workflow"` after their initial `status.json` is durable; workflow roots can omit `task`, and any included prompt fields are redacted. Their keyed children are then announced dynamically through `subagent:child-status`. Companion UI extensions can combine those hints with the authoritative live lifecycle artifacts under `asyncDir` without scraping terminal output.
311
315
 
312
316
  Intercom delivery events:
313
317
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  Parameters and actions for the `subagent` tool. These are what the LLM passes when it calls the tool; most users ask naturally or use slash commands instead.
4
4
 
5
+ In a fresh parent session, `subagents_enable({})` makes the full `subagent` tool available on the immediately following model request without launching work. Pi may call it when delegation is authorized by the current request or applicable instructions, or to manage existing runs. Direct execution remains the default; task complexity does not grant delegation authority. The public `subagent` name and parameters are unchanged after activation.
6
+
5
7
  Call `{ action: "guide", topic: "tool-reference" }` for this reference or `topic: "workflows"` for [workflow recipes](workflows.md). Use `topic: "agents"` for authoring, `topic: "missions"` for missions/schedules, and `topic: "watchdog"` for watchdog controls. Guide reads do not change the schema or grant authority.
6
8
 
7
9
  ## Execution examples
@@ -93,9 +95,9 @@ The complete plain-JSON inventory is validated before the first launch (maximum
93
95
  | `agent` | string | - | One direct child or agent-management target. Workflow child agents are set inside `runs.run` or `runs.all`. |
94
96
  | `task` | string | agent default | Direct child's task; requires `agent`, excludes `action` and workflow inputs. `agent` may also select a management target. |
95
97
  | `action` | string | - | Offline workflow `validate`, agent management (including `guide`, `children.list`, and `refine`/`refine.show`/`refine.rollback`), lane evidence (`lane.status`, `lane.recordMerge`, `lane.recordSupersession`), mission (`mission.create/list/show/update/resolve-decision/attach-run/close`), Inspect actions (`inspector.command/open/status/close`), Herdr project pane (`project.open/status/close`), status/control, plan-only `worktree.cleanup`, schedule, watchdog, or doctor action. |
96
- | `topic` | `overview \| workflows \| agents \| missions \| observability \| tool-reference \| configuration \| models \| watchdog \| extension-api` | `overview` | Packaged guide topic for `action: "guide"`. |
98
+ | `topic` | `overview \| workflows \| agents \| missions \| observability \| tool-reference \| configuration \| models \| watchdog \| extension-api \| council` | `overview` | Packaged guide topic for `action: "guide"`. |
97
99
  | `config` | object/string | - | Agent config for management create/update. |
98
- | `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`, `oracle`, and `advisor` default to `fork`. |
100
+ | `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`. |
99
101
  | `model` | string | agent default | Call `{action:"models"}` first and copy an exact `provider/id`; bare ids resolve only if unique, and agent names are not model ids. 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. |
100
102
  | `missionId` | string | - | Attach a workflow to an existing project mission instead of creating its default enclosing mission. |
101
103
  | `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. |
@@ -115,11 +117,13 @@ The complete plain-JSON inventory is validated before the first launch (maximum
115
117
  | `chatProgress` | `auto \| off \| live-card` | `auto` | WorkflowScript chat projection. `auto` renders a live in-chat card only for watched foreground workflows in the same Git repository, including managed worktrees; it is off otherwise. Explicit `live-card` requires `async:false` and the same Git repository. Async workflows have no inline live card, so omit `chatProgress` or use `auto`/`off`; use `async:false` only when the parent must block. |
116
118
  | `isolation` | `none \| worktree` | - | Workflow child isolation. `none` runs in the shared cwd and does not need Git. `worktree` requires a managed Git worktree. Do not combine it with a contradictory `worktree` value. |
117
119
  | `baseRef` | string | `HEAD` | `HEAD` or a supported named ref such as `refs/heads/release`, `refs/tags/v1`, or `origin/main`. Full 40/64-character commit IDs and revision expressions such as `HEAD~1` are unsupported. The ref must resolve to a commit at worktree allocation; omitted values default to `HEAD` resolved at that time. Source-checkout cleanliness is still checked. For workflowScript, set it on the outer request as a default or on an individual `runs.run`/`runs.all` child to override it. |
118
- | `timeoutMs` / `maxRuntimeMs` | number | config `timeoutMs`, else 30 min foreground / single-agent async | Optional run-level max runtime in milliseconds. When omitted, the global [`timeoutMs`](configuration.md#timeoutms) config provides the default; absent that, foreground and plain single-agent async runs fall back to 30 minutes, while composite async runs (chains, parallel tasks, workflows) stay unbounded at the top level. Expiration of this run-level deadline is terminal. |
120
+ | `timeoutMs` / `maxRuntimeMs` | number | config `timeoutMs`, else 30 min foreground / single-agent async | Optional run-level max runtime in milliseconds. Both aliases may be supplied only when their values agree. When omitted, the global [`timeoutMs`](configuration.md#timeoutms) config provides the default; absent that, foreground and plain single-agent async runs fall back to 30 minutes, while composite async runs (chains, parallel tasks, workflows) stay unbounded at the top level. Expiration of this run-level deadline is terminal. |
119
121
  | `toolTimeoutMs` | number | fast-tool default | Optional positive hard per-tool-call deadline in milliseconds. Precedence: call value → agent frontmatter → config → `PI_SUBAGENT_TOOL_TIMEOUT_MS`. The timer starts on `tool_execution_start`, clears on the matching `tool_execution_end`, and terminates the run with `timedOut: true` if the tool remains open. When omitted, known-fast built-in tools get a five-minute default; long-running tools get attention notices but no hard default. It never extends the run deadline; `contact_supervisor`, `intercom`, and `bg_wait` are exempt. |
120
122
  | `checkpointBeforeDeadlineMs` | number | none | Async single-agent runs only. The runner requests that the child "checkpoint and stop" this many milliseconds before the run deadline (finish the current tool call, report changed files, build/test state, remaining work, commit/PR state; start no new work). This best-effort steer uses the normal steering lifecycle at the next tool boundary, so the receipt is visible in status and events; the ordinary deadline kill still applies. Precedence: call value → config `checkpointBeforeDeadlineMs`. Disarmed when the deadline leaves under one second before the checkpoint. |
121
- | `toolBudget` | object | none | Optional child tool-call budget `{ soft?, hard, block? }`. At `soft` the child is nudged to finalize. After `hard`, configured tools are blocked; `block` defaults to `read`, `grep`, `find`, and `ls`, while `"*"` blocks every tool call. Final assistant text is never blocked. |
122
- | `usageBudget` | object | none | Optional root-only reported-usage budget `{ tokens?: { soft?, hard }, costUsd?: { soft?, hard } }`. Soft limits are status-only. Hard limits prevent later child launches after reported usage is reconciled; already-running children are not stopped and no reservations are made. |
123
+ | `toolBudget` | object | none | Optional child tool-call budget `{ soft?, hard, block? }`: `hard` is a positive integer and `soft`, if set, is a positive integer no greater than `hard`. At `soft` the child is nudged to finalize. After `hard`, configured tools are blocked; `block` defaults to `read`, `grep`, `find`, and `ls`, and accepts either a nonempty array of tool names or `"*"` for every tool call. Final assistant text is never blocked. |
124
+ | `usageBudget` | object | none | Optional root-only reported-usage budget `{ tokens?: { soft?, hard }, costUsd?: { soft?, hard } }`. Include at least one metric; each `hard` must be positive and each optional `soft` positive and no greater than its `hard`. Soft limits are status-only. Hard limits prevent later child launches after reported usage is reconciled; already-running children are not stopped and no reservations are made. |
125
+ | `extensionBindings` | object | none | Child-only plain JSON keyed by namespaces like `package.name/1` (positive version): at most 16 namespaces, nesting depth 16, 256 total object properties, and 16 KiB of canonical UTF-8 JSON. Native Pi launches only; external runners and retained resumes reject it. |
126
+ | `preflight` | object | none | Advisory lane hints for `workflowScript` or `workflowScriptPath` only; not accepted with named workflows or direct children. See [bounded workflows](workflows.md#opt-in-bounded-workflows). |
123
127
  | `cwd` | string | runtime cwd | Override working directory. With `machine`, the directory on that machine. |
124
128
  | `machine` | string | - | Herdr saved machine (label or profile id) for external-cli agents; see [agents.md](agents.md#running-external-cli-agents-on-a-herdr-saved-machine). |
125
129
  | `maxOutput` | object | none | Final output truncation limits `{ bytes?, lines? }`. Only applied when set; there is no default cap on the inline path, so use `outputMode: "file-only"` for large outputs. |
@@ -142,7 +146,7 @@ Explicit `context: "fork"` fails fast when the parent session is not persisted,
142
146
 
143
147
  When the inherited transcript contains signed Anthropic `thinking` / `redacted_thinking` blocks, `pi-subagents` strips those provider-private blocks from the forked child session: a thinking signature is bound to the session that produced it and cannot be replayed into a branch. The child keeps its requested thinking level and reasons fresh from its first turn; sanitizing the inherited transcript is not a downgrade. Explicit `context: "fork"` never silently downgrades to `fresh`.
144
148
 
145
- In workflow runs that omit `context`, each `runs.run` child follows the global `defaultSubagentContext` when set, then its own `defaultContext`. Without the global setting, a fresh-default scout can run fresh beside a fork-default worker. If the parent session file or current leaf is not available yet, implicit fork-default children run fresh. Pass explicit `context: "fork"` or `context: "fresh"` when you intentionally want one context for every child.
149
+ In workflow runs that omit `context`, each `runs.run` child follows the global `defaultSubagentContext` when set, then its own `defaultContext`. Without the global setting, a fresh-default worker can run fresh beside a fork-default oracle. If the parent session file or current leaf is not available yet, implicit fork-default children run fresh. Pass explicit `context: "fork"` or `context: "fresh"` when you intentionally want one context for every child.
146
150
 
147
151
  ### Workflow steering
148
152
 
@@ -179,7 +183,7 @@ Workflows get `await state.get(key)` and `await state.set(key, value)` through t
179
183
 
180
184
  ### Retained children
181
185
 
182
- Completed workflow children from the current parent session stay addressable as retained children. `{ action: "children.list" }` lists up to the last 10 with their run ids and explicit `resumable` or `not resumable` state. Resume only rows reported `resumable`; if no row is resumable, start a same-role fallback challenge and label it as fallback. A later workflow continues a resumable child by passing `resume` instead of `agent`:
186
+ Completed workflow children from the current parent session stay addressable as retained children. `{ action: "children.list" }` lists up to the last 10 with their run ids and explicit `resumable` or `not resumable` state. 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 `{ action: "status", id: "<run-id>" }`; if status identifies the candidate, attempt `{ action: "resume", id: "<run-id>", message: "..." }`. Resume performs the authoritative eligibility check and may reject the attempt. Start 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 by passing `resume` instead of `agent`:
183
187
 
184
188
  ```js
185
189
  { workflowScript: `
@@ -196,7 +200,7 @@ Each workflow key identifies one result lane. Use a new stable workflow key for
196
200
 
197
201
  Inside `workflowScript`, `await runs.run(key, { resume, task })` waits for the revived child to finish and returns its completed output and new `runId`. Each resume can return a new retained run id, so loops must continue from the latest returned `runId`. Top-level `{ action: "resume" }` remains detached and returns a background-run receipt.
198
202
 
199
- For a simple implementation challenge outside a workflow script, send the challenge through `subagent({ action: "resume", id: "<retained-writer-run>", message: "Reconsider the implementation and make any better current-scope change." })` only when `children.list` reports that retained writer as `resumable`. If no retained writer is resumable, start a same-role fallback challenge and record why it is a fallback. Use workflow `runs.run({ resume })` only when the script must await the revived writer output before the next step. Do not use `steer` as the sole challenge action for a completed retained child; `steer` with `mode: "follow_up"` only queues text for the next `resume`.
203
+ For a simple implementation challenge outside a workflow script, send the challenge through `subagent({ action: "resume", id: "<retained-writer-run>", message: "Reconsider the implementation and make any better current-scope change." })` when `children.list` reports that retained writer as `resumable`, or attempt it after exact-id status inspection identifies a known direct-child candidate. Status is advisory; resume authoritatively checks eligibility and may reject missing recovery requirements. If there is no known candidate or resume rejects eligibility, start a same-role fallback challenge and record why it is a fallback. Use workflow `runs.run({ resume })` only when the script must await the revived writer output before the next step. Do not use `steer` as the sole challenge action for a completed retained child; `steer` with `mode: "follow_up"` only queues text for the next `resume`.
200
204
 
201
205
  `resume` and `agent` are mutually exclusive. The revived child keeps its stored agent, model, and tool contract. `gate` is rejected on retained resume items because resume uses the retained child contract.
202
206
 
@@ -204,7 +208,7 @@ For a simple implementation challenge outside a workflow script, send the challe
204
208
 
205
209
  ### Guide
206
210
 
207
- `{ action: "guide" }` reads the packaged `README.md` from the installed version. Pass `topic` to read its packaged `docs/<topic>.md` file instead. Valid topics are `overview`, `workflows`, `agents`, `missions`, `observability`, `tool-reference`, `configuration`, `models`, `watchdog`, and `extension-api`. Unknown topics list the valid values and do not change files. Use `/subagents-guide [topic]` for the slash equivalent.
211
+ `{ action: "guide" }` reads the packaged `README.md` from the installed version. Pass `topic` to read its packaged `docs/<topic>.md` file instead; see the `topic` parameter table for valid values. The `council` topic returns the packaged `skills/council-mode/SKILL.md` with the references it asks for, so `/council` works when Pi runs with `--no-skills`. Unknown topics list the valid values and do not change files. Use `/subagents-guide [topic]` for the slash equivalent.
208
212
 
209
213
  Agent definitions are not loaded into context by default. Management actions let the LLM discover, inspect, create, update, and delete agents at runtime. An unknown action returns safe next steps (`status` and `list`) and may suggest a close non-destructive action. Destructive actions are only named for a near-complete one-character typo, and suggestions never execute an action.
210
214
 
@@ -349,7 +353,7 @@ subagent({ action: "doctor" })
349
353
 
350
354
  - Multi-child async runs and remembered foreground single, parallel, or chain runs can be revived by passing `index` to choose the child.
351
355
  - Nested runs can be resumed by nested id when their live route or persisted nested session metadata is available.
352
- - Completed external-job 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.
356
+ - 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.
353
357
  - 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.
354
358
  - 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.
355
359
 
package/docs/workflows.md CHANGED
@@ -10,7 +10,7 @@ Use orchestration as parent-agent guidance, not as a runtime workflow mode. For
10
10
  clarify → scout → worker → fresh reviewers → worker
11
11
  ```
12
12
 
13
- Packaged `worker`, `oracle`, and `advisor` default to forked context when a launch omits `context`. If the parent has no persisted session file or current leaf yet, that implicit default falls back to `fresh`. Pass `context: "fresh"` when you intentionally want a fresh child run, or `context: "fork"` when fork must remain strict.
13
+ Packaged `worker` defaults to fresh context so implementation starts from its assigned brief instead of the parent's unfinished conversation. Packaged `oracle` and `advisor` default to forked context; if the parent has no persisted session file or current leaf yet, that implicit default falls back to `fresh`. Explicit `context`, `context: "profile"`, and global `defaultSubagentContext` still override these profile defaults.
14
14
 
15
15
  Child-safety boundaries are enforced at runtime:
16
16
 
@@ -118,6 +118,8 @@ subagent({
118
118
 
119
119
  These controls are opt-in. Avoid tight hard budgets for mutation-capable workers unless the workflow has an explicit checkpoint and handoff path.
120
120
 
121
+ The optional `preflight` lane hints apply only to raw `workflowScript` or `workflowScriptPath` requests, not named workflows or direct child calls. They are display-only: mismatched coverage warns but never changes execution authority.
122
+
121
123
  The result is `{ ok, errors }`. Invalid scripts return a tool error and include line and column data when available. Validation checks syntax, portable nested-async rules, literal `runs.run` and `runs.all` keys and child `baseRef` values, duplicate literal keys in one `runs.all` group, direct keyed access to a known `runs.all` result, and statically clear non-JSON boundary values. Dynamic keys and other runtime-only values are accepted without a warning. Validation does not discover agents, launch children, or create run artifacts.
122
124
 
123
125
  ```js
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "pi-subagents",
4
- "version": "0.70.1",
4
+ "version": "0.72.0",
5
5
  "description": "Pi extension for single-agent delegation and scripted multi-agent workflows",
6
6
  "author": "Nico Bailon",
7
7
  "license": "MIT",
@@ -19,15 +19,15 @@
19
19
  "dependencies": {
20
20
  "acorn": "8.18.0",
21
21
  "jiti": "2.7.0",
22
- "typebox": "1.1.38",
23
22
  "undici": "8.10.0",
24
23
  "yaml": "2.8.3"
25
24
  },
26
25
  "peerDependencies": {
27
26
  "@earendil-works/pi-agent-core": "*",
28
- "@earendil-works/pi-ai": ">=0.80.0",
27
+ "@earendil-works/pi-ai": ">=0.86.1",
29
28
  "@earendil-works/pi-coding-agent": "*",
30
- "@earendil-works/pi-tui": "*"
29
+ "@earendil-works/pi-tui": "*",
30
+ "typebox": "*"
31
31
  },
32
32
  "peerDependenciesMeta": {
33
33
  "@earendil-works/pi-agent-core": {
@@ -41,6 +41,9 @@
41
41
  },
42
42
  "@earendil-works/pi-tui": {
43
43
  "optional": true
44
+ },
45
+ "typebox": {
46
+ "optional": true
44
47
  }
45
48
  },
46
49
  "keywords": [
@@ -74,6 +77,10 @@
74
77
  "types": "./src/api/agents.d.ts",
75
78
  "default": "./src/api/agents.js"
76
79
  },
80
+ "./inspectors": {
81
+ "types": "./src/api/inspectors.d.ts",
82
+ "default": "./src/api/inspectors.js"
83
+ },
77
84
  "./delegation": {
78
85
  "types": "./src/api/delegation.d.ts",
79
86
  "default": "./src/api/delegation.js"