@fitchmultz/pi-subagents 0.0.0-stage → 0.44.4

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 (342) hide show
  1. package/CHANGELOG.md +1645 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1529 -2
  4. package/agents/context-builder.md +97 -0
  5. package/agents/debugger.md +51 -0
  6. package/agents/delegate.md +13 -0
  7. package/agents/fixer.md +37 -0
  8. package/agents/oracle.md +71 -0
  9. package/agents/planner.md +72 -0
  10. package/agents/researcher.md +51 -0
  11. package/agents/reviewer-claude.md +69 -0
  12. package/agents/reviewer-gpt.md +68 -0
  13. package/agents/reviewer-ponytail.md +82 -0
  14. package/agents/reviewer-security.md +81 -0
  15. package/agents/reviewer.md +69 -0
  16. package/agents/scout.md +66 -0
  17. package/agents/ui-designer.md +51 -0
  18. package/agents/watcher.md +26 -0
  19. package/agents/worker.md +46 -0
  20. package/agents/writer.md +36 -0
  21. package/dist/agents/agent-management.js +923 -0
  22. package/dist/agents/agent-scope.js +7 -0
  23. package/dist/agents/agent-selection.js +20 -0
  24. package/dist/agents/agent-serializer.js +100 -0
  25. package/dist/agents/agents.js +752 -0
  26. package/dist/agents/chain-serializer.js +367 -0
  27. package/dist/agents/frontmatter.js +21 -0
  28. package/dist/agents/identity.js +29 -0
  29. package/dist/agents/skills.js +570 -0
  30. package/dist/extension/build-info.js +1 -0
  31. package/dist/extension/compact-tools.js +112 -0
  32. package/dist/extension/config.js +22 -0
  33. package/dist/extension/control-notices.js +29 -0
  34. package/dist/extension/doctor.js +143 -0
  35. package/dist/extension/fanout-child.js +326 -0
  36. package/dist/extension/index.js +577 -0
  37. package/dist/extension/schemas.js +416 -0
  38. package/dist/extension/tool-input.js +20 -0
  39. package/dist/extension/tool-result.js +14 -0
  40. package/dist/history/canonical-result.js +81 -0
  41. package/dist/history/database.js +72 -0
  42. package/dist/history/index.js +194 -0
  43. package/dist/history/ingest.js +447 -0
  44. package/dist/history/queries.js +350 -0
  45. package/dist/history/store.js +216 -0
  46. package/dist/history/types.js +4 -0
  47. package/dist/history/worker.js +461 -0
  48. package/dist/intercom/intercom-bridge.js +112 -0
  49. package/dist/intercom/live-intercom.js +94 -0
  50. package/dist/intercom/result-intercom.js +373 -0
  51. package/dist/pi-intercom/agent-dir.js +10 -0
  52. package/dist/pi-intercom/broker/broker.js +426 -0
  53. package/dist/pi-intercom/broker/client.js +492 -0
  54. package/dist/pi-intercom/broker/framing.js +65 -0
  55. package/dist/pi-intercom/broker/paths.js +42 -0
  56. package/dist/pi-intercom/broker/pid.js +66 -0
  57. package/dist/pi-intercom/broker/spawn.js +221 -0
  58. package/dist/pi-intercom/config.js +102 -0
  59. package/dist/pi-intercom/index.js +2942 -0
  60. package/dist/pi-intercom/reply-tracker.js +182 -0
  61. package/dist/pi-intercom/session-targets.js +128 -0
  62. package/dist/pi-intercom/subagent-live-events.js +132 -0
  63. package/dist/pi-intercom/topics.js +157 -0
  64. package/dist/pi-intercom/types.js +163 -0
  65. package/dist/pi-intercom/ui/compose.js +269 -0
  66. package/dist/pi-intercom/ui/inline-message.js +80 -0
  67. package/dist/pi-intercom/ui/session-list.js +124 -0
  68. package/dist/runs/background/async-control.js +95 -0
  69. package/dist/runs/background/async-execution.js +676 -0
  70. package/dist/runs/background/async-job-tracker.js +383 -0
  71. package/dist/runs/background/async-result-file.js +58 -0
  72. package/dist/runs/background/async-resume.js +305 -0
  73. package/dist/runs/background/async-status.js +442 -0
  74. package/dist/runs/background/completion-dedupe.js +69 -0
  75. package/dist/runs/background/completion-delivery.js +245 -0
  76. package/dist/runs/background/notify.js +71 -0
  77. package/dist/runs/background/parallel-groups.js +55 -0
  78. package/dist/runs/background/result-watcher.js +426 -0
  79. package/dist/runs/background/run-id-resolver.js +64 -0
  80. package/dist/runs/background/run-status.js +382 -0
  81. package/dist/runs/background/stale-run-reconciler.js +335 -0
  82. package/dist/runs/background/subagent-runner-launcher.js +55 -0
  83. package/dist/runs/background/subagent-runner.js +1872 -0
  84. package/dist/runs/background/top-level-async.js +5 -0
  85. package/dist/runs/foreground/chain-clarify.js +1152 -0
  86. package/dist/runs/foreground/clarify-invocation.js +72 -0
  87. package/dist/runs/foreground/execution-input.js +423 -0
  88. package/dist/runs/foreground/foreground-control.js +817 -0
  89. package/dist/runs/foreground/question-control.js +77 -0
  90. package/dist/runs/foreground/run-async-path.js +205 -0
  91. package/dist/runs/foreground/subagent-executor.js +442 -0
  92. package/dist/runs/foreground/subagent-params.js +165 -0
  93. package/dist/runs/foreground/wait-run.js +139 -0
  94. package/dist/runs/shared/acceptance-contract.js +253 -0
  95. package/dist/runs/shared/acceptance-evaluation.js +256 -0
  96. package/dist/runs/shared/acceptance-finalization.js +280 -0
  97. package/dist/runs/shared/acceptance-reports.js +147 -0
  98. package/dist/runs/shared/acceptance.js +4 -0
  99. package/dist/runs/shared/chain-outputs.js +110 -0
  100. package/dist/runs/shared/child-attempt.js +693 -0
  101. package/dist/runs/shared/child-execution-cwd.js +96 -0
  102. package/dist/runs/shared/child-observations.js +114 -0
  103. package/dist/runs/shared/claude-code.js +199 -0
  104. package/dist/runs/shared/completion-guard.js +31 -0
  105. package/dist/runs/shared/dynamic-fanout.js +274 -0
  106. package/dist/runs/shared/history-index.js +72 -0
  107. package/dist/runs/shared/mcp-direct-tool-allowlist.js +334 -0
  108. package/dist/runs/shared/model-fallback.js +185 -0
  109. package/dist/runs/shared/mutating-tool-guard.js +170 -0
  110. package/dist/runs/shared/native-finalization.js +101 -0
  111. package/dist/runs/shared/native-usage.js +153 -0
  112. package/dist/runs/shared/nested-events.js +700 -0
  113. package/dist/runs/shared/nested-path.js +48 -0
  114. package/dist/runs/shared/nested-render.js +108 -0
  115. package/dist/runs/shared/parallel-utils.js +61 -0
  116. package/dist/runs/shared/parent-receipts.js +68 -0
  117. package/dist/runs/shared/parent-usage.js +121 -0
  118. package/dist/runs/shared/pi-args.js +310 -0
  119. package/dist/runs/shared/pi-spawn.js +52 -0
  120. package/dist/runs/shared/run-history-queries.js +45 -0
  121. package/dist/runs/shared/run-history.js +103 -0
  122. package/dist/runs/shared/run-id-ambiguity.js +4 -0
  123. package/dist/runs/shared/run-records.js +679 -0
  124. package/dist/runs/shared/session-cwd-preload.js +33 -0
  125. package/dist/runs/shared/single-output.js +222 -0
  126. package/dist/runs/shared/streaming-text.js +15 -0
  127. package/dist/runs/shared/structured-output.js +55 -0
  128. package/dist/runs/shared/subagent-control.js +179 -0
  129. package/dist/runs/shared/subagent-prompt-runtime.js +197 -0
  130. package/dist/runs/shared/subagent-tool-loop-guard.js +66 -0
  131. package/dist/runs/shared/supervisor-questions.js +320 -0
  132. package/dist/runs/shared/workflow-graph.js +214 -0
  133. package/dist/runs/shared/workflow-policy.js +84 -0
  134. package/dist/runs/shared/worktree.js +525 -0
  135. package/dist/shared/agent-context-policy.js +126 -0
  136. package/dist/shared/artifacts.js +96 -0
  137. package/dist/shared/atomic-json.js +13 -0
  138. package/dist/shared/cooperative.js +20 -0
  139. package/dist/shared/execution-cwd.js +14 -0
  140. package/dist/shared/file-coalescer.js +21 -0
  141. package/dist/shared/fork-context.js +49 -0
  142. package/dist/shared/formatters.js +85 -0
  143. package/dist/shared/journal-reader.js +407 -0
  144. package/dist/shared/lazy-tools.js +32 -0
  145. package/dist/shared/model-info.js +68 -0
  146. package/dist/shared/native-session.js +15 -0
  147. package/dist/shared/native-tui.js +18 -0
  148. package/dist/shared/native-typebox.js +20 -0
  149. package/dist/shared/post-exit-stdio-guard.js +197 -0
  150. package/dist/shared/prompt-sections.js +8 -0
  151. package/dist/shared/session-entries.js +52 -0
  152. package/dist/shared/session-identity.js +14 -0
  153. package/dist/shared/settings.js +254 -0
  154. package/dist/shared/status-format.js +111 -0
  155. package/dist/shared/temp-root.js +114 -0
  156. package/dist/shared/types.js +207 -0
  157. package/dist/shared/ui-mode.js +3 -0
  158. package/dist/shared/utils.js +334 -0
  159. package/dist/slash/prompt-template-bridge.js +298 -0
  160. package/dist/slash/slash-bridge.js +116 -0
  161. package/dist/slash/slash-commands.js +607 -0
  162. package/dist/slash/slash-live-state.js +246 -0
  163. package/dist/tui/action-hints.js +75 -0
  164. package/dist/tui/agent-history.js +197 -0
  165. package/dist/tui/agent-view.js +1656 -0
  166. package/dist/tui/render.js +1515 -0
  167. package/docs/intercom.md +579 -0
  168. package/docs/performance.md +121 -0
  169. package/package.json +101 -4
  170. package/prompts/gather-context-and-clarify.md +14 -0
  171. package/prompts/parallel-cleanup.md +62 -0
  172. package/prompts/parallel-context-build.md +56 -0
  173. package/prompts/parallel-handoff-plan.md +62 -0
  174. package/prompts/parallel-research.md +51 -0
  175. package/prompts/parallel-review.md +59 -0
  176. package/prompts/review-loop.md +42 -0
  177. package/scripts/build.mjs +134 -0
  178. package/scripts/check-compat.mjs +48 -0
  179. package/scripts/compat-host.mjs +19 -0
  180. package/scripts/linux-smoke.sh +51 -0
  181. package/scripts/local-install-smoke.mjs +66 -0
  182. package/scripts/native-package-smoke.mjs +82 -0
  183. package/scripts/package-smoke.mjs +205 -0
  184. package/scripts/prepare.mjs +67 -0
  185. package/scripts/real-pi-smoke.mjs +415 -0
  186. package/scripts/run-tests.mjs +149 -0
  187. package/skills/pi-intercom/SKILL.md +113 -0
  188. package/skills/pi-intercom/evals/evals.json +29 -0
  189. package/skills/pi-intercom/evals/trigger-evals.json +47 -0
  190. package/skills/pi-intercom/references/peer-sessions.md +69 -0
  191. package/skills/pi-subagents/SKILL.md +76 -0
  192. package/skills/pi-subagents/evals/evals.json +29 -0
  193. package/skills/pi-subagents/evals/trigger-evals.json +42 -0
  194. package/skills/pi-subagents/references/full-orchestration-guide.md +863 -0
  195. package/src/agents/agent-management.ts +813 -0
  196. package/src/agents/agent-scope.ts +7 -0
  197. package/src/agents/agent-selection.ts +23 -0
  198. package/src/agents/agent-serializer.ts +99 -0
  199. package/src/agents/agents.ts +916 -0
  200. package/src/agents/chain-serializer.ts +329 -0
  201. package/src/agents/frontmatter.ts +21 -0
  202. package/src/agents/identity.ts +30 -0
  203. package/src/agents/skills.ts +637 -0
  204. package/src/extension/build-info.ts +2 -0
  205. package/src/extension/compact-tools.ts +114 -0
  206. package/src/extension/config.ts +23 -0
  207. package/src/extension/control-notices.ts +47 -0
  208. package/src/extension/doctor.ts +171 -0
  209. package/src/extension/fanout-child.ts +312 -0
  210. package/src/extension/index.ts +649 -0
  211. package/src/extension/schemas.ts +444 -0
  212. package/src/extension/tool-input.ts +19 -0
  213. package/src/extension/tool-result.ts +16 -0
  214. package/src/history/canonical-result.ts +62 -0
  215. package/src/history/database.ts +59 -0
  216. package/src/history/index.ts +152 -0
  217. package/src/history/ingest.ts +332 -0
  218. package/src/history/queries.ts +241 -0
  219. package/src/history/store.ts +203 -0
  220. package/src/history/types.ts +166 -0
  221. package/src/history/worker.ts +317 -0
  222. package/src/intercom/intercom-bridge.ts +123 -0
  223. package/src/intercom/live-intercom.ts +104 -0
  224. package/src/intercom/result-intercom.ts +429 -0
  225. package/src/pi-intercom/agent-dir.ts +9 -0
  226. package/src/pi-intercom/broker/broker.ts +463 -0
  227. package/src/pi-intercom/broker/client.ts +558 -0
  228. package/src/pi-intercom/broker/framing.ts +77 -0
  229. package/src/pi-intercom/broker/paths.ts +47 -0
  230. package/src/pi-intercom/broker/pid.ts +59 -0
  231. package/src/pi-intercom/broker/spawn.ts +248 -0
  232. package/src/pi-intercom/config.ts +142 -0
  233. package/src/pi-intercom/index.ts +2929 -0
  234. package/src/pi-intercom/reply-tracker.ts +211 -0
  235. package/src/pi-intercom/session-targets.ts +172 -0
  236. package/src/pi-intercom/subagent-live-events.ts +133 -0
  237. package/src/pi-intercom/topics.ts +125 -0
  238. package/src/pi-intercom/types.ts +271 -0
  239. package/src/pi-intercom/ui/compose.ts +289 -0
  240. package/src/pi-intercom/ui/inline-message.ts +92 -0
  241. package/src/pi-intercom/ui/session-list.ts +139 -0
  242. package/src/runs/background/async-control.ts +89 -0
  243. package/src/runs/background/async-execution.ts +850 -0
  244. package/src/runs/background/async-job-tracker.ts +385 -0
  245. package/src/runs/background/async-result-file.ts +62 -0
  246. package/src/runs/background/async-resume.ts +333 -0
  247. package/src/runs/background/async-status.ts +481 -0
  248. package/src/runs/background/completion-dedupe.ts +79 -0
  249. package/src/runs/background/completion-delivery.ts +195 -0
  250. package/src/runs/background/notify.ts +123 -0
  251. package/src/runs/background/parallel-groups.ts +53 -0
  252. package/src/runs/background/result-watcher.ts +423 -0
  253. package/src/runs/background/run-id-resolver.ts +69 -0
  254. package/src/runs/background/run-status.ts +384 -0
  255. package/src/runs/background/stale-run-reconciler.ts +369 -0
  256. package/src/runs/background/subagent-runner-launcher.ts +56 -0
  257. package/src/runs/background/subagent-runner.ts +2053 -0
  258. package/src/runs/background/top-level-async.ts +13 -0
  259. package/src/runs/foreground/chain-clarify.ts +1340 -0
  260. package/src/runs/foreground/clarify-invocation.ts +77 -0
  261. package/src/runs/foreground/execution-input.ts +467 -0
  262. package/src/runs/foreground/foreground-control.ts +821 -0
  263. package/src/runs/foreground/question-control.ts +70 -0
  264. package/src/runs/foreground/run-async-path.ts +243 -0
  265. package/src/runs/foreground/subagent-executor.ts +501 -0
  266. package/src/runs/foreground/subagent-params.ts +320 -0
  267. package/src/runs/foreground/wait-run.ts +121 -0
  268. package/src/runs/shared/acceptance-contract.ts +257 -0
  269. package/src/runs/shared/acceptance-evaluation.ts +275 -0
  270. package/src/runs/shared/acceptance-finalization.ts +353 -0
  271. package/src/runs/shared/acceptance-reports.ts +152 -0
  272. package/src/runs/shared/acceptance.ts +33 -0
  273. package/src/runs/shared/chain-outputs.ts +114 -0
  274. package/src/runs/shared/child-attempt.ts +623 -0
  275. package/src/runs/shared/child-execution-cwd.ts +91 -0
  276. package/src/runs/shared/child-observations.ts +99 -0
  277. package/src/runs/shared/claude-code.ts +243 -0
  278. package/src/runs/shared/completion-guard.ts +35 -0
  279. package/src/runs/shared/dynamic-fanout.ts +295 -0
  280. package/src/runs/shared/history-index.ts +69 -0
  281. package/src/runs/shared/mcp-direct-tool-allowlist.ts +376 -0
  282. package/src/runs/shared/model-fallback.ts +219 -0
  283. package/src/runs/shared/mutating-tool-guard.ts +194 -0
  284. package/src/runs/shared/native-finalization.ts +128 -0
  285. package/src/runs/shared/native-usage.ts +113 -0
  286. package/src/runs/shared/nested-events.ts +752 -0
  287. package/src/runs/shared/nested-path.ts +52 -0
  288. package/src/runs/shared/nested-render.ts +119 -0
  289. package/src/runs/shared/parallel-utils.ts +153 -0
  290. package/src/runs/shared/parent-receipts.ts +59 -0
  291. package/src/runs/shared/parent-usage.ts +121 -0
  292. package/src/runs/shared/pi-args.ts +350 -0
  293. package/src/runs/shared/pi-spawn.ts +52 -0
  294. package/src/runs/shared/run-history-queries.ts +44 -0
  295. package/src/runs/shared/run-history.ts +93 -0
  296. package/src/runs/shared/run-id-ambiguity.ts +4 -0
  297. package/src/runs/shared/run-records.ts +607 -0
  298. package/src/runs/shared/session-cwd-preload.ts +27 -0
  299. package/src/runs/shared/single-output.ts +267 -0
  300. package/src/runs/shared/streaming-text.ts +18 -0
  301. package/src/runs/shared/structured-output.ts +68 -0
  302. package/src/runs/shared/subagent-control.ts +219 -0
  303. package/src/runs/shared/subagent-prompt-runtime.ts +201 -0
  304. package/src/runs/shared/subagent-tool-loop-guard.ts +89 -0
  305. package/src/runs/shared/supervisor-questions.ts +372 -0
  306. package/src/runs/shared/workflow-graph.ts +220 -0
  307. package/src/runs/shared/workflow-policy.ts +125 -0
  308. package/src/runs/shared/worktree.ts +635 -0
  309. package/src/shared/agent-context-policy.ts +184 -0
  310. package/src/shared/artifacts.ts +95 -0
  311. package/src/shared/atomic-json.ts +16 -0
  312. package/src/shared/cooperative.ts +21 -0
  313. package/src/shared/execution-cwd.ts +14 -0
  314. package/src/shared/file-coalescer.ts +29 -0
  315. package/src/shared/fork-context.ts +68 -0
  316. package/src/shared/formatters.ts +84 -0
  317. package/src/shared/journal-reader.ts +333 -0
  318. package/src/shared/lazy-tools.ts +36 -0
  319. package/src/shared/model-info.ts +81 -0
  320. package/src/shared/native-session.ts +8 -0
  321. package/src/shared/native-tui.ts +10 -0
  322. package/src/shared/native-typebox.ts +14 -0
  323. package/src/shared/post-exit-stdio-guard.ts +204 -0
  324. package/src/shared/prompt-sections.ts +10 -0
  325. package/src/shared/session-entries.ts +49 -0
  326. package/src/shared/session-identity.ts +18 -0
  327. package/src/shared/settings.ts +384 -0
  328. package/src/shared/status-format.ts +123 -0
  329. package/src/shared/temp-root.ts +107 -0
  330. package/src/shared/types.ts +1259 -0
  331. package/src/shared/ui-mode.ts +5 -0
  332. package/src/shared/utils.ts +342 -0
  333. package/src/slash/prompt-template-bridge.ts +408 -0
  334. package/src/slash/slash-bridge.ts +178 -0
  335. package/src/slash/slash-commands.ts +617 -0
  336. package/src/slash/slash-live-state.ts +292 -0
  337. package/src/tui/action-hints.ts +69 -0
  338. package/src/tui/agent-history.ts +210 -0
  339. package/src/tui/agent-view.ts +1323 -0
  340. package/src/tui/render.ts +1550 -0
  341. package/tsconfig.build.json +12 -0
  342. package/tsconfig.json +19 -0
package/README.md CHANGED
@@ -1,3 +1,1530 @@
1
- # Temporary Holding Version
1
+ # pi-subagents
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ `pi-subagents` lets Pi delegate work to focused child agents. Use it for code review, scouting, implementation, parallel audits, saved workflows, background jobs, and anything else that benefits from a second or third set of model eyes.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pi install npm:@fitchmultz/pi-subagents
9
+ ```
10
+
11
+ **The unscoped npm package `pi-subagents` is not this project.** Use the owned `@fitchmultz/pi-subagents` package; no `npx` installer is provided.
12
+
13
+ `pi-subagents` requires Pi **1.0.0** and Node **24.21.0** or later, including saved-child continuation in a different directory. No Pi fork is required. Indexed history requires the qualified built-in SQLite **3.53.4** binding; other bindings report history as unavailable rather than silently scanning journals on the interactive thread. Usage is attributed through finalized native tool results; see [usage accounting](#usage-accounting). Known Intercom host limitations are listed in the [Intercom guide](docs/intercom.md#limitations).
14
+
15
+ New sessions inherit the child process's working directory. Saved sessions retain their file, identity, header, and history; a requested directory change uses Pi's native SDK cwd override before startup. Same-directory resumes, including symlink and trailing-slash spellings, need no override. Structured-output startup preserves active tools and enables its capture tool. Use an explicit tool policy for restricted child runs; Pi can restore default built-ins when resuming without one.
16
+
17
+ With [pi-change-working-dir](https://github.com/fitchmultz/pi-change-working-dir) **0.5.0 or later**, tool and slash-command delegation, agent discovery, and command completion use the selected execution directory. Relative `cwd` overrides resolve from that directory, captured once before asynchronous preparation. New forks initialize their own selection without changing the parent's history. An explicit continuation `cwd` replaces the child's selection once; omitted continuation cwd preserves saved launch settings and later child `change_dir` selections.
18
+
19
+ Without a directory extension, native Pi cwd behavior is unchanged. An installed older or failing directory extension produces a clear error before work starts; update it rather than silently launching in another directory. Every child validates its loaded directory owner before its first prompt, including fresh runs. Inspection, review, questions, stop, and ordinary saved-child continuation remain available even when the parent's selected directory is unavailable. Native session identity, project context, and browser-group identity keep their existing ownership.
20
+
21
+ Git fallback (existing tags and branches remain installable):
22
+
23
+ ```bash
24
+ pi install git:github.com/fitchmultz/pi-subagents
25
+ ```
26
+
27
+ Use `pi update --extension npm:@fitchmultz/pi-subagents` for an npm install, or `pi update --extension git:github.com/fitchmultz/pi-subagents` for an existing Git install. To switch sources, remove only the old package declaration with `pi remove git:github.com/fitchmultz/pi-subagents`, then install the scoped package; keep your user profiles and settings. Before updating an in-use Pi checkout or extension, checkpoint work and **fully quit every Pi session using that installation**. Run rebuilds and updates from a separate terminal, then start fresh Pi processes. `/reload` can refresh supported settings, skills, and prompts, but cannot reliably activate changed JavaScript. Resume the **same saved parent session**, for example with `pi --session /path/to/parent.jsonl`, to retain run ownership, questions, and pending intercom delivery. A new or forked parent does not adopt them.
28
+
29
+ To restart the bundled broker too, close every Pi session using the same agent directory and wait at least five seconds before reopening Pi.
30
+
31
+ To load a local checkout into Pi, build it as a runtime-only package:
32
+
33
+ ```bash
34
+ npm install --omit=dev # prepare builds dist/ with a throwaway TypeScript compiler
35
+ pi install /absolute/path/to/pi-subagents
36
+ ```
37
+
38
+ Local path registration does not run npm for you. Run `npm install --omit=dev` before loading the checkout and again after source edits; the prepare lifecycle installs only the pinned TypeScript compiler into a temporary directory, builds `dist/`, and deletes it, leaving only runtime dependencies. This also works after a normal development install. A bare `npm run build` is not the runtime rebuild recipe because TypeScript is removed afterward.
39
+
40
+ Use the normal development workflow below for editing and validation, then rerun `npm install --omit=dev` before loading that checkout into Pi. Leaving the development Pi packages present can load their UI instead of the running Pi's UI. The runtime-only recipe avoids that mismatch; it does not repair Pi's loader when development packages remain installed.
41
+
42
+ Supported platforms: **macOS and Linux**. Termux on Android is unverified; Windows is not supported.
43
+
44
+ Pi core packages and TypeBox remain optional wildcard peers. Detached runners resolve TypeBox from the same Pi installation as the session APIs, so runtime-only installs need no private TypeBox copy. Development dependencies are pinned to the coherent official Pi 1.0.0 cohort for typechecking and package checks.
45
+
46
+ ### Saved conversations and run records
47
+
48
+ See [performance and verification](docs/performance.md) for the long-session processing fixes, measured regression cases, and remaining host/integrity costs.
49
+
50
+ Native Pi journals retain the complete conversation. Detached run records keep compact launch, execution, acceptance, accounting and delivery facts; ordinary controls do not load child transcripts. A separate process builds a private SQLite browse index for the current parent's genuinely owned runs, not an archive-wide backfill. Run filters and sorting apply before paging. Freshness is explicit: catching up, current, or degraded; indexed observations never prove ownership, completion, billing, or delivery.
51
+
52
+ The Agents picker asynchronously loads 50 runs at a time and filters the full original assignments. Conversations use pages of 100 physical native records, not a retained-history limit. F2 Actions opens earlier/later pages or validated full selected details. Drafts remain available while loading or recovering; unavailable history stays quiet during background updates until F5 or a new run-list/history/search request retries it. Full selected records and saved reports have a 16 MiB budget and refuse changed or oversized sources. Large output previews retain their separate full-output paths.
53
+
54
+ Child lifecycle aggregates are not copied into the owner event feed. Committed native message IDs reference their journal; uncommitted messages, session-disabled output, Claude Code results and diagnostics remain in a once-stored audit with byte-range receipts. Accounting failures preserve the completed execution and acceptance outcome. Repair reconciles saved billing evidence without launching another child or repeating tools or checks. Claude Code's reported totals remain available, with accounting explicitly incomplete when the adapter lacks native per-category counters or costs.
55
+
56
+ A completion is delivered only when its identity appears in a persisted parent message or completed wait receipt. Queued, journaled and dropped states remain separate across reload/restart. Hosts without an individual pending-queue boundary retain ambiguous work as pending rather than send another copy.
57
+
58
+ Pi 1.0 still eagerly loads native journals during its own startup; extension installation alone does not remove that host cost. Explicit fork context opens the parent separately for each child and publishes an independent native branch without changing the parent. Required branch publication/fsync costs remain.
59
+
60
+ ## Local validation
61
+
62
+ `npm run check:compat` uses the selected host installed in this checkout, never a hidden Pi from PATH. It runs full CI with actual native editor receipts: a supplied clean `PI_EDITOR_RECEIPT_TEST_ROOT` stays read-only, otherwise the owning runner snapshots public `pi-apply-edits` main once in a temporary checkout, records its exact Git SHA, installs only its third-party runtime dependencies, and cleans its owned copy. Repository CI resolves that editor SHA once for all host/platform lanes. It checks host SDK/manifest-bin identity, typechecks, builds, and qualifies both compiled entries with a private Intercom broker through the native SDK and bundled RPC CLI. Official hosts exercise same/different-cwd resume, acceptance, structured output, native result routing/ownership and tool activation. No provider credentials or inference services are used.
63
+
64
+ Repository CI resolves latest stable official Pi and maintained fork main once, then freezes that version/SHA across the Linux/macOS lanes and release qualification. Full `npm run ci`, selected-host native contracts, Git production builds and packed-install smokes remain required.
65
+
66
+ Fork jobs supply `PI_COMPAT_HOST=fork`, `PI_COMPAT_EXPECTED_VERSION`, `PI_COMPAT_EXPECTED_PACKAGE_DIR`, `PI_HOST_INDEX`, and `PI_HOST_CLI` to verify the selected SDK and CLI. The official job uses the resolved latest stable cohort with `PI_COMPAT_HOST=official`. Both targets use ordinary 1.0 lifecycle and finalized tool-result accounting, without checkpoint, immediate-usage or pending-call APIs. Unsupported hosts fail qualification rather than skip native checks. See [host capabilities](#host-capabilities-and-result-delivery) and [limitations](docs/intercom.md#limitations).
67
+
68
+ For a fresh development worktree, run `npm ci` before launching Pi there: project-local `.pi/extensions` can autoload before dependencies exist. Alternatively launch from a neutral directory and use `change_dir` to enter the owned worktree after startup. Do not disable all extensions or remove project extensions to hide missing dependencies.
69
+
70
+ Use an empty HOME outside your real home ancestry and a short temporary directory whose ancestors have no project/package or agent markers. Set HOME, TMPDIR, TMP, TEMP, cache and fixture cwd consistently; never create mutable fixtures beneath the real home or retained evidence directory. Child tests use local fixtures and their own broker/profile. CI runs the latest Node 24 release on Linux and macOS without claiming a full platform-by-host matrix.
71
+
72
+ The completion guard recognizes verified `modifiedFiles` receipts from pi-apply-edits v1's `apply_patch`, `replace_text`, and `write_files`, including partial publication errors. Previews and unchanged results do not count as mutations. To exercise the real editor through native SDK events, use an installed v1 editor checkout:
73
+
74
+ ```bash
75
+ PI_EDITOR_RECEIPT_TEST_ROOT=/absolute/path/to/pi-apply-edits \
76
+ node --test test/integration/native-editor-receipts.test.ts
77
+ ```
78
+
79
+ `PI_EDITOR_RECEIPT_TEST_SDK` selects another installed host package root; `PI_EDITOR_RECEIPT_EVIDENCE_DIR` retains receipts and fixture files. Without an editor checkout, this optional integration test skips.
80
+
81
+ ### SDK embeddings of runtime-only installations
82
+
83
+ Before loading a pruned package with `DefaultResourceLoader`, set `process.env.PI_PACKAGE_DIR = getPackageDir()` from the **selected SDK**. This is the existing host-location contract for native session APIs and detached runners. Alternatively the host must be discoverable through the extension's dependency graph or an actual Pi executable on PATH. CLI consumers resolve their own host normally.
84
+
85
+ Detached history workers need one of those host-location sources to resolve the selected host's terminal-stripping implementation. The parent uses Pi's normal extension-loader imports without loading another runtime. Qualification covers both the explicit-host SDK path and the real bundled CLI with a production-only package.
86
+
87
+ To diagnose the full suite against the locked published Pi dependencies:
88
+
89
+ ```bash
90
+ npm ci
91
+ npm run ci
92
+ ```
93
+
94
+ The [host limitations](docs/intercom.md#limitations) include historical official 0.87.1 results. Retain distinct queue and prompt-preparation checks and report their actual results for the selected host; portable qualification does not establish a full-suite pass.
95
+
96
+ That command runs TypeScript no-emit checking, package shape smoke checks, an isolated single-package install smoke, and the full unit/integration suite. The bundled agent tests cover the Fitch profile set directly, so validation does not require pi-fitch-kit. `npm test` is intentionally the fast unit-test shortcut (`npm run test:unit`), not the full completion gate.
97
+
98
+ For a credential-free Linux gate against committed `HEAD`, Docker and `PI_LINUX_PI_ARCHIVE` are required. Supply an absolute path to a `.tar.gz` containing one top-level `pi/`: a Pi 1.0 source checkout, its Linux `node_modules` (including workspace dependencies), and all built `dist/` output. It must include `pi/packages/coding-agent/dist/index.js` and `pi/packages/coding-agent/dist/bundle/cli.js`.
99
+
100
+ Prepare that checkout in a clean Linux build environment matching the image's CPU architecture and Node version. Install locked dependencies and complete Pi's workspace build, including its generated model data, before archiving. Do not copy host `node_modules`, Pi user state, `auth.json`, secret `.env` files, or credential-bearing npm/Git configuration. From the Linux build environment:
101
+
102
+ ```bash
103
+ tar -czf /absolute/path/native-pi-linux-node24.tar.gz -C /clean/linux-build pi
104
+ ```
105
+
106
+ Run with an archive matching the image:
107
+
108
+ ```bash
109
+ PI_LINUX_PI_ARCHIVE=/absolute/path/native-pi-linux-node24.tar.gz \
110
+ bash scripts/linux-smoke.sh
111
+ ```
112
+
113
+ The archive is mounted read-only and extracted to `/native-pi`. The unprivileged `node` user installs locked package dependencies in `/workspace`, points the private CLI link and all SDK overrides at the supplied build, and runs the full, unchanged `npm run ci` gate. No host home, source mount, credentials, or model calls are passed into it. The gate does not patch Pi/Jiti or skip native cases.
114
+
115
+ ## Real Pi smoke
116
+
117
+ The default local gate includes real SDK reload/reopen and native child-session ownership checks with a controlled CLI and no model calls. Other execution tests stay mock-heavy and deterministic. When you need to verify the actual local file-path Pi package boundary, run the opt-in real smoke:
118
+
119
+ ```bash
120
+ export PATH="$PWD/node_modules/.bin:$PATH"
121
+ node scripts/real-pi-smoke.mjs
122
+ ```
123
+
124
+ Use direct `node` invocation with the intended `pi` first on `PATH`. npm scripts prepend `node_modules/.bin`.
125
+
126
+ It installs this checkout into an isolated temporary Pi home, runs `pi list`, and loads the bundled subagent and intercom extensions. It does not install pi-fitch-kit, publish to npm, or use GitHub Actions.
127
+
128
+ Live model-backed subagent paths are intentionally opt-in because they can use provider credentials and tokens:
129
+
130
+ ```bash
131
+ PI_REAL_SMOKE_MODEL=openai/gpt-6-astra node scripts/real-pi-smoke.mjs --llm
132
+ ```
133
+
134
+ That mode copies local `auth.json` and `models.json` into the isolated Pi agent dir, then asks a real Pi session to exercise intercom status plus subagent list, waiting execution, background launch, and background completion. Set `PI_REAL_SMOKE_AUTH_AGENT_DIR` if your auth files are not in `~/.pi/agent`.
135
+
136
+ For a broader live gate, add `--llm-full`:
137
+
138
+ ```bash
139
+ PI_REAL_SMOKE_MODEL=openai/gpt-6-astra node scripts/real-pi-smoke.mjs --llm-full
140
+ ```
141
+
142
+ That also verifies real parallel, chain, file output, and acceptance flows. It checks actual tool calls and native settlement, and audits saved parent/child model identities. The smoke stops its own processes before removing copied credentials or artifacts, including on timeout or handled cancellation. Use `--keep-temp` to preserve noncredential evidence.
143
+
144
+ ## Local test watchdog
145
+
146
+ `npm test`, `npm run test:unit`, `npm run test:integration`, and `npm run test:all` run through `scripts/run-tests.mjs`, which applies a per-suite local watchdog so hung child-process or worktree tests fail with the command context instead of hanging forever. The default is 300000ms for units and 900000ms for integration. Override it when debugging slow local runs:
147
+
148
+ ```bash
149
+ PI_TEST_TIMEOUT_MS=1800000 npm run test:integration
150
+ # or
151
+ node scripts/run-tests.mjs integration --timeout-ms 1800000
152
+ ```
153
+
154
+ ## Try this first
155
+
156
+ The **Agents** area above the editor shows active tasks on separate colored rows, with a running count and distinct waiting and needs-action states. A quietly pulsing green dot marks running work without repeating “working”; yellow attention indicators stay steady. The six-second pulse uses the existing refresh cadence and your theme’s colors (native emphasis for palette/default colors). In regular mode, offscreen dots stay steady instead of repainting scrollback when expanded details or other widgets fill the screen; the pulse resumes when visible. Task names, meaningful states and unread/replied badges take priority over activity previews; activity detail remains in the conversation and selected picker preview. Queued work does not count as running. The whole area disappears when no agents are active, even with unread results or a saved pin; completed conversations remain available through **Option+Shift+M** (**Alt+Shift+M**) or **`/agents`**. One child opens directly, while several use a task picker. Your own children come first across working directories and worktrees. **Other connected sessions** keeps ordinary peer messaging available.
157
+
158
+ Each child’s provider-qualified model appears in the strip, picker and conversation status when space allows. **Selected** is the current attempt’s requested model, including a fallback; an unprefixed model comes from a native model entry saved during that attempt; **saved** is recorded configuration, not a claim about an active request. Full assignment details retain the model’s source. Finished runs keep their own saved choice even if a continuation later changes the shared session. Provider and model namespaces stay intact. For the full identity at any terminal size, choose **F2 → Full original assignment**; message/tool **Full details / diff** also shows the recorded message model. Missing model data is shown as unavailable, never filled from current profile defaults.
159
+
160
+ The shortcut also closes the open Agents view. Change `shortcut` in the existing [Intercom config](docs/intercom.md#config); the entrance hint follows that setting.
161
+
162
+ The framed picker uses the available terminal width and shows each agent's role and state beside its task. Type to filter globally by task, agent, or any part of the original assignment, including text beyond its preview. Earlier/later picker pages retain access to all matching owned runs. Loading, partial catch-up, no matches, and unavailable history are distinct; **F5** retries. When space allows, the selected assignment is previewed below the list. Open its conversation and choose **F2 → Full original assignment** to read it without shortening it.
163
+
164
+ Finished conversations open at the beginning of their readable saved report, not the structured submission payload. Existing native answers are not repeated. Messages and grouped tool activity use Pi's native presentation; tool output expands through Pi's configured expand-tools key or a fullscreen click. **Full details / diff** shows recorded diffs as readable lines before raw arguments, results and acceptance data; contextual replies carry the selected evidence. Viewing a saved edit shows its recorded diff, not a new comparison against today's file.
165
+
166
+ Inside an agent conversation, use the native multiline editor to message that child directly. **Tab** switches between writing and selecting history; **Page Up/Down** scroll without following new output. **F2** lists all actions, including contextual Reply, full tool details/diff, working-tree changes, Keep visible, Stop, and Continue. **Esc** closes the current menu or detail view; from the conversation it returns to the parent without interrupting either agent or changing the parent draft. Child drafts, unread position and one optional pin survive returning to the same saved parent.
167
+
168
+ In native fullscreen mode, clicking a task opens it; clicking the same task or the **Agents** entrance again closes the view. Displayed action hints are clickable too, including Back, Send, actions, read/write focus, reply, quoted context and latest activity. The connected-session list, message composer and topics view also support their displayed controls. Parent result cards, slash results and notifications expand on click and keep Pi's configured expansion shortcut. Labels use Pi's native **Option** wording on macOS and **Alt** elsewhere; shortcut configuration and key behavior do not change. Regular terminals use the keyboard.
169
+
170
+ | Agent-view shortcut | Action |
171
+ | --- | --- |
172
+ | Enter | Send to the named child, or answer its real waiting question |
173
+ | Alt+R | Reply with the selected message, tool result or change attached |
174
+ | Alt+D | Inspect full details while reading; native word deletion while composing |
175
+ | Alt+G / Alt+L | Working-tree diff / jump to latest activity |
176
+ | Alt+Q / Alt+P | Remove quoted context / pin or unpin this child |
177
+ | Alt+S / Alt+C | Stop only this child / explicitly continue with the draft |
178
+
179
+ Queued children say **waiting to start**. Their drafts stay available until they run; messaging or Continue never launches a duplicate queued child. Viewing finished work never launches it. If a child finishes while you compose or send, the draft remains available for **Continue**. An older multi-child runner that cannot target one child is reported as unavailable rather than stopping its siblings. A saved conversation or launch profile that is missing is likewise not invented. Native selection/copy covers visible fullscreen text; cross-page drag selection is not provided.
180
+
181
+ Human messages are marked as user direction in the child's own conversation. Broker acceptance means **waiting**, not read or acted upon; a native receipt confirms delivery to the conversation, and an actual subsequent response is separate. The parent receives one small informational breadcrumb with the direction, not an approval or relay request. Working-tree diffs are explicitly workspace-wide, not attributed to one child when agents share a directory.
182
+
183
+ Fresh sessions expose `delegate` and small discovery loaders, not the full run-control or peer schemas. Known-profile delegation enables `agent_runs` automatically. For profiles or history before delegation, load only run controls:
184
+
185
+ ```typescript
186
+ load_subagent({ advanced: false })
187
+ agent_runs({ action: "profiles" })
188
+ delegate({ agent: "worker", task: "Implement the approved fix", worktree: true })
189
+ agent_runs({ action: "list" })
190
+ agent_runs({ action: "inspect", id: "<run-id>" })
191
+ agent_runs({ action: "inspect", id: "<run-id>", full: true }) // Full task and launch configuration
192
+ agent_runs({ action: "nudge", id: "<run-id>", message: "Keep the public API unchanged." })
193
+ agent_runs({ action: "continue", id: "<run-id>", message: "Now check the edge case." })
194
+ agent_runs({ action: "review", id: "<run-id>", decision: "accepted", message: "Checked the result." })
195
+ ```
196
+
197
+ Run controls also appear when the same saved session owns actionable work: live runs, questions, failures, or unreviewed results. Reviewed inert history alone does not activate them; it remains accessible through `load_subagent({ advanced: false })`. Tool-only allowlists without a loader remain eager, and exclusions are never overridden. Activated schemas stay available for the selected branch; native tool declarations preserve selection across requests, reload and compaction rather than unloading every turn.
198
+
199
+ `delegate` uses the same durable run owner and acceptance path as `subagent`; `worktree: true` runs one isolated writer through the existing worktree path. `agent_runs` keeps the saved parent's work discoverable across working directories, reloads, and restarts. A nudge never restarts completed work; `continue` explicitly revives its saved session. Use `load_subagent` for parallel groups, chains, detailed overrides, and profile administration. Existing `subagent` calls remain supported.
200
+
201
+ ### Owned runs, review, and continuation
202
+
203
+ `continue` and `answer` accept `async: false` to wait for the actual new or redirected run's saved result. Cancelling a newly launched `async: false` continuation requests cancellation of that new run, not an older sibling. On the portable path, important steered Intercom messages release the wait so the parent can respond while the child keeps working. Continue useful work or end the turn; the saved completion is delivered separately. Background calls return a receipt; completion arrives as a separate wake-up message. A blocking child question releases the foreground wait with its durable question so the parent can answer it. Explicit queue/passive messages do not release waits.
204
+
205
+ Stop receipts mean **requested**, not process exit. Saved results separately record the actual agent-process exit code/signal when observed. A returned tool result is not proof that every command descendant exited, and an unrecorded command result means **exit unconfirmed**, not “still running” or exit zero.
206
+
207
+ If a background runner exits while its children remain alive, Stop signals those recorded child process groups directly after checking their saved process identities. Selected-child Stop still leaves siblings running. Older runs without saved process identities report that ownership cannot be verified.
208
+
209
+ `agent_runs({ action: "list" })` puts unanswered questions first, then failures, interrupted or unconfirmed work, live work, completed-but-unreviewed results, and other runs. It returns 20 runs by default. Filter globally with `agent`, `state`, or `text`, and choose `sort: "attention" | "newest" | "oldest"`. Use `limit` (1–100) with the returned `details.runList.nextCursor`, or use `offset`/`nextOffset`. Cursors belong to the exact owner, query and indexed snapshot; after a stale-cursor error, restart paging without a cursor. Paging never discards history or disables exact-ID lookup. Ambiguous run-ID prefixes report the total match count and at most five candidates; retry with a longer prefix or full run ID. Ordering/filtering use the off-thread browse index; only the selected page rechecks canonical owner/control facts. Index freshness remains an observation, never authority. `inspect` shows a concise task/result summary, acceptance outcome, questions, errors, paths, review, continuation links, and available live diagnostics. Use `full: true` for the full task and saved launch configuration (also supported by exact `subagent` status). Stored details and history are unchanged. Explicit continuation links identify separate work; a successor's result or review never satisfies the predecessor automatically. Final continuation results name the current run ID and its predecessor, including results recovered from the saved parent's durable run records.
210
+
211
+ ### Indexed history and saved-text search
212
+
213
+ ```typescript
214
+ agent_runs({ action: "list", text: "login", state: "completed", sort: "newest", limit: 20 })
215
+ agent_runs({ action: "history", id: "<owned-run-id>", index: 0, limit: 100 })
216
+ agent_runs({ action: "search", query: '"login timeout"', agent: "worker", sort: "newest", limit: 20 })
217
+ // Reuse the returned cursor with the same action, filters, sort and limit.
218
+ ```
219
+
220
+ `history` requires an owned run; choose `index` for a multi-child run. It returns bounded native-entry previews and an earlier-page cursor. Finished attempts stop at their saved terminal entry or completion-time boundary, so a continuation sharing the same native file cannot become its predecessor's evidence. The native file still retains the whole physical conversation.
221
+
222
+ `search` accepts 1–12 lexical words (all must match within one native record, even across distant text or separate visible fields), or one contiguous double-quoted phrase within a text field. Terminal styling/control sequences are stripped before indexing, and each matching record contributes one excerpt per child attempt. Operators, punctuation and prefixes such as `OR` or `word*` are rejected. It searches saved visible user/assistant/tool text, displayed notices and summaries, not thinking, tool arguments, images, hidden custom data or provider payloads. Restrict to an owned `id`/`index` or child `agent`; ordering and filters apply before the 1–100-match page. Search excerpts are bounded observations, not full records or canonical receipts. Common terms can still require substantial matching/sorting work; requests have a process deadline and can be narrowed or retried.
223
+
224
+ Browse databases live privately under `${PI_CODING_AGENT_DIR}/history-index` (default `~/.pi/agent/history-index`), on a local filesystem, with a private directory and files. They are rebuildable projections of admitted sources; malformed, missing, structurally over-budget or changed sources produce explicit freshness/errors instead of synchronous query fallbacks. Index corruption selects a replacement generation without rewriting journals or adopting unrelated archives. Timing samples use a separate `run-timing.sqlite` metadata database in that directory: writers retain the latest 1,000 samples per agent in one transaction. Legacy `run-history.jsonl` remains untouched; reads and the first writer's import use at most its latest 1 MiB of complete records. Older legacy samples remain on disk but are outside the timeout-estimation window.
225
+
226
+ ### Parent review and continuation
227
+
228
+ `review` records `decision: "accepted"` or `"needs_changes"`, with an optional `message`. Review a finished result, not a live run. The decision is separate from execution status, runtime acceptance checks, and delivery. It returns a short saved-decision receipt, not another inspection. The review note is parent-only and is **not sent to the child**, including on revival. Put actionable instructions in `continue` or `nudge`. Review does not run checks, launch another child, or mark a follow-up accepted; inspect and late nudges do not restart anything.
229
+
230
+ Children also receive `PI_SUBAGENT_ROOT_SESSION_ID`: the owning root's actual Pi session ID, inherited unchanged through fresh/forked children, nested delegation, and detached runner configuration. Saved children inherit the reviving parent's root. This is independent of cwd, transcript file paths, run IDs, and ordinary Pi fork/clone ancestry. Extensions such as pi-agent-browser-native use it to share one browser within the parent/descendant group while keeping unrelated roots independent. The parent process environment is not changed; opening a child transcript as an unrelated standalone root does not adopt that group.
231
+
232
+ Continuation and exited-question revival reuse the resolved provider/model, thinking level, profile, selected skill injection, tool/extension and context policies, output settings, limits, and acceptance contract. Without an explicit `agent`, changed profile defaults are not substituted and any explicit override pin is preserved. Selecting `agent` adopts that current profile's model, thinking and fallbacks; a separate `model` override wins and pins its choice. `agent_runs` accepts explicit `model`, `cwd`, `output`, and `acceptance` overrides on `continue`/`answer`; `agent` explicitly selects a current profile. Detailed overrides remain available through `subagent({ action: "resume", ... })`. Launch overrides apply when starting a continuation, not when delivering a follow-up or answer to a still-live child. Live guidance and `continue`/`answer` overrides do **not** mutate that child's model or acceptance contract. A missing worktree can be replaced with an explicit `cwd`; a missing child session cannot be invented. New acceptance sessions inherit their launch cwd; saved-session launches, including acceptance finalization, use the header cwd directly when it resolves to the same existing directory as the requested cwd. A different effective cwd is supplied to native `SessionManager.open` by a launch-scoped Node preload before Pi creates tools, project resources, or extensions, without rewriting the saved session header, identity, or history. If the same saved child already has a live continuation, another `continue` sends it the follow-up instead of starting a second process. Status labels distinguish **Launch cwd** from intercom's **Native session cwd**; neither proves a shell command's physical directory. The **Saved session header cwd** remains unchanged by the native override.
233
+
234
+ When the saved launch records that an output path was generated from a relative profile default, continuation and exited-question revival generate a new path for the successor using that saved filename, leaving the predecessor file untouched. Selecting a current profile with `agent` preserves the saved filename independently of that profile's current default; an explicit `output` override changes the output choice. Explicit paths, absolute profile defaults, and `output: false` retain their saved choices unless overridden. Older snapshots without output-origin information keep their saved paths; supply an explicit `output` override to choose a different path.
235
+
236
+ Old receipts recover their handles and available results from saved parent/child sessions and existing metadata. Active legacy owners finish with their original runtime and files; they are not relaunched or converted in place. Keep that installation available until its runs and question waiters finish. Terminal legacy results can be preserved in durable storage without deleting their original history. When an old run has no saved profile snapshot, continuation asks for an explicit `agent` choice rather than guessing its original configuration. Resuming the same saved parent restores its ownership; a new or forked parent does not automatically adopt that work. Explicit legacy async-ID inspection remains available without adopting the inspected run.
237
+
238
+ You do not need to create agents, write config, or learn slash commands. After installing, ask Pi for delegation in plain language:
239
+
240
+ ```text
241
+ Use reviewer to review this diff.
242
+ ```
243
+
244
+ ```text
245
+ Ask oracle for a second opinion on my current plan.
246
+ ```
247
+
248
+ ```text
249
+ Use scout to understand this code based on our discussion then ask me clarification questions.
250
+ ```
251
+
252
+ ```text
253
+ Run parallel reviewers: one for correctness, one for tests, and one for unnecessary complexity.
254
+ ```
255
+
256
+ That is enough to start.
257
+
258
+ ## What happens
259
+
260
+ Pi is the parent session. A subagent is a focused child Pi session with its own job.
261
+
262
+ For ordinary delegation, Pi uses `delegate` and `agent_runs`. Parallel workflows and advanced controls use `load_subagent` to load the full orchestration schema on demand.
263
+
264
+ Every new run has one detached owner, whether it is a single task, parallel group, chain, saved workflow, or continuation. That owner starts each Pi attempt through Pi's native JSON CLI, preserving native startup, project trust, resources, and sessions. Claude Code uses its own CLI adapter through the same child-attempt lifecycle. `async: false` and `--fg` wait on that owner's saved result and stream progress; they do not select a different executor.
265
+
266
+ Background delivery is the default. A waiting call and a background call use the same controls, acceptance checks, saved results, and recovery path.
267
+
268
+ Installing the extension does not start an automatic reviewer in the background. It gives Pi a delegation tool. `acceptance.review` is not a supported shortcut: review remains parent-controlled so a worker cannot spend a full run and then fail for a reviewer result the runtime never produced. If you want every implementation reviewed, say that in your prompt or put it in your project instructions:
269
+
270
+ ```text
271
+ When you finish implementing, run a reviewer subagent before summarizing.
272
+ ```
273
+
274
+ ## Host capabilities and result delivery
275
+
276
+ Ordinary background calls return a durable launch receipt. The detached owner keeps working, saves its result, and notifies the same saved parent. `continue`/`answer` without `async: false` also return immediate receipts. Completion is appended separately through Intercom when available, otherwise `subagent-notify`; a published parent message, not broker or queue acceptance, prevents repeat delivery after reload/restart. When a legacy notification file is the only saved result, it stays in its existing location until a matching verified parent receipt is published, so a lost native queue cannot erase it.
277
+
278
+ Use `async: false` or `--fg` when the calling tool must wait for the result, including one-shot callers that need it on stdout. These waits are abort-aware, release for important Intercom attention or durable questions, and never adopt another parent's work. Stopping a wait on existing work leaves the child alive; cancellation of newly launched foreground work requests cancellation without claiming process exit.
279
+
280
+ Pi 1.0 does not provide the old fork's native pending-call recovery, idle checkpoint or immediate `recordUsage` APIs. Existing saved run, question, delivery and usage records remain readable, but obsolete pending-call metadata does not reserve completion forever. Resume the same saved parent and use its durable run controls to inspect or continue work. Finalized tool-result usage is charged once; background notifications alone are not usage receipts.
281
+
282
+ ## Good first prompts
283
+
284
+ These cover most day-to-day use:
285
+
286
+ ```text
287
+ Ask oracle for a second opinion on my current plan. Challenge assumptions and tell me what I might be missing.
288
+ ```
289
+
290
+ ```text
291
+ Use oracle to help solve this hard bug. Have it inspect the code and propose the best next move before we edit anything.
292
+ ```
293
+
294
+ ```text
295
+ Run parallel reviewers on this diff. I want one focused on correctness, one on tests, and one on unnecessary complexity.
296
+ ```
297
+
298
+ ```text
299
+ Have worker implement this approved plan. Afterward, run parallel reviewers, summarize their feedback, and apply the fixes that make sense.
300
+ ```
301
+
302
+ ```text
303
+ Run a review loop on this change until reviewers stop finding fixes worth doing, with a max of 3 rounds.
304
+ ```
305
+
306
+ ```text
307
+ Use scout to understand the auth flow, then have planner turn that into an implementation plan.
308
+ ```
309
+
310
+ Those are ordinary Pi requests. Pi decides whether to call `subagent`, which agent to use, and whether a chain or parallel run makes sense.
311
+
312
+ ## Common workflows
313
+
314
+ | Want | Ask naturally |
315
+ |------|---------------|
316
+ | Get a second opinion | “Ask oracle to review this plan and challenge assumptions.” |
317
+ | Solve a hard problem | “Use oracle to investigate this bug before we edit.” |
318
+ | Review a diff | “Use reviewer to review this diff.” |
319
+ | Run parallel reviewers | “Run reviewers for correctness, tests, and cleanup.” |
320
+ | Implement then review | “Implement this, then review it.” |
321
+ | Review until clean | “Run a review loop on this change with a max of 3 rounds.” |
322
+ | Execute a plan carefully | “Have worker implement this approved plan, then run reviewers and apply the feedback.” |
323
+ | Scout before planning | “Use scout to inspect the auth flow before planning.” |
324
+ | Run in the background | “Run this in the background.” |
325
+ | Watch a changing process | “Run watcher in the background to monitor PR checks; notify me on material changes and stop when they finish.” |
326
+ | Browse agents | “Show me the available subagents.” |
327
+ | Use a saved workflow | “Run the review chain on this branch.” |
328
+ | See running work | “Show active async runs.” |
329
+ | Check setup | “Check whether subagents are configured correctly.” |
330
+
331
+ The extension ships with builtin agents you can use immediately.
332
+
333
+ ## Builtin agents in plain English
334
+
335
+ | Agent | Use it when you want... |
336
+ |-------|--------------------------|
337
+ | `scout` | Fast codebase recon and a compressed handoff. |
338
+ | `context-builder` | Requirements and codebase analysis that produces implementation-ready context. |
339
+ | `researcher` | Evidence-driven research for consequential technical decisions. |
340
+ | `watcher` | Read-only background monitoring with timely material-change updates to the parent. |
341
+ | `planner` | A concrete implementation plan without edits. |
342
+ | `worker` | End-to-end implementation of an approved, bounded task. |
343
+ | `debugger` | Root-cause diagnosis with reproduction and repair evidence. |
344
+ | `fixer` | A bounded set of already-decided fixes without replanning. |
345
+ | `reviewer` | General implementation review against the task and evidence. |
346
+ | `reviewer-gpt` | Evidence-backed maintainability and correctness review. |
347
+ | `reviewer-claude` | An independent cross-model review of assumptions and product risk. |
348
+ | `reviewer-security` | Security and data-safety review for trust-boundary changes. |
349
+ | `reviewer-ponytail` | An over-engineering and slop review that never trades away intended behavior. |
350
+ | `ui-designer` | Rendered UI, layout, accessibility, and visual polish. |
351
+ | `writer` | Human-facing documentation, announcements, and polished copy. |
352
+ | `oracle` | A forked second opinion that protects the current decision contract. |
353
+ | `delegate` | Lightweight generic delegation that stays close to the parent session. |
354
+
355
+ Use the role that fits the task. Keep writers isolated and launch independent reviewers separately. Every bundled profile sets `allowSubagents: false` and `maxSubagentDepth: 0`, so routine fanout stays in the parent. Custom profiles may explicitly enable useful helpers within their assigned task, subject to the [depth limit](#recursion-guard) and role authority, including read-only constraints. The original parent owns integration and final delivery; do not enable nested delegation or raise its budget without user authorization.
356
+
357
+ ## Changing a builtin agent's model
358
+
359
+ The [bundled profiles](agents/) define each role's model, thinking and fallback defaults. Use `agent_runs({ action: "profiles" })` to inspect effective defaults after user/project overrides rather than inferring installed routes from examples. Models must be present in Pi's catalog and available to an authorized provider account. Refresh the catalog with `pi update --models` or add custom entries in `~/.pi/agent/models.json`. Override a role when its routes are unavailable; you do not need to copy the bundled agent file. Full editable user profiles may also remain in place even when identical to packaged defaults; user/project profiles keep precedence.
360
+
361
+ For one run, put the override in the command:
362
+
363
+ ```text
364
+ /run reviewer[model=anthropic/claude-sonnet-4:high] "Review this diff"
365
+ ```
366
+
367
+ Profiles are reliable defaults. Warranted per-run overrides are allowed subject to user instructions and provider authorization: `delegate({ agent: "reviewer", task: "Review this diff", model: "provider/model:high" })`. There is no standalone execution `thinking` argument. An explicit override pins route and effort, retaining transient transport retries on that choice but disabling profile fallbacks; if unavailable, the parent must select a replacement. Ordinary runs retain configured fallbacks. `agent_runs({ action: "profiles" })` exposes effective model/thinking/fallback defaults alongside role/source/context, with inherited values labeled rather than guessed.
368
+
369
+ For a persistent override, edit settings. This example changes the reviewer's default everywhere, adds a backup model for provider failures, and leaves the other builtins on their configured routes:
370
+
371
+ ```json
372
+ {
373
+ "subagents": {
374
+ "agentOverrides": {
375
+ "reviewer": {
376
+ "model": "anthropic/claude-sonnet-4",
377
+ "thinking": "high",
378
+ "fallbackModels": ["openai/gpt-5-mini"]
379
+ }
380
+ }
381
+ }
382
+ }
383
+ ```
384
+
385
+ Use `~/.pi/agent/settings.json` for a user override or `.pi/settings.json` for a project override. The same `agentOverrides` block can change `tools`, `skills`, inherited context, prompt text, or disable a builtin. If you want a totally different agent, create a user or project agent with the same name; for normal tweaks, prefer overrides.
386
+
387
+ ## Where running subagents show up
388
+
389
+ Waiting runs stream progress in the conversation. Set `async: false`, use `--fg`, enable `clarify: true`, or provide `timeoutMs`/`maxRuntimeMs` to request this view. A timeout sets the owner's wall-clock budget for the run; it is not just a limit on how long the parent watches. While the run is active, `subagent({ action: "extend", id: "...", extendMs: 300000 })` requests more time. When the timeout expires, running children are soft-interrupted, completed children stay in the result, and timed-out children return `timedOut: true` with a stable timeout message, partial output, and resume guidance when a child session was persisted. Waiting reviewer runs raise short timeout budgets to at least 15 minutes. Planner/researcher-style roles raise short budgets only when local run history shows they need longer.
390
+
391
+ Background runs are the default and keep working independently of the parent's view. Continue useful parent work while they run; if none remains, end the turn for completion delivery instead of polling. Delivery follows the [host's capabilities](#host-capabilities-and-result-delivery). Use `subagent({ action: "status" })` for diagnostics, or inspect a specific run with `subagent({ action: "status", id: "..." })`.
392
+
393
+ An incomplete active Pi goal does not require foreground execution. If child evidence gates the next step, end the current turn and continue the goal after automatic completion delivery; do not advance past the missing evidence.
394
+
395
+ All children share the task-labelled Agents strip. A waiting tool returns the saved result; other background runs send completion notifications. Parallel groups show per-agent progress. Chains with parallel groups keep their grouped shape in progress and results, so failed or paused agents stay visible next to completed ones. Nested delegation remains disabled in bundled profiles.
396
+
397
+ You can also ask naturally:
398
+
399
+ ```text
400
+ Show me the current async runs.
401
+ ```
402
+
403
+ If something feels misconfigured, run:
404
+
405
+ ```text
406
+ /subagents-doctor
407
+ ```
408
+
409
+ or ask:
410
+
411
+ ```text
412
+ Check whether subagents and intercom are set up correctly.
413
+ ```
414
+
415
+ Doctor checks the loaded intercom bridge and the current broker registration without requesting a reconnect. Connected, disconnected, connecting, and unknown states are distinct; a missing bridge response is not reported as a healthy connection.
416
+
417
+ The report identifies the running Node process, Pi's loaded version and reported resource directory, and the loaded extension build. Its SHA-256 fingerprint is embedded at build time from the emitted JavaScript, excluding the stamp itself; replacing files on disk does not change that loaded identity. Direct source loads report an unknown build.
418
+
419
+ ## Recommended orchestration pattern (scaffolding)
420
+
421
+ Use orchestration as parent-agent guidance, not as a runtime workflow mode. For implementation work, the recommended loop is:
422
+
423
+ ```text
424
+ clarify → planner → worker → fresh reviewers → worker
425
+ ```
426
+
427
+ Example prompt files for these patterns remain in `prompts/` for reference.
428
+
429
+ Packaged `oracle` defaults to forked context; the other Fitch role profiles default to fresh context. Forked context is rejected when an affected agent's actual primary or fallback candidate uses the `anthropic/` provider. A pinned non-Anthropic override excludes profile fallbacks, but an Anthropic override remains ineligible.
430
+
431
+ Fresh-child handoffs must contain the relevant exact original user instructions and settled decisions, or readable source references, alongside the bounded assignment. Summaries cannot replace original requirements. The harness does not automatically forward the owner's transcript; keep fresh context rather than switching to fork to compensate.
432
+
433
+ Child boundaries are enforced at runtime. Spawned children do not receive the parent-only `pi-subagents` skill. Their model context omits parent-only orchestration, slash-result, notification, and control messages without deleting saved history. Leaf children also omit orchestration tool calls/results. Delegation-enabled children retain that tool history so their own helper calls remain usable on later turns and resumes.
434
+
435
+ Children do not receive delegation tools by default. When a profile enables delegation and the depth limit allows it, the child starts with `delegate` and `load_subagent`; `agent_runs` appears on delegation, actionable restoration, or explicit `load_subagent({ advanced: false })`. Advanced workflows and controls remain available through `load_subagent`; nested execution still waits by default. The child may use helpful agents within its assigned scope without repeating approval requests for already-authorized work. It remains responsible for its assigned result; the original parent owns integration, review synthesis, and final delivery.
436
+
437
+ ## Example prompts
438
+
439
+ The files in `prompts/` document common workflows without registering additional slash commands:
440
+
441
+ | File | Use it for |
442
+ |------|------------|
443
+ | `parallel-review.md` | Launch fresh-context reviewers with distinct angles, then synthesize what to fix. |
444
+ | `review-loop.md` | Run parent-controlled worker, reviewer, and fix-worker cycles until clean or capped. |
445
+ | `parallel-research.md` | Combine `researcher` and `scout` for external evidence, local code context, and practical tradeoffs. |
446
+ | `parallel-context-build.md` | Run `context-builder` agents in parallel to produce planning handoff context and meta-prompts. |
447
+ | `parallel-handoff-plan.md` | Combine external research and `context-builder` passes into an implementation handoff plan and meta-prompt. |
448
+ | `gather-context-and-clarify.md` | Scout/research first, then ask the user the clarification questions that matter. |
449
+ | `parallel-cleanup.md` | Run review-only cleanup passes after implementation. |
450
+
451
+ ## Bundled intercom
452
+
453
+ The same `pi-subagents` install registers the intercom extension and skill. `load_intercom({})` exposes the full peer tool explicitly; actionable peer inbound and recovered reply needs also expose it before use. Presence, passive breadcrumbs, routine subagent notices, and human messages answered in chat do not. Broker presence and delivery continue even with the schema hidden. Managed children get a private coordination channel back to the parent Pi session unless an explicit agent extension allowlist excludes it. See [the intercom guide](docs/intercom.md) for direct peer messaging, keyboard UI, tool actions, configuration, and broker details.
454
+
455
+ If you previously installed the standalone package, remove that old settings entry once to avoid loading two intercom extensions:
456
+
457
+ ```bash
458
+ pi remove git:github.com/fitchmultz/pi-intercom
459
+ pi install npm:@fitchmultz/pi-subagents
460
+ ```
461
+
462
+ Most users do not call `intercom` directly. `pi-subagents` injects fixed default bridge instructions and auto-adds `intercom`, `contact_supervisor`, and any required `structured_output` tool when a child has an explicit tool list. If an agent sets an explicit `extensions` allowlist, include `pi-intercom` there or those child tools stay sandboxed out. The bridge resolves that entry, including old standalone paths, to the bundled extension.
463
+
464
+ Use it for work where the child might need a decision instead of guessing:
465
+
466
+ ```text
467
+ Run this implementation in the background. If the worker gets blocked or needs a product decision, have it ask me through intercom.
468
+ ```
469
+
470
+ ```text
471
+ Ask oracle to review this plan. If it sees a decision I need to make, have it ask me instead of assuming.
472
+ ```
473
+
474
+ The child can use one dedicated coordination tool:
475
+
476
+ - `contact_supervisor`: the child contacts the parent/supervisor session that delegated the task. Use `reason: "need_decision"` only when the ephemeral child cannot safely continue and must remain alive for one steered supervisor reply. Use `reason: "interview_request"` only when it cannot safely continue until it receives multiple structured answers. Use `reason: "progress_update"` only for discoveries or changes the parent needs while working. These steer at the next tool boundary; skip starts, redundant status, and routine completion, and retain material findings in the final result. Do not ask for clarification when the only conflict is review-only/no-edit versus progress-writing or artifact-writing instructions; no-edit wins.
477
+
478
+ Children return routine completion through their normal result. For portable background delivery, the parent sends one grouped completion through `pi-intercom` per finished run, including child targets, summaries, nested-child summaries, and saved evidence paths. A waiting tool receives the saved result directly; the watcher suppresses a duplicate completion notice. Intercom remains available for live questions and guidance while work continues.
479
+
480
+ ### Questions that survive a reload
481
+
482
+ Blocking supervisor questions are saved before notification, with their owner session, child session, and launch-time acceptance/output requirements. They do not expire at the ordinary intercom ask timeout. A waiting call returns so the supervisor can answer while the same owner and child remain available. Background calls have already returned their receipt. Neither state is successful completion.
483
+
484
+ ```typescript
485
+ agent_runs({ action: "questions" })
486
+ agent_runs({ action: "answer", id: "<run-id>", questionId: "<question-id>", message: "Use the stable API." })
487
+ agent_runs({ action: "stop", id: "<run-id>" })
488
+ ```
489
+
490
+ Resume the **same saved supervisor session**, even from another cwd, to recover its questions. A different session does not silently adopt them. Ordinary `intercom` replies also save the answer while the live waiter is connected. After supervisor/broker restart, prefer `agent_runs` questions/answer; a nudge is guidance, not an answer to a blocking question.
491
+
492
+ Answers are saved once. Repeating the same answer does not start duplicate work; conflicting answers are rejected without replacing the original. A live child reads the saved answer; an exited child resumes from its saved session in a new run, retaining the original acceptance contract. An answer receipt is not execution completion. `stop` cancels outstanding questions and aborts a live waiter using its saved run identity, including after a parent restart.
493
+
494
+ If an answer launch was interrupted before a continuation existed, the reply gives an explicit `continue` recovery call. It refuses to restart when launch evidence is uncertain; inspect the advertised continuation first. Questions, answers, launch contracts, and results live under `${PI_CODING_AGENT_DIR:-~/.pi/agent}/sessions/subagent-runs/<run-id>/`, separate from temporary logs. Ownership and review use native parent `subagent-run` entries; pending intercom delivery is journaled in that same saved Pi session. Temporary cleanup does not erase these records, but deleting saved sessions or metadata removes their recovery data. Pending questions are not age-cleaned.
495
+
496
+ After 10 minutes of no observed child activity by default, needs-attention notices offer `agent_runs` inspection, stopping, or nudging. A matching unresolved durable question says **Waiting for supervisor input** and gives its question ID and answer call; a saved but undelivered answer remains actionable. An active tool is named with its elapsed time and no-output age, with guidance to inspect command progress—not a claim of a hang or forward progress. When the child is registered, prefer `agent_runs({ action: "nudge", id: "<run-id>", message: "What are you blocked on?" })` for live guidance, answers, corrections, or blockers. It sends a non-blocking steer that supplements the child's active task unless the message explicitly replaces it. Use the status-shown blocking intercom ask only when the parent must remain alive waiting for a reply.
497
+
498
+ If messages do not show up, run:
499
+
500
+ ```text
501
+ /subagents-doctor
502
+ ```
503
+
504
+ There is no bridge mode, instruction-file config, or second package to install.
505
+
506
+ At this point, you know enough to use the plugin. The rest of this README is reference material for exact command syntax, custom agents, saved chains, worktrees, and configuration.
507
+
508
+ ## Direct commands
509
+
510
+ Skip this section until you want exact syntax.
511
+
512
+ | Command | Description |
513
+ |---------|-------------|
514
+ | `/run <agent> [task]` | Run one agent; omit the task for self-contained agents |
515
+ | `/chain agent1 "task1" -> agent2 "task2"` | Run agents in sequence |
516
+ | `/parallel agent1 "task1" -> agent2 "task2"` | Run agents in parallel |
517
+ | `/run-chain <chainName> -- <task>` | Launch a saved `.chain.md` or `.chain.json` workflow |
518
+ | `/subagents-doctor` | Show read-only setup diagnostics |
519
+
520
+ Commands validate agent names locally, support tab completion, and send results back into the conversation.
521
+
522
+ ### Per-step tasks
523
+
524
+ Use `->` to separate steps and give each step its own task:
525
+
526
+ ```text
527
+ /chain scout "scan the codebase" -> planner "create an implementation plan"
528
+ /parallel scout "map security-sensitive code" -> researcher "check current security guidance"
529
+ ```
530
+
531
+ Both double and single quotes work. You can also use `--` as a delimiter:
532
+
533
+ ```text
534
+ /chain scout -- scan code -> planner -- analyze auth
535
+ ```
536
+
537
+ Steps without a task inherit behavior from the execution mode. Chain steps get `{previous}`, the prior step’s output. Parallel steps use the first available task as a fallback.
538
+
539
+ ```text
540
+ /chain scout "analyze auth" -> planner -> worker
541
+ # scout gets "analyze auth"; planner gets scout output; worker gets planner output
542
+ ```
543
+
544
+ For a shared task, list agents and place one `--` before the task:
545
+
546
+ ```text
547
+ /chain scout planner -- analyze the auth system
548
+ /parallel scout researcher -- investigate security requirements
549
+ ```
550
+
551
+ ### Inline per-step config
552
+
553
+ Append `[key=value,...]` to an agent name to override defaults for that step:
554
+
555
+ ```text
556
+ /chain scout[output=context.md] "scan code" -> planner[reads=context.md] "analyze auth"
557
+ /run scout[model=anthropic/claude-sonnet-4] summarize this codebase
558
+ /parallel scout[skills=security] "map backend risk" -> researcher[model=openai/gpt-5-mini] "research frontend guidance"
559
+ ```
560
+
561
+ | Key | Example | Description |
562
+ |-----|---------|-------------|
563
+ | `output` | `output=context.md` | Write results to a file. For `/chain` and `/parallel`, relative paths live under the chain directory; for `/run`, relative paths resolve against cwd. |
564
+ | `outputMode` | `outputMode=file-only` | Return only a concise file reference for saved output instead of the full saved content. Requires `output`; default is `inline`. |
565
+ | `reads` | `reads=a.md+b.md` | Read files before executing. `+` separates multiple paths. |
566
+ | `model` | `model=anthropic/claude-sonnet-4` | Override model for this step. |
567
+ | `skills` | `skills=planning+review` | Override injected skills. `+` separates multiple skills. |
568
+ | `progress` | `progress` | Enable progress tracking. |
569
+
570
+ Set `output=false`, `reads=false`, or `skills=false` to disable that behavior explicitly. Do not use `output=false` for file-only returns; use `outputMode=file-only` with an `output` path.
571
+
572
+ ### Execution mode and forked runs
573
+
574
+ Slash commands launch the same detached owner by default. Add `--fg` when the command must wait for its result. `--bg` explicitly requests background delivery, which is useful when configuration sets `asyncByDefault` to `false`. `forceTopLevelAsync` overrides `--fg`, so disable it before requesting a wait:
575
+
576
+ ```text
577
+ /run scout "audit the codebase"
578
+ /chain scout "analyze auth" -> planner "design refactor" -> worker
579
+ # One /parallel call returns one aggregate completion; use separate calls for per-child wakeups.
580
+ /parallel scout "scan frontend" -> scout "scan backend"
581
+ /run reviewer "review this diff" --fg
582
+ ```
583
+
584
+ Add `--fork` to start each child from a real branched session created from the parent’s current leaf:
585
+
586
+ ```text
587
+ /run oracle "review this decision" --fork
588
+ /chain scout "analyze this branch" -> oracle "plan next steps" --fork
589
+ /parallel scout "audit frontend" -> oracle "review backend constraints" --fork
590
+ ```
591
+
592
+ You can combine either execution override with `--fork`:
593
+
594
+ ```text
595
+ /run oracle "review this decision" --fork --fg
596
+ /run oracle "review this decision" --fork --bg
597
+ ```
598
+
599
+ Prefer separate single-agent runs for independent fanout when each result should reach the parent without waiting for every sibling. Use a parallel group when the parent needs one aggregate result or shared concurrency/worktree controls. Continue useful parent work or end the turn for delivery; do not run sleep or status-polling loops. This also applies when child evidence gates an incomplete active goal. Non-interactive one-shot Pi callers should set `async: false` when stdout must contain the child result. On the portable path, omitted `async` returns a launch receipt.
600
+
601
+ Use `oracle` for an advisory decision-consistency pass when helpful, then launch `worker` under the existing implementation authority. Ordinary reversible choices need no new approval. Planning-only requests and explicit holds remain read-only.
602
+
603
+ ## Clarify and launch UI
604
+
605
+ Tool calls launch directly by default. Single, parallel, and chain runs can opt into the clarify UI with `clarify: true` when you want to preview or edit the workflow before it runs; slash commands launch directly.
606
+
607
+ Common clarify keys:
608
+
609
+ - `Enter` launches and waits, or returns a background receipt if background is toggled on
610
+ - `Esc` cancels or backs out
611
+ - `↑↓` moves between steps or tasks
612
+ - `e` edits the task/template
613
+ - `m` selects a model
614
+ - `t` selects thinking level
615
+ - `s` selects skills
616
+ - `b` toggles background execution
617
+ - `w` edits output/write behavior where supported
618
+ - `r` edits reads where supported
619
+ - `p` toggles progress tracking where supported
620
+ Picker screens use `↑↓`, `Enter`, `Esc`, and type-to-filter. The full-screen editor supports word wrapping, paste, `Esc` to save, and `Ctrl+C` to discard.
621
+
622
+ ## Agents and chains
623
+
624
+ Agents are markdown files with YAML frontmatter and a system prompt body. They define the specialist that will run in the child Pi process.
625
+
626
+ Agent locations, lowest to highest priority:
627
+
628
+ | Scope | Path |
629
+ |-------|------|
630
+ | Builtin | Subagents' own `agents/` directory |
631
+ | Package | Configured Pi packages declaring `subagents.agents` directories |
632
+ | User | `~/.pi/agent/agents/**/*.md` |
633
+ | Project | `.pi/agents/**/*.md` |
634
+
635
+ Package profiles use Pi's public package manager to resolve installed npm, Git and local package declarations, without installing missing packages or scanning undeclared dependencies. Declare exact package-relative directories in `package.json`, for example `"subagents": { "agents": ["resources/agents"] }`; absolute, escaping and missing directories are rejected. Profiles are read-only: create a same-named user or trusted-project profile to override one. Precedence is builtin < package < user < trusted project. Package declarations follow `agentScope`; untrusted project declarations are not read. In both scopes, a project declaration shadows the same npm name, Git repository or local package identity; a project `autoload:false` resource delta retains the global package's profiles. Discovery reads current settings on every request, so source removal/reload cannot retain stale profiles. Pi's native resource filters still control extensions/skills/prompts; they do not filter this separate profile manifest.
636
+
637
+ Install `npm:@fitchmultz/pi-workflows` alongside Subagents 0.44.4 or later for its recipe specialists. No profile copying into user or project directories is needed.
638
+
639
+ Project discovery also reads legacy `.agents/**/*.md` files. Nested subdirectories are discovered recursively. `.chain.md` files do not define agents. If both `.agents/` and `.pi/agents/` define the same parsed runtime agent name, `.pi/agents/` wins. Use `agentScope: "user" | "project" | "both"` to control discovery; `both` is the default and project definitions win runtime-name collisions.
640
+
641
+ Builtin agents load at the lowest priority, so a user or project agent with the same name overrides them. The bundled profiles define provider models, fallback routes, and thinking levels; inspect effective defaults with `agent_runs({ action: "profiles" })`. `oracle` is the only packaged fork-default role. The other Fitch profiles default to fresh context and use Pi's normal tool surface.
642
+
643
+ ### Builtin overrides
644
+
645
+ You can override selected builtin fields without copying the whole agent. Overrides live in settings:
646
+
647
+ - User: `~/.pi/agent/settings.json`
648
+ - Project: `.pi/settings.json`
649
+
650
+ Example:
651
+
652
+ ```json
653
+ {
654
+ "subagents": {
655
+ "agentOverrides": {
656
+ "reviewer": {
657
+ "inheritProjectContext": false
658
+ }
659
+ }
660
+ }
661
+ }
662
+ ```
663
+
664
+ Supported override fields are `model`, `fallbackModels`, `thinking`, `systemPromptMode`, `inheritProjectContext`, `inheritSkills`, `defaultContext`, `disabled`, `skills`, `tools`, and `systemPrompt`. Use `defaultContext: false` in builtin overrides to clear an inherited context default. Project overrides beat user overrides.
665
+
666
+ Set `disabled: true` to hide a builtin from runtime discovery and agent-facing `subagent({ action: "list" })` output. For bulk control, set `subagents.disableBuiltins: true` in settings.
667
+
668
+ ### Prompt assembly
669
+
670
+ Subagents start with fresh conversation context while preserving Pi's operating environment by default: the base prompt, project instruction files, and discovered skills catalog. Give a fresh child the task and source paths it needs; it does not receive the parent's conversation unless you choose `fork`.
671
+
672
+ Role boundaries, structured-output instructions, and Intercom guidance use Pi's native prompt sections. If another extension supplies an exact full-prompt override, the required sections are appended to that override. This preserves the instructions but changes the prompt prefix; neither that fallback nor filtered fork context guarantees cache-prefix reuse.
673
+
674
+ Use these fields only when an agent needs stricter isolation or inherited conversation:
675
+
676
+ | Field | Effect |
677
+ |-------|--------|
678
+ | `systemPromptMode: replace` | Replace Pi's normal base prompt with the agent prompt. |
679
+ | `inheritProjectContext: false` | Suppress current project-instruction loading from files like `AGENTS.md` and `CLAUDE.md`; inherited fork history is not scrubbed. |
680
+ | `inheritSkills: false` | Disable discovered skills; explicitly selected skills and inherited fork history remain separate. |
681
+ | `defaultContext: fork` | Use forked session context when a launch omits `context`; explicit `context: "fresh"` still wins. |
682
+
683
+ Bundled agents use the same prompt, project-context, and skill inheritance defaults. `oracle` alone opts into forked conversation context; the other profiles remain fresh.
684
+
685
+ For `claude-code/*` models, append mode preserves Claude Code's native base prompt and its native `CLAUDE.md` and `.claude/skills` discovery. `inheritSkills: false` passes `--disable-slash-commands`, which disables Claude Code skills and commands. Setting both inheritance flags to `false` also disables Claude Code setting sources; Claude Code rejects `inheritProjectContext: false` with `inheritSkills: true` because its setting sources bundle project instructions and skills. Claude Code children never support nested delegation, regardless of depth settings.
686
+
687
+ This changes the behavior of custom agents that omitted these fields before v0.38.0. To preserve the old isolated policy, set `systemPromptMode: replace`, `inheritProjectContext: false`, and `inheritSkills: false` explicitly. Profiles that intentionally delegate must now also set `maxSubagentDepth: 2` or higher, with an installation limit at least as high.
688
+
689
+ Pi task arguments stay inline through 900 UTF-8 bytes, including the `Task: ` prefix; larger tasks use Pi's native `@file` input. System instructions use a separate temporary file, including for agents named `task`. The shared Pi child-attempt driver uses this transport for every execution mode; Claude Code receives its task as positional input.
690
+
691
+ ### Agent frontmatter
692
+
693
+ A typical agent looks like this:
694
+
695
+ ```yaml
696
+ ---
697
+ name: scout
698
+ # Optional: registers this as code-analysis.scout while preserving name: scout
699
+ package: code-analysis
700
+ description: Fast codebase recon
701
+ tools: read, grep, find, ls, bash, mcp:chrome-devtools
702
+ extensions:
703
+ model: claude-haiku-4-5
704
+ fallbackModels: openai/gpt-5-mini, anthropic/claude-sonnet-4
705
+ thinking: high
706
+ systemPromptMode: append
707
+ inheritProjectContext: true
708
+ inheritSkills: true
709
+ skills: safe-bash, chrome-devtools
710
+ allowSubagents: false
711
+ output: context.md
712
+ defaultReads: context.md
713
+ defaultProgress: true
714
+ completionGuard: false
715
+ interactive: true
716
+ maxSubagentDepth: 0
717
+ maxExecutionTimeMs: 600000
718
+ maxTokens: 50000
719
+ ---
720
+
721
+ Your system prompt goes here.
722
+ ```
723
+
724
+ Important fields:
725
+
726
+ | Field | Notes |
727
+ |-------|-------|
728
+ | `package` | Optional package identifier. A file with `name: scout` and `package: code-analysis` registers as `code-analysis.scout`; serialization keeps `name` and `package` separate. |
729
+ | `tools` | Tool allowlist, including extension tools. `mcp:` entries select direct MCP tools when `pi-mcp-adapter` is installed. Omit it to keep Pi's normal configured tool surface. |
730
+ | `allowSubagents` | Opt-in child-safe nested delegation. Disabled in bundled profiles and still bounded by `maxSubagentDepth`. |
731
+ | `extensions` | Omitted means normal extensions; empty means no extensions; comma-separated values allowlist specific extensions. |
732
+ | `model` | Default model. Bare ids prefer the current provider when possible, then unique registry matches. |
733
+ | `fallbackModels` | Ordered backup models for provider/model failures such as quota, usage limit, auth, timeout, or unavailable model. The shared driver first retries the same model once for recoverable transport failures such as WebSocket/stream/socket timeouts or SIGTERM-style provider exits, then falls back when appropriate. Ordinary task failures do not trigger retry or fallback. |
734
+ | `thinking` | Appended as a `:level` suffix at runtime unless a suffix is already present. |
735
+ | `systemPromptMode` | `append` by default; `replace` discards Pi's base prompt. |
736
+ | `inheritProjectContext` | Uses Pi's native context-file loading policy; `false` passes `--no-context-files`. |
737
+ | `inheritSkills` | Keeps or strips Pi’s discovered skills catalog. |
738
+ | `defaultContext` | Optional `fresh` or `fork` launch context default for this agent. |
739
+ | `skills` | Injects specific skills directly, regardless of `inheritSkills`. |
740
+ | `output` | Default single-agent output file. |
741
+ | `defaultReads` | Files to read before running in chain/parallel behavior. |
742
+ | `defaultProgress` | Maintain `progress.md`. |
743
+ | `completionGuard` | Opt in with `true` to require an observed successful mutating tool result. Disabled by default; task wording never determines success. An explicit `acceptance` contract takes precedence and can allow valid no-op outcomes. |
744
+ | `interactive` | Parsed for compatibility but not enforced in v1. |
745
+ | `maxSubagentDepth` | Defaults to `0`; raise it explicitly for an agent allowed to delegate, subject to the inherited global limit. |
746
+ | `maxExecutionTimeMs` | Stops each child attempt after the given number of milliseconds, with a fresh budget for each self-review turn. |
747
+ | `maxTokens` | Bounds the child's assistant input plus output tokens per attempt, including separate self-review attempts. It is not a cumulative workflow or nested-usage budget. Enforcement is best-effort because usage arrives after model events. |
748
+
749
+ ### Tool and extension selection
750
+
751
+ All bundled agents omit `tools` and `extensions` allowlists. If `tools` is omitted, `pi-subagents` does not pass `--tools`, so the child keeps Pi’s configured builtin tools and tools from loaded extensions. If `tools` is present, regular tool names become an explicit allowlist. `mcp:` entries are split out and forwarded as direct MCP selections. Path-like `tools` entries, such as extension paths or `.ts`/`.js` files, are treated as tool-extension paths rather than builtin tool names. Tool capabilities and task prose do not imply a mutation requirement. Use `completionGuard: true` only when a successful mutating tool result is explicitly required, or use `acceptance` with real verification commands for stronger evidence.
752
+
753
+ Examples:
754
+
755
+ - `tools` omitted and `extensions` omitted: configured builtins and normal extensions, including their tools.
756
+ - `allowSubagents: true` with `tools` omitted: normal tools plus child-safe `delegate` and `load_subagent`, with `agent_runs` activated by delegation or discovery. The full `subagent` tool loads on demand. A first-level child remains blocked until both the agent and installation set `maxSubagentDepth` to at least `2`.
757
+ - `tools: mcp:chrome-devtools`: normal builtins plus direct Chrome DevTools MCP tools.
758
+ - `tools: read, bash, mcp:chrome-devtools`: only `read` and `bash` as builtins, plus direct Chrome DevTools MCP tools.
759
+ - `tools: subagent, read`: the explicitly requested child-safe `subagent` tool stays active, alongside compact delegation tools. A first-level child remains blocked until both the agent and installation set `maxSubagentDepth` to at least `2`.
760
+ - `allowSubagents: true` with an explicit regular tool allowlist: the launcher adds compact delegation tools and permits the advanced tool for lazy loading. Other tools retain their existing selection.
761
+
762
+ Direct MCP tools require [pi-mcp-adapter](https://github.com/fitchmultz/pi-mcp-adapter). By default, children preserve the adapter’s configured direct tools and any inherited `MCP_DIRECT_TOOLS` setting. Explicit `mcp:` entries override that selection; explicit `tools` and `extensions` allowlists still apply. The generic `mcp` and `mcp_script` tools remain available when enabled by the adapter and not excluded by an explicit allowlist. 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. An `mcp:` entry named `subagent` does not authorize nested fanout; explicit opt-in requires `allowSubagents: true` or the builtin `subagent` tool name plus both agent and global depth limits of at least `2`.
763
+
764
+ `extensions` controls child extension loading:
765
+
766
+ ```yaml
767
+ # Omitted: all normal extensions load
768
+
769
+ # Empty: no extensions
770
+ extensions:
771
+
772
+ # Allowlist
773
+ extensions: /abs/path/to/ext-a.ts, /abs/path/to/ext-b.ts
774
+ ```
775
+
776
+ When `extensions` is present, it takes precedence over extension paths implied by `tools` entries.
777
+
778
+ ## Chain files
779
+
780
+ Chains are reusable workflows stored separately from agent files. Use `.chain.md` for simple sequential saved chains. Use `.chain.json` when a chain needs dynamic fanout.
781
+
782
+ | Scope | Path |
783
+ |-------|------|
784
+ | User | `~/.pi/agent/chains/**/*.chain.md`, `~/.pi/agent/chains/**/*.chain.json` |
785
+ | Project | `.pi/chains/**/*.chain.md`, `.pi/chains/**/*.chain.json` |
786
+
787
+ Nested subdirectories are discovered recursively. If both `.chain.md` and `.chain.json` define the same parsed runtime chain name in the same scope, `.chain.json` wins. If user and project scopes define the same parsed runtime chain name, the project chain wins. Chains support the same optional `package` frontmatter as agents; `name: review-flow` plus `package: code-analysis` runs as `code-analysis.review-flow`.
788
+
789
+ Example:
790
+
791
+ ```md
792
+ ---
793
+ name: scout-planner
794
+ description: Gather context then plan implementation
795
+ ---
796
+
797
+ ## scout
798
+ phase: Context
799
+ label: Map auth flow
800
+ as: context
801
+ output: context.md
802
+
803
+ Analyze the codebase for {task}
804
+
805
+ ## planner
806
+ phase: Planning
807
+ label: Implementation plan
808
+ reads: context.md
809
+ model: anthropic/claude-sonnet-4-5:high
810
+ progress: true
811
+
812
+ Create an implementation plan based on {outputs.context}
813
+ ```
814
+
815
+ Each `.chain.md` `## agent-name` section is a step. Config lines such as `phase`, `label`, `as`, `outputSchema`, `output`, `outputMode`, `reads`, `model`, `skills`, and `progress` go immediately after the header. A blank line separates config from task text. In saved `.chain.md` files, `outputSchema` is a path to a JSON Schema file; direct tool calls and `.chain.json` files can pass the schema object inline.
816
+
817
+ For task text containing `##` headings, use a `task-json` config line containing a JSON string instead of a prose body, for example `task-json: "Review the change.\n\n## Requirements\nDo not modify files."`. Managed create/update saves use this form automatically when needed, preserving the headings as task text rather than extra steps.
818
+
819
+ For `output`, `reads`, `skills`, and `progress`, chain behavior is three-state: omitted inherits from the agent, a value overrides, and `false` disables.
820
+
821
+ Use `phase` to group related work in status output, `label` for a readable step name, and `as` to store a successful step or parallel task result for later `{outputs.name}` references. Duplicate `as` names, invalid identifiers, and unknown output references fail before child execution.
822
+
823
+ Dynamic fanout is available only through direct `subagent({ chain: [...] })` JSON or saved `.chain.json` files. It expands an array from a prior structured named output, runs one child template per item, and stores the ordered collection under `collect.as`. The source must be structured output; prose is never parsed. Either `expand.maxItems` or `config.chain.dynamicFanout.maxItems` is required (the per-step limit takes precedence), over-limit arrays fail, nested fanout and arbitrary expressions are not supported, and `.chain.md` has no dynamic syntax in this release.
824
+
825
+ ```json
826
+ {
827
+ "name": "dynamic-analysis",
828
+ "description": "Find migration targets, inspect them in parallel, then synthesize a plan.",
829
+ "chain": [
830
+ {
831
+ "agent": "scout",
832
+ "task": "Return {\"items\":[{\"path\":\"...\",\"reason\":\"...\"}]} via structured_output.",
833
+ "as": "targets",
834
+ "outputSchema": { "type": "object" }
835
+ },
836
+ {
837
+ "expand": {
838
+ "from": { "output": "targets", "path": "/items" },
839
+ "item": "target",
840
+ "key": "/path",
841
+ "maxItems": 12
842
+ },
843
+ "parallel": {
844
+ "agent": "scout",
845
+ "label": "Inspect {target.path}",
846
+ "task": "Inspect {target.path}. Reason: {target.reason}",
847
+ "outputSchema": { "type": "object" }
848
+ },
849
+ "collect": { "as": "analyses" },
850
+ "concurrency": 4
851
+ },
852
+ {
853
+ "agent": "planner",
854
+ "task": "Synthesize a migration plan from {outputs.analyses}"
855
+ }
856
+ ]
857
+ }
858
+ ```
859
+
860
+ Create simple `.chain.md` chains by writing files directly or with the `subagent({ action: "create", config: ... })` management action. Create dynamic `.chain.json` chains by writing the JSON file directly. Run saved chains with natural language or:
861
+
862
+ ```text
863
+ /run-chain scout-planner -- refactor authentication
864
+ ```
865
+
866
+ ## Chain variables
867
+
868
+ Task templates support:
869
+
870
+ | Variable | Description |
871
+ |----------|-------------|
872
+ | `{task}` | Original task from the first step. |
873
+ | `{previous}` | Output from the prior step, or aggregated output from a parallel step. |
874
+ | `{chain_dir}` | Path to the chain artifact directory. |
875
+ | `{outputs.name}` | Text value from a prior step or completed parallel task with `as: "name"`. |
876
+
877
+ Parallel outputs are aggregated with clear separators before being passed to the next step:
878
+
879
+ ```text
880
+ === Parallel Task 1 (worker) ===
881
+ ...
882
+
883
+ === Parallel Task 2 (worker) ===
884
+ ...
885
+ ```
886
+
887
+ ## Skills
888
+
889
+ Skills are `SKILL.md` files injected into an agent’s system prompt.
890
+
891
+ Discovery uses project-first precedence:
892
+
893
+ 1. `.pi/skills/{name}/SKILL.md`
894
+ 2. Project packages and project settings packages via `package.json -> pi.skills`
895
+ 3. Current task cwd package via `package.json -> pi.skills`
896
+ 4. `.pi/settings.json -> skills`
897
+ 5. `~/.pi/agent/skills/{name}/SKILL.md`
898
+ 6. User packages and user settings packages via `package.json -> pi.skills`
899
+ 7. `~/.pi/agent/settings.json -> skills`
900
+
901
+ Use agent defaults, override them at runtime, or disable them:
902
+
903
+ ```ts
904
+ { agent: "scout", task: "..." }
905
+ { agent: "scout", task: "...", skill: "tmux, safe-bash" }
906
+ { agent: "scout", task: "...", skill: false }
907
+ ```
908
+
909
+ For chains, named `skill` values at the top level are additive. Top-level `skill: false` disables inherited, agent, and step skills for every step. A step-level `skill` otherwise overrides that step; step-level `false` disables all skills for that step.
910
+
911
+ Injected skills use this shape:
912
+
913
+ ```xml
914
+ <skill name="safe-bash">
915
+ [skill content from SKILL.md, frontmatter stripped]
916
+ </skill>
917
+ ```
918
+
919
+ Missing skills do not fail execution. The result summary shows a warning.
920
+
921
+ ### Bundled skill
922
+
923
+ The package bundles a `pi-subagents` skill that is automatically available to the parent agent when the extension is installed. It is for the orchestrating parent only: child subagents never receive it, and their context is explicitly filtered to strip parent-only orchestration instructions.
924
+
925
+ What the bundled skill covers:
926
+ - **Delegation patterns**: when to launch which agent, whether to use single, parallel, chain, or async mode, and whether to use fresh or forked context
927
+ - **Workflow recipes**: how to apply the example techniques directly with `subagent(...)` when the user describes the workflow in natural language. This includes parallel review, review-loop, parallel research, parallel context-build, parallel handoff-plan, gather-context-and-clarify, and parallel cleanup
928
+ - **Role-agent prompting guidance**: compact contract prompts instead of long scripts, what to include in role-specific meta prompts, and retrieval budgets for researchers
929
+ - **Delegation boundaries**: helpers stay within their assigned scope and configured permissions/depth; agents must not invent Intercom targets or expand unapproved scope
930
+ - **Intercom conventions**: when to ask vs send, and how parent-side result delivery works with `pi-intercom`
931
+ - **Control and diagnostics**: attention signals, soft interrupts, status, and the `doctor` action
932
+
933
+ If you are writing an agent that orchestrates subagents, the bundled skill helps it behave correctly without guessing the patterns. If you are a human user, you do not need to read it directly; the README and example prompts encode the same workflows in user-facing form.
934
+
935
+ ## Programmatic tool usage
936
+
937
+ These are the parameters the LLM passes when it calls the `subagent` tool. Most users ask naturally or use slash commands instead.
938
+
939
+ ### Everyday and advanced schemas
940
+
941
+ `delegate` and `agent_runs` use closed parameter schemas with local validation, without provider-side strict sampling. Their acceptance criteria use `{ id, must, evidence?, severity? }` objects, and verification environments use unique `{ name, value }` pairs. Duplicate environment names are rejected before execution.
942
+
943
+ ```ts
944
+ delegate({
945
+ agent: "worker",
946
+ task: "Implement the approved fix",
947
+ acceptance: {
948
+ criteria: [{ id: "fix", must: "Fix the reproduced bug without changing the public API" }],
949
+ evidence: ["changed-files", "commands-run", "residual-risks"],
950
+ verify: [{ id: "unit", command: "npm test", env: [{ name: "CI", value: "1" }] }],
951
+ maxFinalizationTurns: 3
952
+ }
953
+ })
954
+ ```
955
+
956
+ `load_subagent({ advanced: false })` enables only `agent_runs` for profiles, history, and controls. Omit `advanced` (or set it true) to enable those controls plus the advanced `subagent` schema. It retains string or object acceptance criteria, environment maps, arbitrary caller-supplied output schemas, workflows, and detailed launch overrides. Those flexible inputs do not require strict conversion. Child `structured_output` submissions are still validated against the requested schema; constrained sampling depends on native model and schema support.
957
+
958
+ ### Execution examples
959
+
960
+ ```ts
961
+ // Single agent
962
+ { agent: "worker", task: "refactor auth" }
963
+ { agent: "scout", task: "find todos", maxOutput: { lines: 1000 } }
964
+ { agent: "scout", task: "investigate", output: false }
965
+ { agent: "scout", task: "write a large report", output: "reports/scout.md", outputMode: "file-only" }
966
+
967
+ // Forked context
968
+ { agent: "oracle", task: "review this thread", context: "fork" }
969
+
970
+ // Parallel
971
+ { tasks: [{ agent: "scout", task: "a" }, { agent: "researcher", task: "b" }] }
972
+ { tasks: [{ agent: "scout", task: "audit auth", count: 3 }] }
973
+ { tasks: [{ agent: "scout", task: "audit frontend" }, { agent: "oracle", task: "review backend constraints" }], context: "fork" }
974
+
975
+ // Chain
976
+ { chain: [
977
+ { agent: "scout", task: "Gather context for auth refactor" },
978
+ { agent: "planner" },
979
+ { agent: "worker" }
980
+ ]}
981
+
982
+ // Wait for the same owner's result
983
+ { chain: [...], async: false }
984
+
985
+ // Chain with fan-out/fan-in
986
+ { chain: [
987
+ { agent: "scout", task: "Gather context", phase: "Context", label: "Map code", as: "context" },
988
+ { parallel: [
989
+ { agent: "scout", task: "Audit frontend from {outputs.context}", label: "Frontend", as: "frontend" },
990
+ { agent: "researcher", task: "Research API constraints from {outputs.context}", label: "API", as: "api" }
991
+ ], concurrency: 2, failFast: true },
992
+ { agent: "planner", task: "Create a plan from {outputs.frontend} and {outputs.api}" }
993
+ ]}
994
+
995
+ // Dynamic fanout from structured output
996
+ { chain: [
997
+ {
998
+ agent: "scout",
999
+ task: "Return migration targets as structured_output: { items: [{ path, reason }] }",
1000
+ as: "targets",
1001
+ outputSchema: { type: "object" }
1002
+ },
1003
+ {
1004
+ expand: { from: { output: "targets", path: "/items" }, item: "target", key: "/path", maxItems: 12 },
1005
+ parallel: { agent: "scout", task: "Inspect {target.path}. Reason: {target.reason}", outputSchema: { type: "object" } },
1006
+ collect: { as: "analyses" },
1007
+ concurrency: 4
1008
+ },
1009
+ { agent: "planner", task: "Synthesize a migration plan from {outputs.analyses}" }
1010
+ ] }
1011
+
1012
+ // Strict structured output for reliable handoff data
1013
+ { chain: [
1014
+ {
1015
+ agent: "scout",
1016
+ task: "Return the key files and risks for {task}",
1017
+ as: "scan",
1018
+ outputSchema: {
1019
+ type: "object",
1020
+ required: ["files", "risks"],
1021
+ properties: {
1022
+ files: { type: "array", items: { type: "string" } },
1023
+ risks: { type: "array", items: { type: "string" } }
1024
+ }
1025
+ }
1026
+ },
1027
+ { agent: "planner", task: "Plan from this scan: {outputs.scan}" }
1028
+ ] }
1029
+
1030
+ // Worktree isolation
1031
+ { tasks: [
1032
+ { agent: "worker", task: "Implement auth" },
1033
+ { agent: "worker", task: "Implement API" }
1034
+ ], worktree: true }
1035
+ ```
1036
+
1037
+ ### Management actions
1038
+
1039
+ Agent definitions are not loaded into context by default. Management actions let the LLM discover, inspect, create, update, and delete agents and chains at runtime. `list` and `get` show the effective runtime agent by default, so user/project agents that shadow a builtin appear once with the same precedence used for execution (`project` > `user` > `package` > `builtin`). Pass `agentScope: "user"` or `agentScope: "project"` to inspect a specific shadowing scope.
1040
+
1041
+ ```ts
1042
+ { action: "list" }
1043
+ { action: "list", agentScope: "project" }
1044
+ { action: "get", agent: "scout" }
1045
+ { action: "get", agent: "code-analysis.scout" }
1046
+ { action: "get", chainName: "review-pipeline" }
1047
+
1048
+ { action: "create", config: {
1049
+ name: "Code Scout",
1050
+ package: "code-analysis",
1051
+ description: "Scans codebases for patterns and issues",
1052
+ scope: "user",
1053
+ systemPrompt: "You are a code scout...",
1054
+ systemPromptMode: "replace",
1055
+ inheritProjectContext: false,
1056
+ inheritSkills: false,
1057
+ model: "anthropic/claude-sonnet-4",
1058
+ fallbackModels: ["openai/gpt-5-mini", "anthropic/claude-haiku-4-5"],
1059
+ tools: "read, bash, mcp:github/search_repositories",
1060
+ extensions: "",
1061
+ skills: "parallel-scout",
1062
+ thinking: "high",
1063
+ output: "context.md",
1064
+ reads: "shared-context.md",
1065
+ progress: true
1066
+ }}
1067
+
1068
+ { action: "create", config: {
1069
+ name: "analysis-pipeline",
1070
+ description: "Scout then plan",
1071
+ scope: "project",
1072
+ steps: [
1073
+ { agent: "scout", task: "Scan {task}", output: "context.md" },
1074
+ { agent: "planner", task: "Plan from {previous}", reads: ["context.md"] }
1075
+ ]
1076
+ }}
1077
+
1078
+ { action: "update", agent: "code-analysis.scout", config: { model: "openai/gpt-4o" } }
1079
+ { action: "update", chainName: "analysis-pipeline", config: { steps: [...] } }
1080
+ { action: "delete", agent: "scout" }
1081
+ { action: "delete", chainName: "analysis-pipeline" }
1082
+ ```
1083
+
1084
+ `create` uses `config.scope`, not `agentScope`. `config.name` is the local frontmatter name; optional `config.package` registers the runtime name as `{package}.{name}` and is saved as separate `name` and `package` frontmatter. `get` uses effective runtime precedence by default and can be narrowed with `agentScope`. `update` and `delete` use the runtime name and `agentScope` only when the same runtime name exists in multiple mutable scopes. To clear optional string fields, including `package`, set them to `false` or `""`.
1085
+
1086
+ ### Parameter reference
1087
+
1088
+ | Param | Type | Default | Description |
1089
+ |-------|------|---------|-------------|
1090
+ | `agent` | string | - | Agent name for single mode, or target for management actions. |
1091
+ | `task` | string | - | Task string for single mode. |
1092
+ | `action` | string | - | `list`, `get`, `create`, `update`, `delete`, `status`, `history`, `search`, `interrupt`, `extend`, `resume`, `nudge`, `questions`, `answer`, `review`, or `doctor`. |
1093
+ | `questionId` | string | - | Required with `id` and `message` for `action: "answer"`. |
1094
+ | `decision` | `accepted \| needs_changes` | - | Parent review outcome for `action: "review"`; optional `message` adds a note. |
1095
+ | `offset` / `limit` | integer | 0 / 20 | Page indexed `status` lists; limit is 1–100 and also applies to history/search (history defaults to 100). Exact-ID lookup is retained independently. |
1096
+ | `cursor` | string | - | Opaque list/history/search cursor; reuse the same query, without offset/before. Restart paging after a stale-cursor error. |
1097
+ | `sort` | string | attention / relevance | `status`: attention, newest, oldest. `search`: relevance, newest. |
1098
+ | `state` / `text` | string | - | Global execution-state/full-assignment filters for `status` lists, applied before paging. `agent` also filters list/search children. |
1099
+ | `query` | string | - | Required for `search`: lexical words or one quoted phrase, without operators/punctuation/prefixes. |
1100
+ | `before` | integer | - | `history` only: exclusive physical native-entry position for an earlier page; omit for latest. |
1101
+ | `full` | boolean | false | Exact `status`/`agent_runs` inspect: include the full task and saved launch configuration. |
1102
+ | `chainName` | string | - | Chain name for management actions. |
1103
+ | `config` | object/string | - | Agent or chain config for create/update. |
1104
+ | `output` | `string \| false` | agent default | Override single-agent output handoff file. Explicit caller paths persist at their resolved cwd/workspace path; agent-default relative paths are materialized under run artifacts. |
1105
+ | `outputMode` | `"inline" \| "file-only"` | `inline` | Inline mode returns the saved content plus an output reference. `file-only` returns only a compact persistent-file reference and requires an `output` path. |
1106
+ | `skill` | `string \| string[] \| false` | agent default | Override skills or disable all. |
1107
+ | `model` | string | agent default | Override model. |
1108
+ | `tasks` | array | - | Top-level parallel tasks. Supports `agent`, `task`, `cwd`, `count`, `outputSchema`, `output`, `outputMode`, `reads`, `progress`, `skill`, `model`, and `acceptance`. |
1109
+ | `concurrency` | number | config or `4` | Top-level parallel concurrency. |
1110
+ | `timeoutMs` / `maxRuntimeMs` | number | - | Owner-enforced wall-clock timeout for waiting single, parallel, and chain runs. When `async` is omitted, either field requests a wait. Explicit async/background calls reject it. Short reviewer budgets are raised to a safe floor; planner/researcher-style budgets are raised only from local run-history duration data. For `action: "extend"`, `timeoutMs`/`maxRuntimeMs` can also supply the extension amount when `extendMs` is omitted. |
1111
+ | `extendMs` | number | - | Additional milliseconds for `action: "extend"`. |
1112
+ | `worktree` | boolean | false | Create isolated git worktrees for parallel tasks. |
1113
+ | `chain` | array | - | Sequential, static parallel, and dynamic fanout chain steps. Sequential steps and parallel child tasks support `phase`, `label`, `as`, `outputSchema`, and `acceptance` in addition to the usual execution fields. Dynamic fanout uses `expand`, one child `parallel` template, and `collect`; group-level acceptance is not supported because there is no child session to finalize. |
1114
+ | `context` | `fresh \| fork` | agent default or `fresh` | `fork` creates real branched sessions from the parent leaf. Packaged `oracle` defaults to `fork`; the other Fitch role profiles default to `fresh`. Fork is rejected for effective `anthropic/` primary or fallback models. |
1115
+ | `chainDir` | string | temp chain dir | Persistent directory for chain artifacts. |
1116
+ | `clarify` | boolean | false | Show TUI preview/edit flow only when explicitly set to `true`. |
1117
+ | `agentScope` | `user \| project \| both` | `both` | Agent discovery scope. Project wins on collisions. |
1118
+ | `async` | boolean | top-level: true | Background delivery from the shared owner. Set `false` to wait for the saved result. Child-safe nested calls default to waiting so their results can appear in the calling child's report; `clarify: true` and timeout fields also request a wait. |
1119
+ | `cwd` | string | selected execution cwd | Override working directory. Relative paths resolve from the parent's current selection; omitted continuation cwd retains the saved child launch and selection. Without a directory extension, use native Pi cwd. |
1120
+ | `progress` | boolean | agent default | Maintain `progress.md` for a single run. Parallel task-level progress is maintained in each task cwd; chain progress is maintained in `chainDir`. |
1121
+ | `maxOutput` | object | 200KB, 5000 lines | Final output truncation limits. |
1122
+ | `artifacts` | boolean | true | Write input, output, and metadata debug artifacts. JSONL is not written. |
1123
+ | `includeProgress` | boolean | false | Include full progress in result. |
1124
+ | `control` | object | enabled, 10-minute idle threshold | Override needs-attention tracking (`enabled`, `needsAttentionAfterMs`, `failedToolAttemptsBeforeAttention`, `notifyOn`, `notifyChannels`). |
1125
+ | `share` | boolean | false | Upload session export to GitHub Gist. |
1126
+ | `sessionDir` | string | derived | Override session log directory. |
1127
+ | `acceptance` | object | omitted | Explicit criteria/evidence/verification contract. When present, the child gets a structured contract, then the runtime continues the same session for a bounded self-review/repair loop before evaluating acceptance. Launch independent reviewers separately from the parent. |
1128
+
1129
+ `context: "fork"` fails fast when an affected agent's effective primary or fallback model uses the `anthropic/` provider, the parent session is not persisted, the current leaf is missing, or the branched child session cannot be created. A pinned non-Anthropic override excludes profile fallbacks; actual Anthropic candidates remain ineligible, and fork never silently downgrades to `fresh`. When a multi-agent run omits `context`, each child uses its own `defaultContext`: a fresh-default scout or reviewer stays fresh even when batched with fork-default `oracle`. Other providers continue to use these agent defaults and explicit context overrides normally.
1130
+
1131
+ By default, `output` paths are handoff files. Explicit `output` paths are resolved from the task cwd and left in place, so workspace paths like `.scratchpad/scout.md` remain readable after the run. Reports inside disposable worktrees are copied to the durable run directory before cleanup; returned file references point to that surviving copy even with `artifacts: false`. Relative output paths that come only from an agent default are materialized under the run artifact directory as unique files, so parallel defaults like `context.md` or `review.md` do not collide and do not create project-root leftovers. In inline mode, the runtime reads the handoff content into the parent result and records `savedOutputPath`/`outputReference`; when a materialized agent-default file is consumed, the result records `outputCleanup`. Session artifacts still expose `artifactPaths.outputPath` when artifacts are enabled.
1132
+
1133
+ Use `outputMode: "file-only"` when the parent only needs a pointer. The returned text is a compact reference like `Output saved to: /abs/report.md (48.2 KB, 2847 lines). Read this file if needed.` Failed runs and save errors still return normal inline output for debugging. In chains, later `{previous}` steps receive the same compact reference when the prior step used file-only mode.
1134
+
1135
+ Single, top-level parallel, sequential chain, and parallel chain tasks accept `outputSchema`. If `outputSchema` is present, the child must call `structured_output` with schema-valid JSON; prose-only completion or invalid JSON fails the step. Validated structured values are preserved on the step result, and `as` also exposes a compact text representation through `{outputs.name}` for chain steps.
1136
+
1137
+ Status and control actions:
1138
+
1139
+ ```ts
1140
+ subagent({ action: "status" })
1141
+ subagent({ action: "status", id: "<run-id>" })
1142
+ subagent({ action: "status", id: "<nested-run-id>" })
1143
+ subagent({ action: "interrupt", id: "<run-id>" })
1144
+ subagent({ action: "interrupt", id: "<nested-run-id>" })
1145
+ subagent({ action: "extend", id: "<run-id>", extendMs: 300000 })
1146
+ subagent({ action: "resume", id: "<run-id>", message: "follow-up question" })
1147
+ subagent({ action: "resume", id: "<run-id>", index: 1, message: "follow-up for child 2" })
1148
+ subagent({ action: "resume", id: "<nested-run-id>", message: "follow-up for a nested child" })
1149
+ subagent({ action: "nudge", id: "<run-id>", message: "What are you blocked on?" })
1150
+ subagent({ action: "review", id: "<run-id>", decision: "needs_changes", message: "One edge case remains." })
1151
+ subagent({ action: "status", text: "login", sort: "newest", limit: 20 })
1152
+ subagent({ action: "history", id: "<run-id>", index: 0, limit: 100 })
1153
+ subagent({ action: "search", query: '"login timeout"', limit: 20 })
1154
+ subagent({ action: "doctor" })
1155
+ ```
1156
+
1157
+ `status` resolves exact run IDs, including legacy foreground IDs and nested run IDs, before falling back to prefix matching. Completed, failed, and interrupted owned runs remain inspectable after reload or restart of the same saved parent. `id: "latest"` / `id: "last"` selects the latest owned run; exact IDs are retained regardless of list size. Nested status shows the root/parent path, nested children, session/artifact paths when known, and nested control commands. Inside child-safe fanout mode, `agent_runs({ action: "list" })` lists only the child's directly owned runs restored from its saved session. Use an explicit run ID for advanced `status`; children cannot enumerate unrelated top-level runs. Bare `interrupt` still targets only the visible top-level run; interrupting a nested run requires its explicit nested id.
1158
+
1159
+ `extend` targets an active run with an existing timeout and requests more milliseconds on its deadline. The receipt says **requested** until the owner applies it. It is useful when progress or a needs-attention notice shows useful work still happening and throwing away the child session would waste context. It cannot revive an already-timed-out run; use `resume` after timeout.
1160
+
1161
+ `resume` sends the follow-up directly when the child is still reachable over Intercom. After completion, it starts a new owned continuation from the stored child session file. For multi-child runs, including remembered legacy foreground runs, pass `index` to choose the child. Nested runs can be resumed by nested ID when their live route or persisted nested session metadata is available. Timed-out or transient-error children use the same revival path when their `.jsonl` session file was persisted. Revived children reuse their saved effective launch configuration, including the original explicit acceptance contract. Explicit resume overrides replace the corresponding choices only on a newly launched continuation, never a live child's acceptance. `agent` opts into a current profile; old runs without a profile snapshot require that choice. Revive starts a new child process from the old session context; it does not restart the same OS process, and it requires the chosen child to have a persisted `.jsonl` session file.
1162
+
1163
+ `nudge` sends a short non-blocking steered Intercom message to a live child. Use it for guidance, answers, corrections, or blockers that may affect active work. The child treats it as supplemental coordination and continues its current task unless the message explicitly replaces it. It requires the bundled intercom extension and a registered child target. Use the `Ask:` command shown by `status` only when the parent must remain alive waiting for a reply.
1164
+
1165
+ ## Worktree isolation
1166
+
1167
+ Parallel agents can clobber each other if they edit the same checkout. `worktree: true` gives each parallel child its own git worktree branched from `HEAD`.
1168
+
1169
+ ```ts
1170
+ { tasks: [
1171
+ { agent: "worker", task: "Implement auth", count: 2 },
1172
+ { agent: "worker", task: "Implement API" }
1173
+ ], worktree: true }
1174
+
1175
+ { chain: [
1176
+ { agent: "scout", task: "Gather context" },
1177
+ { parallel: [
1178
+ { agent: "worker", task: "Implement feature A from {previous}" },
1179
+ { agent: "worker", task: "Implement feature B from {previous}" }
1180
+ ], worktree: true },
1181
+ { agent: "planner", task: "Create an integration plan for all changes from {previous}" }
1182
+ ]}
1183
+ ```
1184
+
1185
+ Requirements:
1186
+
1187
+ - run inside a git repo
1188
+ - working tree must be clean
1189
+ - dependencies belong to each worktree; install them there with the project's package manager, or automate installation with `worktreeSetupHook`. The original checkout's `node_modules/` is not shared, so workspace imports resolve the child's code
1190
+ - task-level `cwd` overrides must be omitted or match the shared cwd
1191
+ - configured `worktreeSetupHook` must return valid JSON before timeout
1192
+
1193
+ Stop and run deadlines also cancel Git checkout and setup hooks. Failed or interrupted setup rolls back newly created worktrees within the setup-hook timeout and reports anything it cannot remove.
1194
+
1195
+ After a worktree parallel step completes, per-agent diff stats are appended to the output and full patch files are written to artifacts. Worktrees and temp branches are then cleaned up. Runner exceptions or diff-capture failures preserve them so edits remain recoverable.
1196
+
1197
+ ## Configuration
1198
+
1199
+ `pi-subagents` reads optional JSON config from `~/.pi/agent/extensions/subagent/config.json`.
1200
+
1201
+ ### `asyncByDefault`
1202
+
1203
+ Background delivery is the stock top-level default. Make calls wait by default if needed:
1204
+
1205
+ ```json
1206
+ { "asyncByDefault": false }
1207
+ ```
1208
+
1209
+ The setting applies when a top-level tool or slash call does not explicitly set `async`. Child-safe nested calls default to waiting unless `asyncByDefault: true` is explicitly configured; set `async: false` when their result must appear in the calling child's report. Top-level callers can request a wait with `async: false` unless `forceTopLevelAsync` is enabled. The run owner and child driver are the same either way.
1210
+
1211
+ ### `compactChildTools`
1212
+
1213
+ Authorized children start with `delegate` and `load_subagent`; run controls and the full `subagent` schema load on demand. Native declarations restore the selected branch's tools on startup and tree navigation; compaction preserves current selection. Saved owned runs and unanswered questions enable available run controls; obsolete pending-call records do not reserve tool activation or completion. Explicit `tools: subagent` profiles keep the advanced tool active. Agent-definition mutations remain blocked in children, including after loading.
1214
+
1215
+ Set this flag to `false` to restore the previous full `subagent`-only child surface:
1216
+
1217
+ ```json
1218
+ { "compactChildTools": false }
1219
+ ```
1220
+
1221
+ The default is `true`. Restart children after changing the setting. It does not change models, thinking levels, depth limits, execution defaults, run ownership, or the parent tool surface.
1222
+
1223
+ ### `forceTopLevelAsync`
1224
+
1225
+ ```json
1226
+ { "forceTopLevelAsync": true }
1227
+ ```
1228
+
1229
+ Forces depth-0 single, parallel, and chain calls to request background delivery and bypasses clarify UI by forcing `clarify: false`. Nested calls keep their own inherited settings. The detached owner still records the eventual outcome.
1230
+
1231
+ ### `parallel`
1232
+
1233
+ ```json
1234
+ {
1235
+ "parallel": {
1236
+ "maxTasks": 12,
1237
+ "concurrency": 6
1238
+ }
1239
+ }
1240
+ ```
1241
+
1242
+ `maxTasks` defaults to `8`; `concurrency` defaults to `4`. Per-call `concurrency` takes precedence.
1243
+
1244
+ ### `defaultSessionDir`
1245
+
1246
+ ```json
1247
+ { "defaultSessionDir": "~/.pi/agent/sessions/subagent/" }
1248
+ ```
1249
+
1250
+ Session directory precedence is: `params.sessionDir`, then `config.defaultSessionDir`, then a directory derived from the parent session. Sessions are always enabled.
1251
+
1252
+ ### `projectTrust`
1253
+
1254
+ ```json
1255
+ { "projectTrust": { "childRuns": "approve" } }
1256
+ ```
1257
+
1258
+ Controls project-trust flags for non-interactive child `pi` processes. Child runs default to `approve` so subagents see the same project-local instructions, settings, skills, and extensions the parent trusted. If the parent Pi process was explicitly started with `--no-approve`, child runs keep `--no-approve`. Set `"childRuns": "inherit"` to only forward the parent CLI trust flag, or `"childRuns": "no-approve"` to force children to ignore project-local inputs.
1259
+
1260
+ ### `maxSubagentDepth`
1261
+
1262
+ ```json
1263
+ { "maxSubagentDepth": 1 }
1264
+ ```
1265
+
1266
+ Controls nested delegation when no inherited `PI_SUBAGENT_MAX_DEPTH` is already in effect. The default is `1`, which allows the main session to launch subagents and blocks those children from delegating again. Per-agent `maxSubagentDepth` can tighten the limit for that agent’s child runs, but cannot relax an inherited stricter limit.
1267
+
1268
+ Agent profiles separately default `maxSubagentDepth` to `0`. A first-level child runs at depth `1`, so nested orchestration requires both the installation and that orchestrator profile to set `maxSubagentDepth` to at least `2`.
1269
+
1270
+ ### Agent resource limits
1271
+
1272
+ Set `maxExecutionTimeMs` and `maxTokens` in agent frontmatter or through `subagent({ action: "create" | "update", config })` to bound each attempt for a specific agent. Retry, fallback, and self-review attempts receive their own budgets; these limits do not become cumulative workflow caps.
1273
+
1274
+ ```yaml
1275
+ maxExecutionTimeMs: 600000
1276
+ maxTokens: 50000
1277
+ ```
1278
+
1279
+ When a limit is reached, the child receives a soft interrupt, the run fails with a clear `Resource limit exceeded...` error, and the result includes `resourceLimitExceeded` with the limit kind, configured limit, and observed token count when available. Resource-limit failures do not trigger fallback model retries. `maxTokens` is best-effort because providers report usage after message events; a child may exceed the exact limit before the runtime can stop it.
1280
+
1281
+ Spawn-count and per-agent child-concurrency quotas are not part of this release; use `maxSubagentDepth` and parallel `concurrency` for those boundaries today.
1282
+
1283
+ ### Intercom pairing
1284
+
1285
+ Intercom wiring is always on and bundled with `pi-subagents`. Children receive fixed default bridge instructions and parent-side result/control delivery uses the resolved orchestrator target automatically. If an agent sets an explicit `extensions` allowlist, include `pi-intercom` so child-side `intercom` and `contact_supervisor` tools stay available.
1286
+
1287
+ The injected guidance tells children to use steered blocking `contact_supervisor` decisions or structured interviews only when the ephemeral child cannot safely continue and must remain alive for the answer, non-blocking steered `progress_update` for material discoveries needed during active work, and generic intercom only as fallback plumbing. Supervisor nudges supplement the active task unless they explicitly replace it; routine completion still returns through normal child results.
1288
+
1289
+ ### `worktreeSetupHook`
1290
+
1291
+ ```json
1292
+ {
1293
+ "worktreeSetupHook": "./scripts/setup-worktree.mjs",
1294
+ "worktreeSetupHookTimeoutMs": 45000
1295
+ }
1296
+ ```
1297
+
1298
+ The hook runs once per created worktree. Paths must be absolute, `~/...`, or repo-relative; bare command names are rejected.
1299
+
1300
+ stdin is a JSON object with `repoRoot`, `worktreePath`, `agentCwd`, `branch`, `index`, `runId`, and `baseCommit`. stdout must be one JSON object, for example:
1301
+
1302
+ ```json
1303
+ { "syntheticPaths": [".venv", ".env.local"] }
1304
+ ```
1305
+
1306
+ `syntheticPaths` must be relative to the worktree root. They are removed before diff capture so helper files do not pollute patches. Tracked files are never excluded; marking a tracked path as synthetic fails setup. Default timeout is `30000` ms.
1307
+
1308
+ ## Files, logs, and observability
1309
+
1310
+ Each chain run creates a user-scoped temp directory like:
1311
+
1312
+ ```text
1313
+ <tmpdir>/pi-subagents-<scope>/chain-runs/{runId}/
1314
+ ```
1315
+
1316
+ It may contain files such as `context.md`, `plan.md`, `progress.md`, and `parallel-{stepIndex}/.../output.md`. Directories older than 24 hours are cleaned up on extension startup.
1317
+
1318
+ Debug artifacts live under `{sessionDir}/subagent-artifacts/` or a user-scoped temp artifact directory. Per task you may see:
1319
+
1320
+ - `{runId}_{agent}_input.md`
1321
+ - `{runId}_{agent}_output.md`
1322
+ - `{runId}_{agent}_meta.json`
1323
+
1324
+ Metadata records timing, usage, exit code, final model, attempted models, fallback attempt outcomes, acceptance details when configured, and any resource-limit termination reason. Completion notices and compact delivery receipts include existing result/metadata paths so a short worker summary does not hide that evidence. Disabled artifacts do not create metadata paths.
1325
+
1326
+ Session files are stored under a per-run session directory. With `context: "fork"`, each child starts with `--session <branched-session-file>` produced from the parent’s current leaf. That is a real session fork, not an injected summary.
1327
+
1328
+ Native parent `subagent-run` entries store ownership, continuation links, delivery receipts, and parent review outside model context. They are restored from the full saved session, not only its current context window. Legacy `subagent-invocation` entries remain in old saved sessions but no longer reserve completion or reconnect a native pending call.
1329
+
1330
+ New runs use storage version 2 under `${PI_CODING_AGENT_DIR:-~/.pi/agent}/sessions/subagent-runs/<run-id>/`. The detached owner is the sole writer of execution status and the final result. Controls submit separate identified requests; questions, answers, revival claims, parent review, and UI state retain their own ownership. Inspection reads the owner's evidence without rewriting its execution state or fabricating a successful result. No separate task service or database is used.
1331
+
1332
+ The saved configuration retains profile choices and selected skill text, not copies of installed extensions or inherited project files. Those resources remain live. Debug artifacts and caller-owned output files can still be removed independently; inspection reports missing session/artifact paths, and a saved conversation alone never proves successful execution.
1333
+
1334
+ A run directory contains:
1335
+
1336
+ ```text
1337
+ ${PI_CODING_AGENT_DIR:-~/.pi/agent}/sessions/subagent-runs/<run-id>/
1338
+ launch.json # Frozen launch configuration
1339
+ status.json # Owner-published progress
1340
+ result.json # Canonical final result
1341
+ question-owner.json
1342
+ contracts/<index>.json
1343
+ questions/
1344
+ events.jsonl
1345
+ output-<n>.log
1346
+ subagent-log-<run-id>.md
1347
+ ```
1348
+
1349
+ `status.json` powers the Agents view and run inspection. Reloading or resuming the same saved parent restores its active runs from durable records. `events.jsonl` contains owner and child JSON events annotated with run and step metadata, except streaming `message_update` deltas and cumulative `tool_execution_update` progress, whose final content `message_end` and `tool_execution_end` record; `output-<n>.log` is a live readable tail. Results retain per-child outcomes, acceptance evidence, fallback attempts, output references, and worktree patch paths, including completed siblings when a workflow fails or pauses. Nested summaries reference compact sidecar records rather than copying recursive status snapshots.
1350
+
1351
+ Temporary cleanup does not remove these canonical records. Legacy temporary run directories and `foreground.json` snapshots remain readable. Active old owners drain on their original runtime; recovery does not replay their side effects, guess missing launch settings, or delete native session history. Missing or ambiguous evidence remains unavailable.
1352
+
1353
+ The result watcher emits `subagent:async-complete` for the saved parent's delivery and accounting. Runs with a waiting tool suppress ordinary completion notices; the canonical result remains available after delivery.
1354
+
1355
+ ### Usage accounting
1356
+
1357
+ Child usage comes from finalized native records after the attempt's launch baseline. Inherited fork history and nonbillable checkpoints are excluded. Retries, self-review, summaries, and nested tool usage are included once, with recorded provider/model attribution; unavailable attribution is explicit. Reasoning tokens are part of output tokens, and one-hour cache writes are part of cache writes, not extra totals.
1358
+
1359
+ The finalized execution/wait tool result carries each stable native contribution once when Pi persists that message. Reopening the parent or reading the result again does not charge it again. Saved usage entries from older hosts remain deduplication evidence. A launch receipt, custom completion notification, or slash-command result card alone does not add child usage to parent totals. Portable fire-and-forget background work therefore does not automatically enter the parent's usage totals. Run inspection and streaming progress never charge usage. Subscription-route cost fields remain estimates, not invoices.
1360
+
1361
+ See [cached-input traffic and delegation](docs/performance.md#cached-input-traffic-and-delegation) for the fresh/fork boundary, repeated-prefix arithmetic and evidence needed to investigate an actual usage spike.
1362
+
1363
+ ## Acceptance Gates
1364
+
1365
+ `acceptance` is an explicit contract. Omit it for lightweight runs. For review-only tasks, omit it unless the user explicitly requests a same-session acceptance contract; the extra finalization turn is not independent review. Set it on single runs, top-level parallel task items, sequential chain steps, static parallel task items, and dynamic fanout child templates when the child must prove the work meets concrete criteria. Do not set it on static parallel groups or dynamic fanout aggregate groups; those groups do not own a same-session child turn.
1366
+
1367
+ `no-staged-files` requires the **entire Git index** to be empty, including paths staged before the child started. It does not mean only files changed by that child. A parent contract requiring both a staged deliverable and `no-staged-files` is contradictory; the runtime does not weaken the check or alter the index to reconcile it.
1368
+
1369
+ If you are coming from Codex Goals, `acceptance` is the subagent equivalent for one delegated run. When a user says `/goal`, “goal”, “active goal”, “continue until evidence says done”, or “verify against a goal”, translate that into an acceptance contract: `criteria` are the target, `evidence` and `verify` are proof, `stopRules` are constraints, and `maxFinalizationTurns` is the bounded loop budget.
1370
+
1371
+ ```ts
1372
+ {
1373
+ agent: "worker",
1374
+ task: "Implement the fix",
1375
+ acceptance: {
1376
+ criteria: ["Patch the bug without widening scope"],
1377
+ evidence: ["changed-files", "tests-added", "commands-run", "residual-risks", "no-staged-files"],
1378
+ verify: [{ id: "unit", command: "npm run test:unit", timeoutMs: 120000 }],
1379
+ maxFinalizationTurns: 3
1380
+ }
1381
+ }
1382
+ ```
1383
+
1384
+ When `acceptance` is present, the initial child prompt includes a standardized contract and asks for a fenced `acceptance-report` JSON block. After the initial completion, mandatory bounded self-review continues the same persisted child session. Pi-backed children keep that review inside the same native CLI process; Claude Code uses its native session continuation through the shared adapter. The child can repair omissions before submitting its final report. Missing or malformed reports reject the run when the loop limit is reached. The final answer replaces the initial answer and must stand alone with every requested handoff detail, including paths, identifiers, findings, and cumulative evidence.
1385
+
1386
+ Native Pi finalization uses `structured_output({ value: { answer, report } })`: `answer` is the complete standalone answer, and `report` is a typed acceptance object, not JSON embedded in a string. Only the current attempt's latest assistant turn can submit the report, as its sole tool call. The call needs a matching successful result and an identical saved capture. Later assistant activity requires resubmission; passive context without a new model turn does not. Settlement or exit code zero alone never proves acceptance.
1387
+
1388
+ Missing or stale submissions retry only within `maxFinalizationTurns`; an exhausted run is rejected with the prior full report retained as **UNCONFIRMED** audit evidence. With `outputSchema`, finalization's `answer` is the current JSON payload validated against that schema. It replaces the initial structured result and capture used by named outputs and dynamic fanout; the acceptance `report` remains private. Claude Code submits this same envelope through its native structured-result API when `outputSchema` is present, and keeps its fenced-report contract otherwise. Runtime verification commands run as cancellable work in the owner after self-review, against the final state; child-reported commands do not substitute for them.
1389
+
1390
+ Public acceptance config is evidence-driven. There is no public `level` field and no `acceptance: "checked"` shorthand. Runtime provenance is derived from what actually happened:
1391
+
1392
+ - `attested`: the child returned a structured acceptance report.
1393
+ - `checked`: runtime structural checks passed, such as required criteria, required evidence, and no staged files.
1394
+ - `verified`: configured runtime verification commands passed. Child-reported command success does not count.
1395
+ - `rejected`: attestation, structural checks, verification, or finalization failed.
1396
+
1397
+ Independent review is not part of `acceptance`; the parent launches reviewer runs after the worker completes. Unsupported `acceptance.review` input fails during preflight before any child starts. Self-review finalization never counts as independent review, and it never counts as `verified` unless configured runtime verification commands actually pass. Child-written handoff files remain authoritative during finalization. Otherwise, the current finalization report supplies the parent result, chain input, and artifact output; native finalization also refreshes files generated from earlier assistant output. Legacy and Claude Code fenced reports can retain the prior handoff when they provide no new summary. The initial output remains available as acceptance audit evidence; finalization usage and residual risks are included in the result. Final reports describe cumulative whole-task evidence, including criterion-local evidence requirements, not only edits made during the finalization turn.
1398
+
1399
+ When delegating implementation from a plan or spec, keep the task focused on what to implement and put the definition of done in `acceptance` so the runtime can finalize and evaluate it:
1400
+
1401
+ ```ts
1402
+ subagent({
1403
+ agent: "worker",
1404
+ // Background delivery is the default; set async: false to wait for the result.
1405
+ task: "Implement the plan at /Users/me/docs/mcp-alignment-plan.md. Use scout artifacts in ./handoff/ as context. Do not commit the scout artifacts.",
1406
+ acceptance: {
1407
+ criteria: [
1408
+ "Implementation follows /Users/me/docs/mcp-alignment-plan.md",
1409
+ "Plan acceptance checks are addressed",
1410
+ "Scout handoff artifacts are not committed",
1411
+ "Focused validation for changed behavior passes",
1412
+ "Residual risks or skipped checks are reported"
1413
+ ],
1414
+ evidence: ["changed-files", "commands-run", "validation-output", "residual-risks"],
1415
+ verify: [{ id: "local-gate", command: "npm run ci" }],
1416
+ stopRules: [
1417
+ "Do not edit unrelated files",
1418
+ "Stop and report if the plan requires a decision outside the assigned authority"
1419
+ ],
1420
+ maxFinalizationTurns: 3
1421
+ }
1422
+ })
1423
+ ```
1424
+
1425
+ ## Human-only acceptance blockers
1426
+
1427
+ A real human-only boundary, such as Touch ID or an unavailable MFA code, is **blocked**, not success or a generic failed review. Report the affected criterion with `status: "blocked"`, concrete `evidence`, and a nonempty `humanAction` stating the exact action needed. Retain completed criteria and evidence. The first valid initial or current native blocked report stops further finalization and verification, keeps acceptance incomplete, and prevents dependent workflow steps from starting. Independent siblings continue; real failures still take precedence. Plain “blocked” prose, stale submissions, malformed reports and ordinary fixable failures do not get this treatment.
1428
+
1429
+ The Agents view keeps these tasks visible as **Needs your action — acceptance incomplete**. After doing the requested action, use explicit Continue on the saved conversation. Inspecting, reviewing or restoring it does not retry authentication, and a blocked report does not fabricate a waiting question.
1430
+
1431
+ ## Live progress
1432
+
1433
+ Waiting calls show compact live progress from the same owner used for background work: current tool, recent output, token counts, duration, activity freshness, current-tool duration, and chain graph metadata when available.
1434
+
1435
+ Delegation receipts, completed responses, and completion messages show compact summaries by default. Press `Ctrl+O` to expand their full responses and details, or the full streaming view with output per step. The quiet Agents strip replaces the routine async widget; Ctrl+O still exposes its advanced background details. Collapsing these views does not shorten the content sent to the model.
1436
+
1437
+ Sequential chains show a flow line like `done scout → running planner`. Chains with parallel steps show per-step cards instead. Chain status uses `label` and `phase` metadata when present, while falling back to agent names for older chains.
1438
+
1439
+ ## Compact view
1440
+
1441
+ On a native [`fitchmultz/pi` build with compact-view support](https://github.com/fitchmultz/pi/commit/17cb62faade465700692b0d474ec5652e8df3aed), use `/compact-view on`, `/compact-view off`, or `/compact-view toggle`. `/settings` → **Compact view** controls the same setting. It defaults off, updates the current UI immediately, and saves your default for future Pi starts without changing other running sessions.
1442
+
1443
+ When enabled, ordinary Intercom messages, subagent notifications, and slash-command result cards use one content row plus Pi's existing blank line. Press `Ctrl+O` (or your configured expansion key) for full details. Questions, reply guidance, and needs-attention notices stay prominent. Turning the mode off restores normal presentation; older hosts without the native hint keep that presentation too. This is display-only: message content, attachments, model context, history, and delivery are unchanged. `/compact` is the separate context-compaction command.
1444
+
1445
+ ## Session sharing
1446
+
1447
+ Pass `share: true` to export a full session to HTML, upload it to a secret GitHub Gist through your `gh` credentials, and return a `https://shittycodingagent.ai/session/?<gistId>` URL.
1448
+
1449
+ ```ts
1450
+ { agent: "scout", task: "...", share: true }
1451
+ ```
1452
+
1453
+ This is disabled by default. Session data may contain source code, paths, environment variables, credentials, or other sensitive output. You need `gh` installed and authenticated.
1454
+
1455
+ ## Recursion guard
1456
+
1457
+ Nested child delegation is disabled by default. The default depth guard allows one level—main session → subagent. If the user explicitly authorizes nested helpers, enable delegation in the chosen custom profile and set both its profile and installation depth limits to the authorized budget (at least `2` for a first-level child to delegate). This does not change bundled leaf-profile defaults or the original parent's responsibility for integration and delivery.
1458
+
1459
+ Configure the limit with:
1460
+
1461
+ 1. `PI_SUBAGENT_MAX_DEPTH` before starting Pi
1462
+ 2. `config.maxSubagentDepth`
1463
+ 3. `maxSubagentDepth` in agent frontmatter, which can only tighten the inherited limit
1464
+
1465
+ ```bash
1466
+ export PI_SUBAGENT_MAX_DEPTH=1
1467
+ ```
1468
+
1469
+ `PI_SUBAGENT_DEPTH` is internal and propagated automatically. Do not set it manually; invalid values block nested subagents instead of resetting to zero.
1470
+
1471
+ ## Events
1472
+
1473
+ Owner lifecycle events retain their existing names for all new runs:
1474
+
1475
+ - `subagent:async-started`
1476
+ - `subagent:async-complete`
1477
+
1478
+ Intercom delivery events:
1479
+
1480
+ - `subagent:control-intercom`
1481
+ - `subagent:result-intercom`
1482
+ - `subagent:live-intercom`
1483
+ - `subagent:intercom-health-request`
1484
+ - `subagent:supervisor-question-resolved` — `{ questionId }` after a durable answer or explicit cancellation; clears pending-ask presence without starting a turn.
1485
+
1486
+ The result watcher emits `subagent:async-complete`; `src/extension/index.ts` handles saved-result accounting and notification routing. Waiting tools suppress ordinary completion notices. Raw control events remain in the owner's event log. Idle notices wait until the current parent turn ends and are discarded if their child has finished; previously delivered obsolete idle notices are omitted from future model context without removing saved history. Unresolved supervisor questions and completion-guard findings remain visible. A terminal completion-guard notice leaves automatic completion delivery to the matching result, avoiding two triggered turns. A parallel group delivers one aggregate result after its siblings finish; a mid-group guard notice is visible immediately. With `pi-intercom`, needs-attention notices, live nudges, best-effort child health, and portable grouped results can reach the orchestrator over Intercom.
1487
+
1488
+ ## Prompt-template integration
1489
+
1490
+ `pi-subagents` works standalone through natural language, the `subagent` tool, and its built-in slash commands. The example prompts near the top of this README are not registered as commands. You can wrap subagent delegation in your own reusable Pi prompt templates.
1491
+
1492
+ Example:
1493
+
1494
+ ```md
1495
+ ---
1496
+ description: Take a screenshot
1497
+ model: claude-sonnet-4-20250514
1498
+ subagent: browser-screenshoter
1499
+ cwd: /tmp/screenshots
1500
+ ---
1501
+ Use url in the prompt to take screenshot: $@
1502
+ ```
1503
+
1504
+ Then `/take-screenshot https://example.com` switches to Sonnet, delegates to `browser-screenshoter` with `/tmp/screenshots` as cwd, and restores your model when done. Runtime overrides like `--cwd=<path>` and `--subagent=<name>` work too.
1505
+
1506
+ For more reusable workflows on top of subagents, including `/chain-prompts` and compare-style prompts such as `/best-of-n`, install `pi-prompt-template-model` separately and copy the examples you want into `~/.pi/agent/prompts/`.
1507
+
1508
+ ## Runtime files
1509
+
1510
+ The main runtime files are:
1511
+
1512
+ | File | Purpose |
1513
+ |------|---------|
1514
+ | `src/extension/index.ts` | Extension registration, tool registration, message/render wiring. |
1515
+ | `src/agents/agents.ts` | Agent and chain discovery, frontmatter parsing. |
1516
+ | `src/runs/foreground/subagent-executor.ts` | Main execution routing for single, parallel, chain, management, status, interrupt, and doctor actions. |
1517
+ | `src/runs/background/subagent-runner.ts` | Durable owner for single tasks, parallel groups, chains, and verification. |
1518
+ | `src/runs/background/async-execution.ts` | Frozen launch configuration and detached owner startup for every mode. |
1519
+ | `src/runs/shared/child-attempt.ts` | Shared process/event lifecycle for native Pi JSON CLI attempts and the Claude Code adapter. |
1520
+ | `src/runs/foreground/wait-run.ts` | Abort-aware result/progress view over an owned run. |
1521
+ | `src/runs/background/async-status.ts` | Durable and legacy run discovery and status formatting. |
1522
+ | `src/runs/shared/run-records.ts` | Native parent ownership, saved launch/result recovery, attention-first lists, and lineage/review views. |
1523
+ | `src/agents/chain-serializer.ts` / `src/runs/shared/chain-outputs.ts` / `src/runs/shared/dynamic-fanout.ts` | Saved chain parsing, named outputs, and bounded dynamic expansion. |
1524
+ | `src/runs/shared/native-finalization.ts` | Same-process Pi self-review and current typed report submission. |
1525
+ | `src/runs/foreground/wait-run.ts` / `src/runs/shared/parent-usage.ts` | Abort-aware durable waits and finalized native tool-result usage. |
1526
+ | `src/shared/settings.ts` | Chain behavior, instructions, and config helpers. |
1527
+ | `src/runs/shared/worktree.ts` | Git worktree isolation. |
1528
+ | `src/intercom/intercom-bridge.ts` | Fixed intercom instructions, target names, and agent wiring. |
1529
+ | `src/extension/schemas.ts` / `src/shared/types.ts` | Tool schemas, shared types, and event constants. |
1530
+ | `test/unit/` / `test/integration/` | Unit and loader-based integration tests. |