@fitchmultz/pi-subagents 0.44.7 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (955) hide show
  1. package/CHANGELOG.md +264 -7
  2. package/LICENSE +1 -0
  3. package/README.md +58 -1483
  4. package/agents/context-builder.md +19 -1
  5. package/agents/debugger.md +10 -3
  6. package/agents/delegate.md +1 -0
  7. package/agents/fixer.md +4 -1
  8. package/agents/oracle.md +13 -2
  9. package/agents/planner.md +14 -3
  10. package/agents/researcher.md +11 -2
  11. package/agents/reviewer-claude.md +11 -2
  12. package/agents/reviewer-gpt.md +12 -2
  13. package/agents/reviewer-ponytail.md +11 -1
  14. package/agents/reviewer-security.md +13 -2
  15. package/agents/reviewer.md +12 -3
  16. package/agents/scout.md +12 -1
  17. package/agents/ui-designer.md +10 -3
  18. package/agents/watcher.md +1 -0
  19. package/agents/worker.md +8 -2
  20. package/agents/writer.md +6 -3
  21. package/dist/agents/agent-defaults.js +9 -0
  22. package/dist/agents/agent-definition.js +196 -0
  23. package/dist/agents/agent-management.js +64 -905
  24. package/dist/agents/agent-scope.js +4 -2
  25. package/dist/agents/agent-selection.js +10 -5
  26. package/dist/agents/agent-serializer.js +55 -67
  27. package/dist/agents/agents.js +75 -716
  28. package/dist/agents/builtin-overrides.js +218 -0
  29. package/dist/agents/chain-serializer.js +3 -367
  30. package/dist/agents/config-values.js +52 -0
  31. package/dist/agents/discovery-paths.js +91 -0
  32. package/dist/agents/frontmatter.js +15 -5
  33. package/dist/agents/identity.js +25 -8
  34. package/dist/agents/json-chain.js +254 -0
  35. package/dist/agents/management-config.js +332 -0
  36. package/dist/agents/management-format.js +231 -0
  37. package/dist/agents/management-persistence.js +287 -0
  38. package/dist/agents/management-targets.js +136 -0
  39. package/dist/agents/management-warnings.js +81 -0
  40. package/dist/agents/markdown-chain.js +210 -0
  41. package/dist/agents/package-agents.js +154 -0
  42. package/dist/agents/skill-files.js +157 -0
  43. package/dist/agents/skill-search-paths.js +246 -0
  44. package/dist/agents/skill-types.js +1 -0
  45. package/dist/agents/skills.js +54 -499
  46. package/dist/extension/acceptance-schema.js +55 -0
  47. package/dist/extension/build-info.js +1 -1
  48. package/dist/extension/chain-schema.js +196 -0
  49. package/dist/extension/child-runtime.js +237 -0
  50. package/dist/extension/compact-tools.js +122 -51
  51. package/dist/extension/config-schema.js +29 -0
  52. package/dist/extension/config.js +27 -11
  53. package/dist/extension/control-notice-schema.js +37 -0
  54. package/dist/extension/control-notices.js +13 -6
  55. package/dist/extension/delegation-bridges.js +43 -0
  56. package/dist/extension/doctor.js +48 -25
  57. package/dist/extension/everyday-schemas.js +207 -0
  58. package/dist/extension/fanout-child.js +18 -319
  59. package/dist/extension/index.js +8 -563
  60. package/dist/extension/message-renderers.js +225 -0
  61. package/dist/extension/nested-control-inbox.js +154 -0
  62. package/dist/extension/parent-runtime.js +339 -0
  63. package/dist/extension/primary-tool.js +69 -0
  64. package/dist/extension/result-snapshot.js +22 -0
  65. package/dist/extension/runtime-reload.js +62 -0
  66. package/dist/extension/runtime-storage.js +43 -0
  67. package/dist/extension/schema-overrides.js +75 -0
  68. package/dist/extension/schemas.js +265 -336
  69. package/dist/extension/tool-input.js +27 -12
  70. package/dist/extension/tool-result.js +19 -4
  71. package/dist/history/answer-texts.js +57 -0
  72. package/dist/history/canonical-result.js +76 -43
  73. package/dist/history/canonical-selection.js +40 -0
  74. package/dist/history/database-generation.js +82 -0
  75. package/dist/history/database.js +57 -33
  76. package/dist/history/entry-ingestion.js +61 -0
  77. package/dist/history/index.js +242 -97
  78. package/dist/history/ingest.js +168 -331
  79. package/dist/history/output-digests.js +40 -0
  80. package/dist/history/preview.js +210 -0
  81. package/dist/history/prune.js +33 -0
  82. package/dist/history/queries.js +60 -349
  83. package/dist/history/query-scope.js +190 -0
  84. package/dist/history/rows.js +77 -0
  85. package/dist/history/run-projection.js +137 -0
  86. package/dist/history/run-queries.js +153 -0
  87. package/dist/history/schema.js +31 -0
  88. package/dist/history/search-queries.js +163 -0
  89. package/dist/history/selected-record.js +108 -0
  90. package/dist/history/source-file.js +45 -0
  91. package/dist/history/source-watches.js +141 -0
  92. package/dist/history/store.js +164 -153
  93. package/dist/history/text-chunks.js +169 -0
  94. package/dist/history/text.js +35 -0
  95. package/dist/history/transcript-queries.js +177 -0
  96. package/dist/history/types.js +5 -1
  97. package/dist/history/values.js +36 -0
  98. package/dist/history/wire-inputs.js +122 -0
  99. package/dist/history/wire-models.js +38 -0
  100. package/dist/history/worker-runtime.js +441 -0
  101. package/dist/history/worker.js +66 -462
  102. package/dist/intercom/intercom-bridge.js +48 -20
  103. package/dist/intercom/live-intercom.js +80 -23
  104. package/dist/intercom/nested-result-tree.js +163 -0
  105. package/dist/intercom/result-delivery.js +40 -0
  106. package/dist/intercom/result-intercom.js +178 -261
  107. package/dist/pi-intercom/agent-dir.js +7 -3
  108. package/dist/pi-intercom/async.js +27 -0
  109. package/dist/pi-intercom/bridge-ask.js +57 -0
  110. package/dist/pi-intercom/bridge-config.js +89 -0
  111. package/dist/pi-intercom/bridge-http.js +86 -0
  112. package/dist/pi-intercom/bridge-launch-policy.js +88 -0
  113. package/dist/pi-intercom/bridge-launch.js +217 -0
  114. package/dist/pi-intercom/bridge-protocol.js +106 -0
  115. package/dist/pi-intercom/bridge-routes.js +72 -0
  116. package/dist/pi-intercom/bridge-rpc-process.js +264 -0
  117. package/dist/pi-intercom/bridge-session.js +420 -0
  118. package/dist/pi-intercom/bridge.js +221 -606
  119. package/dist/pi-intercom/broker/broker.js +236 -244
  120. package/dist/pi-intercom/broker/client.js +189 -304
  121. package/dist/pi-intercom/broker/connection.js +165 -0
  122. package/dist/pi-intercom/broker/framing.js +5 -3
  123. package/dist/pi-intercom/broker/paths.js +4 -1
  124. package/dist/pi-intercom/broker/pid.js +53 -25
  125. package/dist/pi-intercom/broker/snapshot-reader.js +78 -0
  126. package/dist/pi-intercom/broker/snapshots.js +188 -0
  127. package/dist/pi-intercom/broker/spawn.js +36 -25
  128. package/dist/pi-intercom/config.js +85 -71
  129. package/dist/pi-intercom/connection.js +297 -0
  130. package/dist/pi-intercom/identity.js +58 -0
  131. package/dist/pi-intercom/inbound-delivery.js +356 -0
  132. package/dist/pi-intercom/inbound-journal.js +303 -0
  133. package/dist/pi-intercom/inbound-record.js +113 -0
  134. package/dist/pi-intercom/inbound.js +179 -0
  135. package/dist/pi-intercom/index.js +79 -2933
  136. package/dist/pi-intercom/inspection.js +62 -0
  137. package/dist/pi-intercom/interview.js +236 -0
  138. package/dist/pi-intercom/lifecycle.js +168 -0
  139. package/dist/pi-intercom/message-format.js +69 -0
  140. package/dist/pi-intercom/outbound.js +304 -0
  141. package/dist/pi-intercom/peer-awareness.js +66 -0
  142. package/dist/pi-intercom/reply-tracker.js +62 -43
  143. package/dist/pi-intercom/reply-wait.js +201 -0
  144. package/dist/pi-intercom/runtime-types.js +3 -0
  145. package/dist/pi-intercom/session-events.js +180 -0
  146. package/dist/pi-intercom/session-targets.js +42 -34
  147. package/dist/pi-intercom/subagent-events.js +238 -0
  148. package/dist/pi-intercom/subagent-live-events.js +129 -86
  149. package/dist/pi-intercom/supervisor.js +282 -0
  150. package/dist/pi-intercom/tool-arguments.js +74 -0
  151. package/dist/pi-intercom/tool-registration.js +95 -0
  152. package/dist/pi-intercom/tool-results.js +38 -0
  153. package/dist/pi-intercom/tool-schemas.js +82 -0
  154. package/dist/pi-intercom/tools.js +51 -0
  155. package/dist/pi-intercom/topic-actions.js +177 -0
  156. package/dist/pi-intercom/topics.js +177 -92
  157. package/dist/pi-intercom/transport.js +1 -0
  158. package/dist/pi-intercom/types.js +151 -114
  159. package/dist/pi-intercom/ui/compose-paste.js +93 -0
  160. package/dist/pi-intercom/ui/compose.js +121 -143
  161. package/dist/pi-intercom/ui/inline-message.js +59 -59
  162. package/dist/pi-intercom/ui/message-renderers.js +147 -0
  163. package/dist/pi-intercom/ui/overlay.js +181 -0
  164. package/dist/pi-intercom/ui/session-format.js +124 -0
  165. package/dist/pi-intercom/ui/session-list.js +76 -43
  166. package/dist/pi-intercom/ui/tool-renderers.js +110 -0
  167. package/dist/pi-intercom/ui/topic-view.js +88 -0
  168. package/dist/pi-intercom/validation.js +59 -0
  169. package/dist/runs/background/async-chain-plan.js +265 -0
  170. package/dist/runs/background/async-control.js +134 -58
  171. package/dist/runs/background/async-execution.js +136 -633
  172. package/dist/runs/background/async-job-admission.js +40 -0
  173. package/dist/runs/background/async-job-projection.js +169 -0
  174. package/dist/runs/background/async-job-tracker.js +297 -327
  175. package/dist/runs/background/async-launch.js +216 -0
  176. package/dist/runs/background/async-plan.js +116 -0
  177. package/dist/runs/background/async-result-file.js +47 -23
  178. package/dist/runs/background/async-resume.js +195 -253
  179. package/dist/runs/background/async-run-discovery.js +213 -0
  180. package/dist/runs/background/async-run-location.js +135 -0
  181. package/dist/runs/background/async-run-record.js +1 -0
  182. package/dist/runs/background/async-run-repair.js +223 -0
  183. package/dist/runs/background/async-run-summary.js +1 -0
  184. package/dist/runs/background/async-single-plan.js +105 -0
  185. package/dist/runs/background/async-status-projection.js +155 -0
  186. package/dist/runs/background/async-status-render.js +117 -0
  187. package/dist/runs/background/async-status-validation.js +181 -0
  188. package/dist/runs/background/async-status.js +3 -442
  189. package/dist/runs/background/async-value.js +21 -0
  190. package/dist/runs/background/completion-dedupe.js +36 -12
  191. package/dist/runs/background/completion-delivery.js +211 -205
  192. package/dist/runs/background/completion-receipts.js +237 -0
  193. package/dist/runs/background/legacy-status-acceptance.js +34 -0
  194. package/dist/runs/background/notify.js +96 -48
  195. package/dist/runs/background/parallel-groups.js +36 -19
  196. package/dist/runs/background/result-payload.js +178 -0
  197. package/dist/runs/background/result-watcher.js +348 -339
  198. package/dist/runs/background/run-id-resolver.js +53 -33
  199. package/dist/runs/background/run-schemas.js +189 -0
  200. package/dist/runs/background/run-status-contracts.js +14 -0
  201. package/dist/runs/background/run-status-render.js +270 -0
  202. package/dist/runs/background/run-status.js +231 -339
  203. package/dist/runs/background/runner-attempt-output.js +155 -0
  204. package/dist/runs/background/runner-attempt.js +263 -0
  205. package/dist/runs/background/runner-child-executor.js +166 -0
  206. package/dist/runs/background/runner-child-observer.js +192 -0
  207. package/dist/runs/background/runner-completion-summary.js +71 -0
  208. package/dist/runs/background/runner-completion.js +211 -0
  209. package/dist/runs/background/runner-config.js +1 -0
  210. package/dist/runs/background/runner-contract.js +1 -0
  211. package/dist/runs/background/runner-dynamic.js +121 -0
  212. package/dist/runs/background/runner-finalization.js +149 -0
  213. package/dist/runs/background/runner-graph.js +68 -0
  214. package/dist/runs/background/runner-initial-status.js +60 -0
  215. package/dist/runs/background/runner-lifecycle.js +142 -0
  216. package/dist/runs/background/runner-monitor.js +309 -0
  217. package/dist/runs/background/runner-parallel.js +204 -0
  218. package/dist/runs/background/runner-prepare-step.js +86 -0
  219. package/dist/runs/background/runner-reporting.js +153 -0
  220. package/dist/runs/background/runner-status.js +148 -0
  221. package/dist/runs/background/runner-step-output.js +92 -0
  222. package/dist/runs/background/runner-step-record.js +45 -0
  223. package/dist/runs/background/runner-step.js +112 -0
  224. package/dist/runs/background/runner-streaming.js +173 -0
  225. package/dist/runs/background/runner-workflow.js +213 -0
  226. package/dist/runs/background/stale-run-reconciler.js +155 -292
  227. package/dist/runs/background/subagent-runner-launcher.js +33 -13
  228. package/dist/runs/background/subagent-runner.js +51 -1842
  229. package/dist/runs/background/top-level-async.js +2 -1
  230. package/dist/runs/foreground/chain-clarify.js +293 -1017
  231. package/dist/runs/foreground/clarification-draft.js +87 -0
  232. package/dist/runs/foreground/clarify-contracts.js +1 -0
  233. package/dist/runs/foreground/clarify-invocation.js +129 -38
  234. package/dist/runs/foreground/clarify-text-editor.js +210 -0
  235. package/dist/runs/foreground/clarify-view.js +167 -0
  236. package/dist/runs/foreground/execution-input.js +226 -353
  237. package/dist/runs/foreground/execution-routing.js +33 -0
  238. package/dist/runs/foreground/execution-timeout.js +81 -0
  239. package/dist/runs/foreground/foreground-control.js +222 -763
  240. package/dist/runs/foreground/foreground-memory.js +99 -0
  241. package/dist/runs/foreground/invocation-context.js +55 -0
  242. package/dist/runs/foreground/invocation-execution.js +331 -0
  243. package/dist/runs/foreground/invocation-expansion.js +48 -0
  244. package/dist/runs/foreground/management-actions.js +295 -0
  245. package/dist/runs/foreground/nested-control.js +179 -0
  246. package/dist/runs/foreground/question-continuation.js +78 -0
  247. package/dist/runs/foreground/question-control.js +155 -50
  248. package/dist/runs/foreground/resume-target.js +221 -0
  249. package/dist/runs/foreground/revival-launch-policy.js +58 -0
  250. package/dist/runs/foreground/run-async-path.js +190 -178
  251. package/dist/runs/foreground/run-interrupt.js +164 -0
  252. package/dist/runs/foreground/run-nudge.js +278 -0
  253. package/dist/runs/foreground/saved-revival.js +251 -0
  254. package/dist/runs/foreground/subagent-executor.js +135 -424
  255. package/dist/runs/foreground/subagent-params.js +67 -30
  256. package/dist/runs/foreground/wait-observation.js +104 -0
  257. package/dist/runs/foreground/wait-registration.js +17 -0
  258. package/dist/runs/foreground/wait-run.js +283 -123
  259. package/dist/runs/shared/acceptance-contract.js +193 -99
  260. package/dist/runs/shared/acceptance-defaults.js +1 -0
  261. package/dist/runs/shared/acceptance-evaluation.js +201 -181
  262. package/dist/runs/shared/acceptance-finalization.js +256 -180
  263. package/dist/runs/shared/acceptance-outcome.js +53 -0
  264. package/dist/runs/shared/acceptance-reports.js +137 -72
  265. package/dist/runs/shared/acceptance-submission.js +167 -0
  266. package/dist/runs/shared/acceptance-verification.js +100 -0
  267. package/dist/runs/shared/chain-outputs.js +80 -52
  268. package/dist/runs/shared/child-attempt-types.js +1 -0
  269. package/dist/runs/shared/child-attempt.js +314 -667
  270. package/dist/runs/shared/child-boundaries.js +173 -0
  271. package/dist/runs/shared/child-context-filter.js +44 -0
  272. package/dist/runs/shared/child-event-observer.js +390 -0
  273. package/dist/runs/shared/child-execution-cwd.js +73 -43
  274. package/dist/runs/shared/child-execution-outcome.js +72 -0
  275. package/dist/runs/shared/child-invocation.js +54 -0
  276. package/dist/runs/shared/child-message-validation.js +215 -0
  277. package/dist/runs/shared/child-native-accounting.js +106 -0
  278. package/dist/runs/shared/child-native-observation.js +69 -0
  279. package/dist/runs/shared/child-observation-spool.js +164 -0
  280. package/dist/runs/shared/child-observations.js +157 -76
  281. package/dist/runs/shared/child-presence.js +3 -0
  282. package/dist/runs/shared/child-route-env.js +119 -0
  283. package/dist/runs/shared/child-stream-observer.js +221 -0
  284. package/dist/runs/shared/child-stream-projection.js +137 -0
  285. package/dist/runs/shared/child-structured-tool.js +27 -0
  286. package/dist/runs/shared/claude-code.js +121 -158
  287. package/dist/runs/shared/claude-model.js +42 -0
  288. package/dist/runs/shared/claude-session.js +83 -0
  289. package/dist/runs/shared/claude-types.js +1 -0
  290. package/dist/runs/shared/completion-guard.js +18 -18
  291. package/dist/runs/shared/control-event-policy.js +8 -0
  292. package/dist/runs/shared/control-notification-owner.js +13 -0
  293. package/dist/runs/shared/dynamic-fanout.js +188 -173
  294. package/dist/runs/shared/dynamic-item.js +102 -0
  295. package/dist/runs/shared/history-index.js +62 -36
  296. package/dist/runs/shared/legacy-async-recovery.js +114 -0
  297. package/dist/runs/shared/legacy-output-recovery.js +148 -0
  298. package/dist/runs/shared/mcp-config-schema.js +36 -0
  299. package/dist/runs/shared/mcp-direct-tool-allowlist.js +147 -116
  300. package/dist/runs/shared/model-fallback.js +97 -38
  301. package/dist/runs/shared/mutating-tool-guard.js +128 -88
  302. package/dist/runs/shared/native-finalization-types.js +1 -0
  303. package/dist/runs/shared/native-finalization.js +155 -76
  304. package/dist/runs/shared/native-usage.js +238 -98
  305. package/dist/runs/shared/nested-control-records.js +128 -0
  306. package/dist/runs/shared/nested-events.js +8 -700
  307. package/dist/runs/shared/nested-path.js +32 -28
  308. package/dist/runs/shared/nested-projection.js +155 -0
  309. package/dist/runs/shared/nested-protocol.js +18 -0
  310. package/dist/runs/shared/nested-registry.js +191 -0
  311. package/dist/runs/shared/nested-render.js +106 -58
  312. package/dist/runs/shared/nested-route.js +220 -0
  313. package/dist/runs/shared/nested-validation.js +216 -0
  314. package/dist/runs/shared/owned-child-evidence.js +125 -0
  315. package/dist/runs/shared/owned-run-list.js +146 -0
  316. package/dist/runs/shared/owned-run-observation.js +267 -0
  317. package/dist/runs/shared/owned-run-progress.js +109 -0
  318. package/dist/runs/shared/owned-run-read-state.js +1 -0
  319. package/dist/runs/shared/owned-run-results.js +202 -0
  320. package/dist/runs/shared/owned-run-status.js +180 -0
  321. package/dist/runs/shared/owned-run-view.js +51 -0
  322. package/dist/runs/shared/owned-workflow-details.js +17 -0
  323. package/dist/runs/shared/owner-output.js +43 -0
  324. package/dist/runs/shared/parallel-utils.js +36 -28
  325. package/dist/runs/shared/parent-receipts.js +90 -32
  326. package/dist/runs/shared/parent-usage.js +169 -57
  327. package/dist/runs/shared/pi-args.js +108 -201
  328. package/dist/runs/shared/pi-launch-input.js +1 -0
  329. package/dist/runs/shared/pi-session-launch.js +86 -0
  330. package/dist/runs/shared/pi-spawn.js +35 -21
  331. package/dist/runs/shared/run-history-queries.js +126 -35
  332. package/dist/runs/shared/run-history.js +101 -35
  333. package/dist/runs/shared/run-metadata-paths.js +14 -0
  334. package/dist/runs/shared/run-metadata.js +158 -0
  335. package/dist/runs/shared/run-persistence.js +131 -0
  336. package/dist/runs/shared/run-records.js +9 -679
  337. package/dist/runs/shared/run-restoration.js +338 -0
  338. package/dist/runs/shared/run-state-owner.js +26 -0
  339. package/dist/runs/shared/session-cwd-preload.js +27 -18
  340. package/dist/runs/shared/single-output.js +148 -70
  341. package/dist/runs/shared/stable-value.js +15 -0
  342. package/dist/runs/shared/streaming-text.js +23 -12
  343. package/dist/runs/shared/structured-output.js +25 -13
  344. package/dist/runs/shared/subagent-control.js +167 -100
  345. package/dist/runs/shared/subagent-prompt-runtime.js +27 -130
  346. package/dist/runs/shared/subagent-tool-loop-guard.js +81 -52
  347. package/dist/runs/shared/supervisor-question-state.js +145 -0
  348. package/dist/runs/shared/supervisor-questions.js +185 -254
  349. package/dist/runs/shared/workflow-graph.js +259 -167
  350. package/dist/runs/shared/workflow-policy.js +120 -48
  351. package/dist/runs/shared/worktree-contract.js +1 -0
  352. package/dist/runs/shared/worktree-hook.js +138 -0
  353. package/dist/runs/shared/worktree-location.js +47 -0
  354. package/dist/runs/shared/worktree-preservation.js +8 -0
  355. package/dist/runs/shared/worktree-process.js +107 -0
  356. package/dist/runs/shared/worktree.js +183 -322
  357. package/dist/shared/agent-context-policy.js +34 -44
  358. package/dist/shared/agent-dir.js +14 -0
  359. package/dist/shared/artifacts.js +30 -12
  360. package/dist/shared/atomic-json.js +4 -1
  361. package/dist/shared/chain-files.js +72 -0
  362. package/dist/shared/concurrency.js +18 -0
  363. package/dist/shared/content-preview.js +115 -0
  364. package/dist/shared/cooperative.js +5 -2
  365. package/dist/shared/execution-cwd.js +13 -5
  366. package/dist/shared/file-coalescer.js +2 -1
  367. package/dist/shared/fork-context.js +10 -12
  368. package/dist/shared/formatters.js +45 -19
  369. package/dist/shared/journal-frames.js +164 -0
  370. package/dist/shared/journal-projections.js +121 -0
  371. package/dist/shared/journal-reader.js +6 -407
  372. package/dist/shared/json-projection.js +191 -0
  373. package/dist/shared/lazy-tools.js +19 -8
  374. package/dist/shared/message-output.js +116 -0
  375. package/dist/shared/model-info.js +31 -14
  376. package/dist/shared/native-import.js +20 -0
  377. package/dist/shared/native-journal.js +140 -0
  378. package/dist/shared/native-session-loader.js +17 -0
  379. package/dist/shared/native-session.js +2 -13
  380. package/dist/shared/native-tui.js +7 -2
  381. package/dist/shared/native-typebox.js +15 -3
  382. package/dist/shared/output-page.js +63 -0
  383. package/dist/shared/post-exit-stdio-guard.js +128 -88
  384. package/dist/shared/prompt-sections.js +2 -0
  385. package/dist/shared/session-entries.js +70 -35
  386. package/dist/shared/session-identity.js +5 -3
  387. package/dist/shared/settings.js +62 -192
  388. package/dist/shared/status-format.js +97 -37
  389. package/dist/shared/task-file-policy.js +24 -0
  390. package/dist/shared/temp-root.js +44 -15
  391. package/dist/shared/types/acceptance.js +1 -0
  392. package/dist/shared/types/async.js +1 -0
  393. package/dist/shared/types/config.js +1 -0
  394. package/dist/shared/types/details.js +1 -0
  395. package/dist/shared/types/history.js +1 -0
  396. package/dist/shared/types/inputs.js +1 -0
  397. package/dist/shared/types/intercom.js +1 -0
  398. package/dist/shared/types/launch.js +1 -0
  399. package/dist/shared/types/messages.js +1 -0
  400. package/dist/shared/types/nested.js +1 -0
  401. package/dist/shared/types/owned-runs.js +1 -0
  402. package/dist/shared/types/progress.js +1 -0
  403. package/dist/shared/types/questions.js +1 -0
  404. package/dist/shared/types/results.js +1 -0
  405. package/dist/shared/types/state.js +1 -0
  406. package/dist/shared/types/usage.js +1 -0
  407. package/dist/shared/types/workflow.js +1 -0
  408. package/dist/shared/types.js +75 -30
  409. package/dist/shared/unknown.js +52 -0
  410. package/dist/shared/utils.js +54 -260
  411. package/dist/slash/command-discovery.js +82 -0
  412. package/dist/slash/command-input.js +190 -0
  413. package/dist/slash/prompt-template-bridge.js +94 -270
  414. package/dist/slash/prompt-template-contract.js +77 -0
  415. package/dist/slash/prompt-template-results.js +125 -0
  416. package/dist/slash/request-protocol.js +68 -0
  417. package/dist/slash/result-delivery.js +237 -0
  418. package/dist/slash/saved-chain.js +78 -0
  419. package/dist/slash/slash-bridge.js +123 -89
  420. package/dist/slash/slash-commands.js +101 -572
  421. package/dist/slash/slash-live-state.js +68 -47
  422. package/dist/tui/action-hints.js +50 -22
  423. package/dist/tui/activity-lines.js +32 -0
  424. package/dist/tui/agent-browser.js +290 -0
  425. package/dist/tui/agent-controls.js +289 -0
  426. package/dist/tui/agent-conversation.js +444 -0
  427. package/dist/tui/agent-dock.js +171 -0
  428. package/dist/tui/agent-history.js +50 -183
  429. package/dist/tui/agent-model.js +62 -0
  430. package/dist/tui/agent-picker.js +262 -0
  431. package/dist/tui/agent-view.js +232 -1564
  432. package/dist/tui/compact-results.js +193 -0
  433. package/dist/tui/conversation-details.js +190 -0
  434. package/dist/tui/conversation-frame.js +135 -0
  435. package/dist/tui/conversation-history.js +201 -0
  436. package/dist/tui/conversation-menu.js +78 -0
  437. package/dist/tui/conversation-notices.js +79 -0
  438. package/dist/tui/conversation-selection.js +58 -0
  439. package/dist/tui/conversation-viewport.js +129 -0
  440. package/dist/tui/direction-message.js +27 -0
  441. package/dist/tui/display.js +282 -0
  442. package/dist/tui/editor-viewport.js +18 -0
  443. package/dist/tui/expanded-content.js +87 -0
  444. package/dist/tui/expanded-multi.js +170 -0
  445. package/dist/tui/expanded-single.js +65 -0
  446. package/dist/tui/history-cards.js +216 -0
  447. package/dist/tui/history-display.js +238 -0
  448. package/dist/tui/history-json.js +16 -0
  449. package/dist/tui/history-metadata.js +152 -0
  450. package/dist/tui/history-record.js +251 -0
  451. package/dist/tui/history-text.js +34 -0
  452. package/dist/tui/indexed-history.js +116 -0
  453. package/dist/tui/nested-widget.js +120 -0
  454. package/dist/tui/picker-page.js +59 -0
  455. package/dist/tui/render.js +58 -1501
  456. package/dist/tui/result-facts.js +64 -0
  457. package/dist/tui/task-observation.js +59 -0
  458. package/dist/tui/task-store.js +366 -0
  459. package/dist/tui/text-values.js +16 -0
  460. package/dist/tui/view-connections.js +47 -0
  461. package/dist/tui/view-model.js +94 -0
  462. package/dist/tui/view-persistence.js +51 -0
  463. package/dist/tui/view-ports.js +1 -0
  464. package/dist/tui/view-session.js +37 -0
  465. package/dist/tui/widget-details.js +144 -0
  466. package/dist/tui/widget-status.js +245 -0
  467. package/dist/tui/widget.js +145 -0
  468. package/dist/tui/workflow-labels.js +223 -0
  469. package/dist/tui/workflow-outcomes.js +124 -0
  470. package/docs/code-quality.md +38 -0
  471. package/docs/development.md +99 -0
  472. package/docs/intercom-bridge.md +77 -22
  473. package/docs/intercom.md +132 -106
  474. package/docs/performance.md +19 -17
  475. package/docs/reference.md +1472 -0
  476. package/generated/RunValidators.d.ts +28 -0
  477. package/generated/RunValidators.js +2 -0
  478. package/package.json +27 -6
  479. package/prompts/parallel-cleanup.md +3 -0
  480. package/prompts/parallel-context-build.md +3 -0
  481. package/prompts/parallel-handoff-plan.md +6 -0
  482. package/prompts/parallel-research.md +4 -0
  483. package/prompts/parallel-review.md +2 -0
  484. package/prompts/review-loop.md +2 -0
  485. package/scripts/build.mjs +129 -85
  486. package/scripts/check-compat.mjs +48 -11
  487. package/scripts/compat-host.mjs +35 -7
  488. package/scripts/generate-run-schemas.mjs +210 -0
  489. package/scripts/intercom-bridge-credentials.mjs +158 -29
  490. package/scripts/intercom-remote.mjs +213 -52
  491. package/scripts/local-install-smoke.mjs +47 -37
  492. package/scripts/native-package-smoke.mjs +135 -25
  493. package/scripts/package-smoke.mjs +360 -140
  494. package/scripts/prepare.mjs +54 -34
  495. package/scripts/real-pi-processes.mjs +261 -0
  496. package/scripts/real-pi-smoke.mjs +432 -351
  497. package/scripts/run-tests.mjs +29 -15
  498. package/skills/pi-intercom/SKILL.md +11 -11
  499. package/skills/pi-intercom/references/peer-sessions.md +7 -2
  500. package/skills/pi-subagents/SKILL.md +1 -1
  501. package/skills/pi-subagents/references/full-orchestration-guide.md +254 -112
  502. package/src/agents/agent-defaults.ts +13 -0
  503. package/src/agents/agent-definition.ts +253 -0
  504. package/src/agents/agent-management.ts +111 -808
  505. package/src/agents/agent-scope.ts +7 -3
  506. package/src/agents/agent-selection.ts +26 -16
  507. package/src/agents/agent-serializer.ts +84 -93
  508. package/src/agents/agents.ts +199 -906
  509. package/src/agents/builtin-overrides.ts +297 -0
  510. package/src/agents/chain-serializer.ts +3 -329
  511. package/src/agents/config-values.ts +57 -0
  512. package/src/agents/discovery-paths.ts +134 -0
  513. package/src/agents/frontmatter.ts +35 -17
  514. package/src/agents/identity.ts +49 -18
  515. package/src/agents/json-chain.ts +305 -0
  516. package/src/agents/management-config.ts +342 -0
  517. package/src/agents/management-format.ts +243 -0
  518. package/src/agents/management-persistence.ts +408 -0
  519. package/src/agents/management-targets.ts +260 -0
  520. package/src/agents/management-warnings.ts +115 -0
  521. package/src/agents/markdown-chain.ts +237 -0
  522. package/src/agents/package-agents.ts +231 -0
  523. package/src/agents/skill-files.ts +182 -0
  524. package/src/agents/skill-search-paths.ts +289 -0
  525. package/src/agents/skill-types.ts +31 -0
  526. package/src/agents/skills.ts +152 -610
  527. package/src/extension/acceptance-schema.ts +88 -0
  528. package/src/extension/chain-schema.ts +276 -0
  529. package/src/extension/child-runtime.ts +302 -0
  530. package/src/extension/compact-tools.ts +259 -102
  531. package/src/extension/config-schema.ts +59 -0
  532. package/src/extension/config.ts +39 -17
  533. package/src/extension/control-notice-schema.ts +55 -0
  534. package/src/extension/control-notices.ts +57 -33
  535. package/src/extension/delegation-bridges.ts +59 -0
  536. package/src/extension/doctor.ts +171 -135
  537. package/src/extension/everyday-schemas.ts +252 -0
  538. package/src/extension/fanout-child.ts +29 -308
  539. package/src/extension/index.ts +17 -642
  540. package/src/extension/message-renderers.ts +334 -0
  541. package/src/extension/nested-control-inbox.ts +196 -0
  542. package/src/extension/parent-runtime.ts +405 -0
  543. package/src/extension/primary-tool.ts +130 -0
  544. package/src/extension/result-snapshot.ts +35 -0
  545. package/src/extension/runtime-reload.ts +72 -0
  546. package/src/extension/runtime-storage.ts +49 -0
  547. package/src/extension/schema-overrides.ts +114 -0
  548. package/src/extension/schemas.ts +451 -418
  549. package/src/extension/tool-input.ts +40 -13
  550. package/src/extension/tool-result.ts +45 -14
  551. package/src/history/answer-texts.ts +74 -0
  552. package/src/history/canonical-result.ts +127 -51
  553. package/src/history/canonical-selection.ts +54 -0
  554. package/src/history/database-generation.ts +86 -0
  555. package/src/history/database.ts +86 -48
  556. package/src/history/entry-ingestion.ts +129 -0
  557. package/src/history/index.ts +426 -148
  558. package/src/history/ingest.ts +372 -342
  559. package/src/history/output-digests.ts +41 -0
  560. package/src/history/preview.ts +235 -0
  561. package/src/history/prune.ts +48 -0
  562. package/src/history/queries.ts +122 -256
  563. package/src/history/query-scope.ts +278 -0
  564. package/src/history/rows.ts +118 -0
  565. package/src/history/run-projection.ts +164 -0
  566. package/src/history/run-queries.ts +199 -0
  567. package/src/history/schema.ts +34 -0
  568. package/src/history/search-queries.ts +216 -0
  569. package/src/history/selected-record.ts +140 -0
  570. package/src/history/source-file.ts +51 -0
  571. package/src/history/source-watches.ts +156 -0
  572. package/src/history/store.ts +310 -197
  573. package/src/history/text-chunks.ts +181 -0
  574. package/src/history/text.ts +43 -0
  575. package/src/history/transcript-queries.ts +251 -0
  576. package/src/history/types.ts +27 -164
  577. package/src/history/values.ts +36 -0
  578. package/src/history/wire-inputs.ts +141 -0
  579. package/src/history/wire-models.ts +51 -0
  580. package/src/history/worker-runtime.ts +502 -0
  581. package/src/history/worker.ts +94 -336
  582. package/src/intercom/intercom-bridge.ts +136 -69
  583. package/src/intercom/live-intercom.ts +197 -92
  584. package/src/intercom/nested-result-tree.ts +213 -0
  585. package/src/intercom/result-delivery.ts +56 -0
  586. package/src/intercom/result-intercom.ts +364 -382
  587. package/src/pi-intercom/agent-dir.ts +9 -3
  588. package/src/pi-intercom/async.ts +33 -0
  589. package/src/pi-intercom/bridge-ask.ts +64 -0
  590. package/src/pi-intercom/bridge-config.ts +120 -0
  591. package/src/pi-intercom/bridge-http.ts +97 -0
  592. package/src/pi-intercom/bridge-launch-policy.ts +109 -0
  593. package/src/pi-intercom/bridge-launch.ts +317 -0
  594. package/src/pi-intercom/bridge-protocol.ts +123 -0
  595. package/src/pi-intercom/bridge-routes.ts +105 -0
  596. package/src/pi-intercom/bridge-rpc-process.ts +293 -0
  597. package/src/pi-intercom/bridge-session.ts +510 -0
  598. package/src/pi-intercom/bridge.ts +305 -549
  599. package/src/pi-intercom/broker/broker.ts +326 -263
  600. package/src/pi-intercom/broker/client.ts +273 -354
  601. package/src/pi-intercom/broker/connection.ts +192 -0
  602. package/src/pi-intercom/broker/framing.ts +11 -6
  603. package/src/pi-intercom/broker/paths.ts +28 -25
  604. package/src/pi-intercom/broker/pid.ts +68 -24
  605. package/src/pi-intercom/broker/snapshot-reader.ts +91 -0
  606. package/src/pi-intercom/broker/snapshots.ts +241 -0
  607. package/src/pi-intercom/broker/spawn.ts +58 -34
  608. package/src/pi-intercom/config.ts +113 -108
  609. package/src/pi-intercom/connection.ts +346 -0
  610. package/src/pi-intercom/identity.ts +71 -0
  611. package/src/pi-intercom/inbound-delivery.ts +450 -0
  612. package/src/pi-intercom/inbound-journal.ts +350 -0
  613. package/src/pi-intercom/inbound-record.ts +141 -0
  614. package/src/pi-intercom/inbound.ts +237 -0
  615. package/src/pi-intercom/index.ts +86 -2923
  616. package/src/pi-intercom/inspection.ts +82 -0
  617. package/src/pi-intercom/interview.ts +295 -0
  618. package/src/pi-intercom/lifecycle.ts +183 -0
  619. package/src/pi-intercom/message-format.ts +77 -0
  620. package/src/pi-intercom/outbound.ts +418 -0
  621. package/src/pi-intercom/peer-awareness.ts +84 -0
  622. package/src/pi-intercom/reply-tracker.ts +121 -59
  623. package/src/pi-intercom/reply-wait.ts +247 -0
  624. package/src/pi-intercom/runtime-types.ts +97 -0
  625. package/src/pi-intercom/session-events.ts +247 -0
  626. package/src/pi-intercom/session-targets.ts +124 -72
  627. package/src/pi-intercom/subagent-events.ts +299 -0
  628. package/src/pi-intercom/subagent-live-events.ts +212 -109
  629. package/src/pi-intercom/supervisor.ts +362 -0
  630. package/src/pi-intercom/tool-arguments.ts +120 -0
  631. package/src/pi-intercom/tool-registration.ts +121 -0
  632. package/src/pi-intercom/tool-results.ts +54 -0
  633. package/src/pi-intercom/tool-schemas.ts +134 -0
  634. package/src/pi-intercom/tools.ts +80 -0
  635. package/src/pi-intercom/topic-actions.ts +243 -0
  636. package/src/pi-intercom/topics.ts +267 -121
  637. package/src/pi-intercom/transport.ts +14 -0
  638. package/src/pi-intercom/types.ts +288 -190
  639. package/src/pi-intercom/ui/compose-paste.ts +109 -0
  640. package/src/pi-intercom/ui/compose.ts +173 -157
  641. package/src/pi-intercom/ui/inline-message.ts +80 -62
  642. package/src/pi-intercom/ui/message-renderers.ts +182 -0
  643. package/src/pi-intercom/ui/overlay.ts +238 -0
  644. package/src/pi-intercom/ui/session-format.ts +146 -0
  645. package/src/pi-intercom/ui/session-list.ts +145 -62
  646. package/src/pi-intercom/ui/tool-renderers.ts +148 -0
  647. package/src/pi-intercom/ui/topic-view.ts +107 -0
  648. package/src/pi-intercom/validation.ts +69 -0
  649. package/src/runs/background/async-chain-plan.ts +451 -0
  650. package/src/runs/background/async-control.ts +201 -71
  651. package/src/runs/background/async-execution.ts +206 -829
  652. package/src/runs/background/async-job-admission.ts +54 -0
  653. package/src/runs/background/async-job-projection.ts +225 -0
  654. package/src/runs/background/async-job-tracker.ts +416 -360
  655. package/src/runs/background/async-launch.ts +319 -0
  656. package/src/runs/background/async-plan.ts +285 -0
  657. package/src/runs/background/async-result-file.ts +79 -37
  658. package/src/runs/background/async-resume.ts +338 -285
  659. package/src/runs/background/async-run-discovery.ts +270 -0
  660. package/src/runs/background/async-run-location.ts +194 -0
  661. package/src/runs/background/async-run-record.ts +14 -0
  662. package/src/runs/background/async-run-repair.ts +307 -0
  663. package/src/runs/background/async-run-summary.ts +71 -0
  664. package/src/runs/background/async-single-plan.ts +168 -0
  665. package/src/runs/background/async-status-projection.ts +188 -0
  666. package/src/runs/background/async-status-render.ts +164 -0
  667. package/src/runs/background/async-status-validation.ts +238 -0
  668. package/src/runs/background/async-status.ts +9 -481
  669. package/src/runs/background/async-value.ts +29 -0
  670. package/src/runs/background/completion-dedupe.ts +103 -54
  671. package/src/runs/background/completion-delivery.ts +313 -187
  672. package/src/runs/background/completion-receipts.ts +309 -0
  673. package/src/runs/background/legacy-status-acceptance.ts +38 -0
  674. package/src/runs/background/notify.ts +167 -106
  675. package/src/runs/background/parallel-groups.ts +95 -46
  676. package/src/runs/background/result-payload.ts +268 -0
  677. package/src/runs/background/result-watcher.ts +484 -387
  678. package/src/runs/background/run-id-resolver.ts +126 -57
  679. package/src/runs/background/run-schemas.ts +240 -0
  680. package/src/runs/background/run-status-contracts.ts +46 -0
  681. package/src/runs/background/run-status-render.ts +364 -0
  682. package/src/runs/background/run-status.ts +338 -356
  683. package/src/runs/background/runner-attempt-output.ts +281 -0
  684. package/src/runs/background/runner-attempt.ts +354 -0
  685. package/src/runs/background/runner-child-executor.ts +232 -0
  686. package/src/runs/background/runner-child-observer.ts +270 -0
  687. package/src/runs/background/runner-completion-summary.ts +106 -0
  688. package/src/runs/background/runner-completion.ts +274 -0
  689. package/src/runs/background/runner-config.ts +52 -0
  690. package/src/runs/background/runner-contract.ts +51 -0
  691. package/src/runs/background/runner-dynamic.ts +185 -0
  692. package/src/runs/background/runner-finalization.ts +203 -0
  693. package/src/runs/background/runner-graph.ts +91 -0
  694. package/src/runs/background/runner-initial-status.ts +72 -0
  695. package/src/runs/background/runner-lifecycle.ts +159 -0
  696. package/src/runs/background/runner-monitor.ts +399 -0
  697. package/src/runs/background/runner-parallel.ts +280 -0
  698. package/src/runs/background/runner-prepare-step.ts +128 -0
  699. package/src/runs/background/runner-reporting.ts +192 -0
  700. package/src/runs/background/runner-status.ts +220 -0
  701. package/src/runs/background/runner-step-output.ts +158 -0
  702. package/src/runs/background/runner-step-record.ts +76 -0
  703. package/src/runs/background/runner-step.ts +150 -0
  704. package/src/runs/background/runner-streaming.ts +220 -0
  705. package/src/runs/background/runner-workflow.ts +284 -0
  706. package/src/runs/background/stale-run-reconciler.ts +279 -336
  707. package/src/runs/background/subagent-runner-launcher.ts +67 -35
  708. package/src/runs/background/subagent-runner.ts +80 -2048
  709. package/src/runs/background/top-level-async.ts +9 -7
  710. package/src/runs/foreground/chain-clarify.ts +499 -1334
  711. package/src/runs/foreground/clarification-draft.ts +92 -0
  712. package/src/runs/foreground/clarify-contracts.ts +33 -0
  713. package/src/runs/foreground/clarify-invocation.ts +192 -65
  714. package/src/runs/foreground/clarify-text-editor.ts +229 -0
  715. package/src/runs/foreground/clarify-view.ts +222 -0
  716. package/src/runs/foreground/execution-input.ts +358 -424
  717. package/src/runs/foreground/execution-routing.ts +41 -0
  718. package/src/runs/foreground/execution-timeout.ts +92 -0
  719. package/src/runs/foreground/foreground-control.ts +333 -812
  720. package/src/runs/foreground/foreground-memory.ts +132 -0
  721. package/src/runs/foreground/invocation-context.ts +88 -0
  722. package/src/runs/foreground/invocation-execution.ts +465 -0
  723. package/src/runs/foreground/invocation-expansion.ts +58 -0
  724. package/src/runs/foreground/management-actions.ts +360 -0
  725. package/src/runs/foreground/nested-control.ts +248 -0
  726. package/src/runs/foreground/question-continuation.ts +112 -0
  727. package/src/runs/foreground/question-control.ts +297 -70
  728. package/src/runs/foreground/resume-target.ts +330 -0
  729. package/src/runs/foreground/revival-launch-policy.ts +112 -0
  730. package/src/runs/foreground/run-async-path.ts +307 -223
  731. package/src/runs/foreground/run-interrupt.ts +202 -0
  732. package/src/runs/foreground/run-nudge.ts +355 -0
  733. package/src/runs/foreground/saved-revival.ts +356 -0
  734. package/src/runs/foreground/subagent-executor.ts +195 -493
  735. package/src/runs/foreground/subagent-params.ts +314 -242
  736. package/src/runs/foreground/wait-observation.ts +160 -0
  737. package/src/runs/foreground/wait-registration.ts +18 -0
  738. package/src/runs/foreground/wait-run.ts +361 -119
  739. package/src/runs/shared/acceptance-contract.ts +410 -209
  740. package/src/runs/shared/acceptance-defaults.ts +1 -0
  741. package/src/runs/shared/acceptance-evaluation.ts +314 -240
  742. package/src/runs/shared/acceptance-finalization.ts +447 -305
  743. package/src/runs/shared/acceptance-outcome.ts +69 -0
  744. package/src/runs/shared/acceptance-reports.ts +220 -126
  745. package/src/runs/shared/acceptance-submission.ts +251 -0
  746. package/src/runs/shared/acceptance-verification.ts +118 -0
  747. package/src/runs/shared/acceptance.ts +25 -25
  748. package/src/runs/shared/chain-outputs.ts +190 -98
  749. package/src/runs/shared/child-attempt-types.ts +118 -0
  750. package/src/runs/shared/child-attempt.ts +372 -608
  751. package/src/runs/shared/child-boundaries.ts +217 -0
  752. package/src/runs/shared/child-context-filter.ts +53 -0
  753. package/src/runs/shared/child-event-observer.ts +496 -0
  754. package/src/runs/shared/child-execution-cwd.ts +139 -68
  755. package/src/runs/shared/child-execution-outcome.ts +103 -0
  756. package/src/runs/shared/child-invocation.ts +74 -0
  757. package/src/runs/shared/child-message-validation.ts +233 -0
  758. package/src/runs/shared/child-native-accounting.ts +154 -0
  759. package/src/runs/shared/child-native-observation.ts +79 -0
  760. package/src/runs/shared/child-observation-spool.ts +188 -0
  761. package/src/runs/shared/child-observations.ts +219 -89
  762. package/src/runs/shared/child-presence.ts +6 -0
  763. package/src/runs/shared/child-route-env.ts +142 -0
  764. package/src/runs/shared/child-stream-observer.ts +302 -0
  765. package/src/runs/shared/child-stream-projection.ts +160 -0
  766. package/src/runs/shared/child-structured-tool.ts +38 -0
  767. package/src/runs/shared/claude-code.ts +201 -228
  768. package/src/runs/shared/claude-model.ts +67 -0
  769. package/src/runs/shared/claude-session.ts +124 -0
  770. package/src/runs/shared/claude-types.ts +31 -0
  771. package/src/runs/shared/completion-guard.ts +35 -26
  772. package/src/runs/shared/control-event-policy.ts +15 -0
  773. package/src/runs/shared/control-notification-owner.ts +20 -0
  774. package/src/runs/shared/dynamic-fanout.ts +402 -238
  775. package/src/runs/shared/dynamic-item.ts +114 -0
  776. package/src/runs/shared/history-index.ts +112 -51
  777. package/src/runs/shared/legacy-async-recovery.ts +153 -0
  778. package/src/runs/shared/legacy-output-recovery.ts +214 -0
  779. package/src/runs/shared/mcp-config-schema.ts +46 -0
  780. package/src/runs/shared/mcp-direct-tool-allowlist.ts +396 -307
  781. package/src/runs/shared/model-fallback.ts +302 -180
  782. package/src/runs/shared/mutating-tool-guard.ts +259 -158
  783. package/src/runs/shared/native-finalization-types.ts +29 -0
  784. package/src/runs/shared/native-finalization.ts +233 -109
  785. package/src/runs/shared/native-usage.ts +379 -96
  786. package/src/runs/shared/nested-control-records.ts +178 -0
  787. package/src/runs/shared/nested-events.ts +45 -752
  788. package/src/runs/shared/nested-path.ts +47 -34
  789. package/src/runs/shared/nested-projection.ts +230 -0
  790. package/src/runs/shared/nested-protocol.ts +67 -0
  791. package/src/runs/shared/nested-registry.ts +273 -0
  792. package/src/runs/shared/nested-render.ts +198 -100
  793. package/src/runs/shared/nested-route.ts +292 -0
  794. package/src/runs/shared/nested-validation.ts +291 -0
  795. package/src/runs/shared/owned-child-evidence.ts +184 -0
  796. package/src/runs/shared/owned-run-list.ts +187 -0
  797. package/src/runs/shared/owned-run-observation.ts +368 -0
  798. package/src/runs/shared/owned-run-progress.ts +172 -0
  799. package/src/runs/shared/owned-run-read-state.ts +7 -0
  800. package/src/runs/shared/owned-run-results.ts +289 -0
  801. package/src/runs/shared/owned-run-status.ts +239 -0
  802. package/src/runs/shared/owned-run-view.ts +65 -0
  803. package/src/runs/shared/owned-workflow-details.ts +24 -0
  804. package/src/runs/shared/owner-output.ts +73 -0
  805. package/src/runs/shared/parallel-utils.ts +93 -129
  806. package/src/runs/shared/parent-receipts.ts +177 -50
  807. package/src/runs/shared/parent-usage.ts +314 -91
  808. package/src/runs/shared/pi-args.ts +241 -311
  809. package/src/runs/shared/pi-launch-input.ts +48 -0
  810. package/src/runs/shared/pi-session-launch.ts +94 -0
  811. package/src/runs/shared/pi-spawn.ts +57 -33
  812. package/src/runs/shared/run-history-queries.ts +189 -38
  813. package/src/runs/shared/run-history.ts +197 -76
  814. package/src/runs/shared/run-id-ambiguity.ts +7 -3
  815. package/src/runs/shared/run-metadata-paths.ts +17 -0
  816. package/src/runs/shared/run-metadata.ts +240 -0
  817. package/src/runs/shared/run-persistence.ts +181 -0
  818. package/src/runs/shared/run-records.ts +19 -607
  819. package/src/runs/shared/run-restoration.ts +455 -0
  820. package/src/runs/shared/run-state-owner.ts +31 -0
  821. package/src/runs/shared/session-cwd-preload.ts +39 -19
  822. package/src/runs/shared/single-output.ts +358 -205
  823. package/src/runs/shared/stable-value.ts +15 -0
  824. package/src/runs/shared/streaming-text.ts +39 -12
  825. package/src/runs/shared/structured-output.ts +76 -46
  826. package/src/runs/shared/subagent-control.ts +330 -197
  827. package/src/runs/shared/subagent-prompt-runtime.ts +92 -174
  828. package/src/runs/shared/subagent-tool-loop-guard.ts +118 -68
  829. package/src/runs/shared/supervisor-question-state.ts +221 -0
  830. package/src/runs/shared/supervisor-questions.ts +396 -401
  831. package/src/runs/shared/workflow-graph.ts +400 -198
  832. package/src/runs/shared/workflow-policy.ts +245 -110
  833. package/src/runs/shared/worktree-contract.ts +29 -0
  834. package/src/runs/shared/worktree-hook.ts +181 -0
  835. package/src/runs/shared/worktree-location.ts +61 -0
  836. package/src/runs/shared/worktree-preservation.ts +10 -0
  837. package/src/runs/shared/worktree-process.ts +132 -0
  838. package/src/runs/shared/worktree.ts +459 -587
  839. package/src/shared/agent-context-policy.ts +176 -145
  840. package/src/shared/agent-dir.ts +15 -0
  841. package/src/shared/artifacts.ts +99 -68
  842. package/src/shared/atomic-json.ts +14 -11
  843. package/src/shared/chain-files.ts +72 -0
  844. package/src/shared/concurrency.ts +27 -0
  845. package/src/shared/content-preview.ts +117 -0
  846. package/src/shared/cooperative.ts +17 -13
  847. package/src/shared/execution-cwd.ts +34 -9
  848. package/src/shared/file-coalescer.ts +24 -22
  849. package/src/shared/fork-context.ts +52 -48
  850. package/src/shared/formatters.ts +88 -47
  851. package/src/shared/journal-frames.ts +197 -0
  852. package/src/shared/journal-projections.ts +133 -0
  853. package/src/shared/journal-reader.ts +18 -333
  854. package/src/shared/json-projection.ts +224 -0
  855. package/src/shared/lazy-tools.ts +76 -27
  856. package/src/shared/message-output.ts +146 -0
  857. package/src/shared/model-info.ts +94 -58
  858. package/src/shared/native-import.ts +25 -0
  859. package/src/shared/native-journal.ts +172 -0
  860. package/src/shared/native-session-loader.ts +13 -0
  861. package/src/shared/native-session.ts +3 -5
  862. package/src/shared/native-tui.ts +13 -3
  863. package/src/shared/native-typebox.ts +18 -3
  864. package/src/shared/output-page.ts +76 -0
  865. package/src/shared/post-exit-stdio-guard.ts +232 -172
  866. package/src/shared/prompt-sections.ts +13 -7
  867. package/src/shared/session-entries.ts +103 -44
  868. package/src/shared/session-identity.ts +17 -10
  869. package/src/shared/settings.ts +182 -367
  870. package/src/shared/status-format.ts +207 -98
  871. package/src/shared/stream-json.d.ts +10 -0
  872. package/src/shared/task-file-policy.ts +35 -0
  873. package/src/shared/temp-root.ts +122 -71
  874. package/src/shared/types/acceptance.ts +149 -0
  875. package/src/shared/types/async.ts +247 -0
  876. package/src/shared/types/config.ts +139 -0
  877. package/src/shared/types/details.ts +104 -0
  878. package/src/shared/types/history.ts +217 -0
  879. package/src/shared/types/inputs.ts +4 -0
  880. package/src/shared/types/intercom.ts +57 -0
  881. package/src/shared/types/launch.ts +39 -0
  882. package/src/shared/types/messages.ts +104 -0
  883. package/src/shared/types/nested.ts +153 -0
  884. package/src/shared/types/owned-runs.ts +148 -0
  885. package/src/shared/types/progress.ts +106 -0
  886. package/src/shared/types/questions.ts +103 -0
  887. package/src/shared/types/results.ts +119 -0
  888. package/src/shared/types/state.ts +56 -0
  889. package/src/shared/types/usage.ts +36 -0
  890. package/src/shared/types/workflow.ts +187 -0
  891. package/src/shared/types.ts +222 -1161
  892. package/src/shared/ui-mode.ts +1 -1
  893. package/src/shared/unknown.ts +59 -0
  894. package/src/shared/utils.ts +111 -305
  895. package/src/slash/command-discovery.ts +109 -0
  896. package/src/slash/command-input.ts +232 -0
  897. package/src/slash/prompt-template-bridge.ts +153 -400
  898. package/src/slash/prompt-template-contract.ts +152 -0
  899. package/src/slash/prompt-template-results.ts +189 -0
  900. package/src/slash/request-protocol.ts +87 -0
  901. package/src/slash/result-delivery.ts +312 -0
  902. package/src/slash/saved-chain.ts +115 -0
  903. package/src/slash/slash-bridge.ts +202 -156
  904. package/src/slash/slash-commands.ts +176 -598
  905. package/src/slash/slash-live-state.ts +287 -229
  906. package/src/tui/action-hints.ts +147 -61
  907. package/src/tui/activity-lines.ts +40 -0
  908. package/src/tui/agent-browser.ts +354 -0
  909. package/src/tui/agent-controls.ts +355 -0
  910. package/src/tui/agent-conversation.ts +514 -0
  911. package/src/tui/agent-dock.ts +250 -0
  912. package/src/tui/agent-history.ts +78 -203
  913. package/src/tui/agent-model.ts +78 -0
  914. package/src/tui/agent-picker.ts +325 -0
  915. package/src/tui/agent-view.ts +391 -1333
  916. package/src/tui/compact-results.ts +342 -0
  917. package/src/tui/conversation-details.ts +206 -0
  918. package/src/tui/conversation-frame.ts +184 -0
  919. package/src/tui/conversation-history.ts +246 -0
  920. package/src/tui/conversation-menu.ts +119 -0
  921. package/src/tui/conversation-notices.ts +116 -0
  922. package/src/tui/conversation-selection.ts +66 -0
  923. package/src/tui/conversation-viewport.ts +169 -0
  924. package/src/tui/direction-message.ts +35 -0
  925. package/src/tui/display.ts +409 -0
  926. package/src/tui/editor-viewport.ts +19 -0
  927. package/src/tui/expanded-content.ts +134 -0
  928. package/src/tui/expanded-multi.ts +264 -0
  929. package/src/tui/expanded-single.ts +92 -0
  930. package/src/tui/history-cards.ts +316 -0
  931. package/src/tui/history-display.ts +334 -0
  932. package/src/tui/history-json.ts +17 -0
  933. package/src/tui/history-metadata.ts +177 -0
  934. package/src/tui/history-record.ts +321 -0
  935. package/src/tui/history-text.ts +34 -0
  936. package/src/tui/indexed-history.ts +149 -0
  937. package/src/tui/nested-widget.ts +192 -0
  938. package/src/tui/picker-page.ts +80 -0
  939. package/src/tui/render.ts +100 -1546
  940. package/src/tui/result-facts.ts +99 -0
  941. package/src/tui/task-observation.ts +96 -0
  942. package/src/tui/task-store.ts +432 -0
  943. package/src/tui/text-values.ts +20 -0
  944. package/src/tui/view-connections.ts +64 -0
  945. package/src/tui/view-model.ts +181 -0
  946. package/src/tui/view-persistence.ts +57 -0
  947. package/src/tui/view-ports.ts +55 -0
  948. package/src/tui/view-session.ts +42 -0
  949. package/src/tui/widget-details.ts +220 -0
  950. package/src/tui/widget-status.ts +331 -0
  951. package/src/tui/widget.ts +208 -0
  952. package/src/tui/workflow-labels.ts +340 -0
  953. package/src/tui/workflow-outcomes.ts +150 -0
  954. package/tsconfig.build.json +11 -10
  955. package/tsconfig.json +30 -17
@@ -0,0 +1,405 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
3
+ import { discoverAgents } from "../agents/agents.ts";
4
+ import {
5
+ ARTIFACT_CLEANUP_DAYS,
6
+ cleanupAllArtifactDirs,
7
+ cleanupOldArtifacts,
8
+ getArtifactsDir,
9
+ } from "../shared/artifacts.ts";
10
+ import { resolveCurrentSessionId } from "../shared/session-identity.ts";
11
+ import { cleanupOldChainDirs } from "../shared/settings.ts";
12
+ import { cleanupOldRunStorage } from "../shared/temp-root.ts";
13
+ import { AgentViewController } from "../tui/agent-view.ts";
14
+ import { createSubagentExecutor } from "../runs/foreground/subagent-executor.ts";
15
+ import { createAsyncJobTracker } from "../runs/background/async-job-tracker.ts";
16
+ import { rememberOwnedRun, restoreOwnedRunsAsync } from "../runs/shared/run-records.ts";
17
+ import { closeRunHistory, runHistoryIndex, startRunHistory } from "../runs/shared/history-index.ts";
18
+ import { registerParentUsage } from "../runs/shared/parent-usage.ts";
19
+ import { createCompletionDelivery } from "../runs/background/completion-delivery.ts";
20
+ import { isObsoleteIdleNotice } from "../runs/shared/subagent-control.ts";
21
+ import { registerSlashCommands } from "../slash/slash-commands.ts";
22
+ import { clearSlashSnapshots, restoreSlashFinalSnapshots } from "../slash/slash-live-state.ts";
23
+ import { isTuiContext } from "../shared/ui-mode.ts";
24
+ import { isRecord } from "../shared/unknown.ts";
25
+ import type { ReadonlyInput } from "../shared/types/inputs.ts";
26
+ import {
27
+ ASYNC_DIR,
28
+ RESULTS_DIR,
29
+ SUBAGENT_ASYNC_COMPLETE_EVENT,
30
+ SUBAGENT_ASYNC_STARTED_EVENT,
31
+ SUBAGENT_CONTROL_EVENT,
32
+ WIDGET_KEY,
33
+ type ExtensionConfig,
34
+ type SubagentExecutionResult,
35
+ type SubagentState,
36
+ } from "../shared/types.ts";
37
+ import {
38
+ handleSubagentControlNotice,
39
+ SUBAGENT_CONTROL_MESSAGE_TYPE,
40
+ type SubagentControlMessageDetails,
41
+ } from "./control-notices.ts";
42
+ import { parseControlNotice } from "./control-notice-schema.ts";
43
+ import { adaptFinalizedToolResult, registerToolResultAdapter } from "./tool-result.ts";
44
+ import { registerCompactSubagentTools } from "./compact-tools.ts";
45
+ import { registerParentSubagentTool, SUBAGENT_GUIDELINES } from "./primary-tool.ts";
46
+ import { registerMessageRenderers } from "./message-renderers.ts";
47
+ import { registerDelegationBridges } from "./delegation-bridges.ts";
48
+ import {
49
+ createRuntimeState,
50
+ ensureAccessibleDir,
51
+ expandTilde,
52
+ getSubagentSessionRoot,
53
+ } from "./runtime-storage.ts";
54
+ import {
55
+ cleanupStaleSubscriptions,
56
+ EVENT_UNSUBSCRIBES_KEY,
57
+ isStaleExtensionContextError,
58
+ removeSharedRuntimeValue,
59
+ RUNTIME_CLEANUP_KEY,
60
+ setSharedRuntimeValue,
61
+ visibleControlNotices,
62
+ } from "./runtime-reload.ts";
63
+
64
+ const TOOL_NAMES = ["subagent", "delegate", "agent_runs"];
65
+
66
+ /** Owns one extension runtime's session projection, timers, delivery, subscriptions and UI. */
67
+ export class ParentSubagentRuntime {
68
+ private readonly pi: ExtensionAPI;
69
+ private readonly config: ExtensionConfig;
70
+ private readonly state: SubagentState;
71
+ private readonly tracker: ReturnType<typeof createAsyncJobTracker>;
72
+ private readonly executor: ReturnType<typeof createSubagentExecutor>;
73
+ private readonly agentView: AgentViewController;
74
+ private readonly parentUsage: ReturnType<typeof registerParentUsage>;
75
+ private readonly completionDelivery: ReturnType<typeof createCompletionDelivery>;
76
+ private readonly adaptToolResult: ReturnType<typeof registerToolResultAdapter>;
77
+ private readonly bridges: ReturnType<typeof registerDelegationBridges>;
78
+ private readonly visibleNotices = visibleControlNotices();
79
+ private readonly pendingIdleNotices = new Map<string, SubagentControlMessageDetails>();
80
+ private readonly pendingReconciliations = new Set<Promise<void>>();
81
+ private readonly runtimeCleanup = (): void => this.cleanupRuntime();
82
+ private eventUnsubscribes: Array<() => void> = [];
83
+ private sessionReset: Promise<void> | undefined;
84
+ private reconcileTools: () => Promise<void> = () => Promise.resolve();
85
+
86
+ constructor(pi: ExtensionAPI, config: ExtensionConfig) {
87
+ this.pi = pi;
88
+ this.config = config;
89
+ this.state = createRuntimeState(pi);
90
+ this.tracker = createAsyncJobTracker(pi, this.state, ASYNC_DIR, {
91
+ render: () => {
92
+ this.refreshView();
93
+ },
94
+ });
95
+ this.executor = createSubagentExecutor({
96
+ pi,
97
+ state: this.state,
98
+ config,
99
+ asyncByDefault: config.asyncByDefault !== false,
100
+ tempArtifactsDir: getArtifactsDir(null),
101
+ getSubagentSessionRoot,
102
+ expandTilde,
103
+ discoverAgents,
104
+ ensureSessionState: (ctx) => this.ensureSession(ctx),
105
+ });
106
+ this.agentView = new AgentViewController(pi, this.state, (params, ctx) =>
107
+ this.executor.execute({ toolCallId: randomUUID(), params, ctx }),
108
+ );
109
+ this.parentUsage = registerParentUsage(pi, TOOL_NAMES);
110
+ this.completionDelivery = createCompletionDelivery(pi, this.state, this.parentUsage);
111
+ this.adaptToolResult = registerToolResultAdapter(pi, TOOL_NAMES);
112
+ this.bridges = registerDelegationBridges({
113
+ events: pi.events,
114
+ getContext: () => this.state.lastUiContext,
115
+ executor: this.executor,
116
+ });
117
+ setSharedRuntimeValue(RUNTIME_CLEANUP_KEY, this.runtimeCleanup);
118
+ }
119
+
120
+ register(): void {
121
+ registerMessageRenderers(this.pi);
122
+ this.registerTools();
123
+ registerSlashCommands(this.pi, this.state);
124
+ this.registerRunEvents();
125
+ this.registerSessionEvents();
126
+ }
127
+
128
+ private registerTools(): void {
129
+ const asyncByDefault = this.config.asyncByDefault !== false;
130
+ const adapt = (
131
+ result: ReadonlyInput<SubagentExecutionResult>,
132
+ ctx: ExtensionContext,
133
+ ): SubagentExecutionResult =>
134
+ adaptFinalizedToolResult(result, ctx, this.parentUsage, this.adaptToolResult);
135
+ this.reconcileTools = registerCompactSubagentTools(this.pi, {
136
+ executor: this.executor,
137
+ state: this.state,
138
+ adapt,
139
+ guidelines: SUBAGENT_GUIDELINES,
140
+ asyncByDefault,
141
+ getHistoryIndex: () => runHistoryIndex(this.state),
142
+ });
143
+ this.state.onRunsChanged = () => {
144
+ this.reconcileInBackground();
145
+ this.refreshView();
146
+ };
147
+ registerParentSubagentTool(this.pi, {
148
+ executor: this.executor,
149
+ adapt,
150
+ config: this.config,
151
+ asyncByDefault,
152
+ });
153
+ }
154
+
155
+ private refreshView(): void {
156
+ this.agentView.refresh().catch((error: unknown) => {
157
+ console.error("Could not refresh subagent view:", error);
158
+ });
159
+ }
160
+
161
+ private reconcileInBackground(): void {
162
+ const operation = this.reconcileTools();
163
+ this.pendingReconciliations.add(operation);
164
+ operation
165
+ .finally(() => {
166
+ this.pendingReconciliations.delete(operation);
167
+ })
168
+ .catch((error: unknown) => {
169
+ console.error("Could not reconcile subagent run controls:", error);
170
+ });
171
+ }
172
+
173
+ private deliverControlNotice(details: SubagentControlMessageDetails): void {
174
+ handleSubagentControlNotice({
175
+ pi: this.pi,
176
+ visibleControlNotices: this.visibleNotices,
177
+ details,
178
+ });
179
+ }
180
+
181
+ private controlEvent(data: unknown): void {
182
+ const details = parseControlNotice(data);
183
+ if (!details) {
184
+ return;
185
+ }
186
+ // Keep idle references out of Pi's active turn queue until its native settle boundary.
187
+ if (
188
+ details.source === "async" &&
189
+ details.event.reason === "idle" &&
190
+ !details.event.supervisorQuestion &&
191
+ this.state.lastUiContext &&
192
+ !this.state.lastUiContext.isIdle()
193
+ ) {
194
+ this.pendingIdleNotices.set(`${details.event.runId}:${details.event.index ?? ""}`, details);
195
+ return;
196
+ }
197
+ this.deliverControlNotice(details);
198
+ }
199
+
200
+ private flushIdleNotices(): void {
201
+ for (const details of this.pendingIdleNotices.values()) {
202
+ this.deliverControlNotice(details);
203
+ }
204
+ this.pendingIdleNotices.clear();
205
+ }
206
+
207
+ private startedEvent(data: unknown): void {
208
+ this.tracker.handleStarted(data);
209
+ if (!isRecord(data) || typeof data.id !== "string" || data.id.length === 0) {
210
+ return;
211
+ }
212
+ const run = this.state.ownedRuns?.get(data.id);
213
+ if (run) {
214
+ rememberOwnedRun(this.state, {
215
+ ...run,
216
+ source: "async",
217
+ asyncDir: typeof data.asyncDir === "string" ? data.asyncDir : undefined,
218
+ pid: typeof data.pid === "number" ? data.pid : undefined,
219
+ });
220
+ }
221
+ }
222
+
223
+ private subscribeEvents(): void {
224
+ this.eventUnsubscribes = [];
225
+ setSharedRuntimeValue(EVENT_UNSUBSCRIBES_KEY, this.eventUnsubscribes);
226
+ // Retain each successful subscription even if a later registration fails.
227
+ this.eventUnsubscribes.push(
228
+ this.pi.events.on(SUBAGENT_ASYNC_STARTED_EVENT, (data) => this.startedEvent(data)),
229
+ );
230
+ this.eventUnsubscribes.push(
231
+ this.pi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, this.tracker.handleComplete),
232
+ );
233
+ this.eventUnsubscribes.push(
234
+ this.pi.events.on(SUBAGENT_CONTROL_EVENT, (data) => this.controlEvent(data)),
235
+ );
236
+ }
237
+
238
+ private registerRunEvents(): void {
239
+ cleanupStaleSubscriptions();
240
+ this.subscribeEvents();
241
+ this.pi.on("turn_end", () => this.flushIdleNotices());
242
+ this.pi.on("agent_before_settle", () => this.flushIdleNotices());
243
+ this.pi.on("context", (event) => ({
244
+ messages: event.messages.filter((message) => {
245
+ if (message.role !== "custom" || message.customType !== SUBAGENT_CONTROL_MESSAGE_TYPE) {
246
+ return true;
247
+ }
248
+ const notice = parseControlNotice(message.details);
249
+ return !notice || !isObsoleteIdleNotice(notice);
250
+ }),
251
+ }));
252
+ this.pi.on("tool_result", (event, ctx) => {
253
+ if (!TOOL_NAMES.includes(event.toolName) || !isTuiContext(ctx)) {
254
+ return;
255
+ }
256
+ this.state.lastUiContext = ctx;
257
+ if (this.state.asyncJobs.size > 0) {
258
+ this.refreshView();
259
+ const ui: ExtensionContext["ui"] & { requestRender?: () => void } = ctx.ui;
260
+ ui.requestRender?.();
261
+ this.tracker.ensurePoller();
262
+ }
263
+ });
264
+ }
265
+
266
+ private registerSessionEvents(): void {
267
+ this.pi.on("session_start", async (_event, ctx) => {
268
+ if (this.eventUnsubscribes.length === 0) {
269
+ this.subscribeEvents();
270
+ }
271
+ await this.resetSession(ctx);
272
+ await this.reconcileTools();
273
+ });
274
+ this.pi.on("session_shutdown", () => this.shutdown());
275
+ }
276
+
277
+ private stopPoller(): void {
278
+ if (this.state.poller) {
279
+ clearInterval(this.state.poller);
280
+ }
281
+ this.state.poller = null;
282
+ }
283
+
284
+ private cleanupRuntime(): void {
285
+ this.agentView.dispose();
286
+ closeRunHistory(this.state).catch((error: unknown) => {
287
+ console.error("Could not close subagent history:", error);
288
+ });
289
+ this.completionDelivery.stop();
290
+ this.stopPoller();
291
+ }
292
+
293
+ private ensureSession(ctx: ExtensionContext): Promise<void> {
294
+ if (this.sessionReset) {
295
+ return this.sessionReset;
296
+ }
297
+ return this.state.currentSessionId !== resolveCurrentSessionId(ctx.sessionManager)
298
+ ? this.resetSession(ctx)
299
+ : Promise.resolve();
300
+ }
301
+
302
+ private resetSession(ctx: ExtensionContext): Promise<void> {
303
+ if (this.sessionReset) {
304
+ return this.sessionReset;
305
+ }
306
+ this.sessionReset = this.restoreSession(ctx).finally(() => {
307
+ this.sessionReset = undefined;
308
+ });
309
+ return this.sessionReset;
310
+ }
311
+
312
+ private async restoreSession(ctx: ExtensionContext): Promise<void> {
313
+ this.pendingIdleNotices.clear();
314
+ this.agentView.dispose();
315
+ this.stopPoller();
316
+ await this.completionDelivery.stopAndJoin();
317
+ closeRunHistory(this.state).catch((error: unknown) => {
318
+ console.error("Could not close subagent history:", error);
319
+ });
320
+ ensureAccessibleDir(RESULTS_DIR);
321
+ ensureAccessibleDir(ASYNC_DIR);
322
+ this.state.baseCwd = ctx.cwd;
323
+ this.state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
324
+ this.state.lastUiContext = ctx;
325
+ this.tracker.resetJobs();
326
+ const restoration = await restoreOwnedRunsAsync(this.state, ctx);
327
+ try {
328
+ this.tracker.restoreJobs(this.state.currentSessionId, ctx, restoration);
329
+ } catch (error) {
330
+ console.error("Failed to restore active async jobs:", error);
331
+ this.tracker.resetJobs(ctx);
332
+ }
333
+ startRunHistory(this.state, ctx);
334
+ this.reconcileInBackground();
335
+ this.agentView.start(ctx);
336
+ await this.cleanupArtifacts(ctx);
337
+ restoreSlashFinalSnapshots(ctx.sessionManager.getEntries());
338
+ this.completionDelivery.start();
339
+ }
340
+
341
+ private async cleanupArtifacts(ctx: ExtensionContext): Promise<void> {
342
+ await cleanupOldRunStorage();
343
+ await cleanupOldChainDirs();
344
+ await cleanupAllArtifactDirs(ARTIFACT_CLEANUP_DAYS);
345
+ try {
346
+ const file = ctx.sessionManager.getSessionFile();
347
+ if (file !== undefined && file.length > 0) {
348
+ await cleanupOldArtifacts(getArtifactsDir(file), ARTIFACT_CLEANUP_DAYS);
349
+ }
350
+ } catch {
351
+ // Artifact failures must not block native session lifecycle events.
352
+ }
353
+ }
354
+
355
+ private async shutdown(): Promise<void> {
356
+ // A reset can still publish history, view and delivery after its awaited restoration/cleanup.
357
+ // Join that owner before disposing the resources it may start.
358
+ try {
359
+ await this.sessionReset;
360
+ } finally {
361
+ await this.disposeSession();
362
+ }
363
+ }
364
+
365
+ private async disposeSession(): Promise<void> {
366
+ this.agentView.dispose();
367
+ this.stopPoller();
368
+ await this.completionDelivery.stopAndJoin({ preservePending: true });
369
+ await closeRunHistory(this.state);
370
+ await Promise.allSettled(this.pendingReconciliations);
371
+ for (const unsubscribe of this.eventUnsubscribes) {
372
+ try {
373
+ unsubscribe();
374
+ } catch {
375
+ /* Shutdown also owns already-disposed subscriptions. */
376
+ }
377
+ }
378
+ removeSharedRuntimeValue(EVENT_UNSUBSCRIBES_KEY, this.eventUnsubscribes);
379
+ this.eventUnsubscribes = [];
380
+ for (const timer of this.state.cleanupTimers.values()) {
381
+ clearTimeout(timer);
382
+ }
383
+ this.state.cleanupTimers.clear();
384
+ this.state.asyncJobs.clear();
385
+ clearSlashSnapshots();
386
+ this.bridges.slash.cancelAll();
387
+ this.bridges.slash.dispose();
388
+ this.bridges.template.cancelAll();
389
+ this.bridges.template.dispose();
390
+ removeSharedRuntimeValue(RUNTIME_CLEANUP_KEY, this.runtimeCleanup);
391
+ this.clearWidget();
392
+ }
393
+
394
+ private clearWidget(): void {
395
+ try {
396
+ if (this.state.lastUiContext && isTuiContext(this.state.lastUiContext)) {
397
+ this.state.lastUiContext.ui.setWidget(WIDGET_KEY, undefined);
398
+ }
399
+ } catch (error) {
400
+ if (!isStaleExtensionContextError(error)) {
401
+ throw error;
402
+ }
403
+ }
404
+ }
405
+ }
@@ -0,0 +1,130 @@
1
+ import type {
2
+ ExtensionAPI,
3
+ ExtensionContext,
4
+ Theme,
5
+ ToolDefinition,
6
+ } from "@earendil-works/pi-coding-agent";
7
+ import { Text } from "@earendil-works/pi-tui";
8
+ import type { Static } from "typebox";
9
+ import {
10
+ normalizeSubagentParamsLike,
11
+ resolveAsyncExecutionMode,
12
+ type createSubagentExecutor,
13
+ } from "../runs/foreground/subagent-executor.ts";
14
+ import { applyForceTopLevelAsyncOverride } from "../runs/background/top-level-async.ts";
15
+ import { renderSubagentResult } from "../tui/render.ts";
16
+ import type { ReadonlyDetails, SubagentExecutionResult, ExtensionConfig } from "../shared/types.ts";
17
+ import type { ReadonlyInput } from "../shared/types/inputs.ts";
18
+ import { SubagentParams } from "./schemas.ts";
19
+
20
+ export const SUBAGENT_GUIDELINES = [
21
+ "Use subagent for materially parallelizable scouting, review, or implementation work where another focused agent adds value.",
22
+ "Top-level subagent execution uses the stock async default unless configuration opts out. Launch a small bounded fanout of independent agents as separate single-agent runs so each completion wakes the parent, with at most one writer. Use one tasks call for non-review fanout when all child results are required together, when shared concurrency/task limits are needed, or when multiple writers require worktree isolation; the parent receives one aggregate completion. If no useful parent work remains, end the turn and wait instead of polling; completion wakes the parent. This also applies when an incomplete active Pi goal needs child evidence: yield, then continue the goal after automatic completion delivery. Set async:false only for explicitly chosen foreground execution.",
23
+ 'Before executing subagent runs, call subagent with { action: "list" } unless the requested executable agent or chain is already known from this conversation.',
24
+ "Keep the parent session responsible for final decisions, verification, and user-facing status; treat subagent output as evidence to review, not automatic truth.",
25
+ "Fresh-child handoffs must include relevant exact user instructions and settled decisions or readable source references alongside the bounded task; summaries do not replace original requirements.",
26
+ "Keep independent review as a separate parent-launched reviewer run after the worker; acceptance.review is unsupported.",
27
+ "For review-only tasks, omit acceptance unless the user explicitly requests a same-session acceptance contract; acceptance adds a finalization turn and is not independent review.",
28
+ "For live child guidance, answers, corrections, or blockers, inspect status and prefer action='nudge'; it sends a non-blocking steer that supplements the active task unless the message explicitly replaces it. Use the shown blocking intercom ask only when the parent must stay alive waiting for a reply.",
29
+ "Do not use subagent when a direct local tool call or small edit is cheaper than delegation.",
30
+ ] as const;
31
+
32
+ interface ParentToolOptions {
33
+ readonly executor: Readonly<ReturnType<typeof createSubagentExecutor>>;
34
+ readonly adapt: (
35
+ result: ReadonlyInput<SubagentExecutionResult>,
36
+ ctx: ExtensionContext,
37
+ ) => SubagentExecutionResult;
38
+ readonly config: ExtensionConfig;
39
+ readonly asyncByDefault: boolean;
40
+ }
41
+
42
+ function effectiveParallelTaskCount(
43
+ tasks: readonly { readonly count?: unknown }[] | undefined,
44
+ ): number {
45
+ return (
46
+ tasks?.reduce(
47
+ (total, task) =>
48
+ total +
49
+ (typeof task.count === "number" && Number.isInteger(task.count) && task.count >= 1
50
+ ? task.count
51
+ : 1),
52
+ 0,
53
+ ) ?? 0
54
+ );
55
+ }
56
+
57
+ type RenderArgs = ReadonlyInput<Partial<Static<typeof SubagentParams>>>;
58
+
59
+ function renderManagement(args: RenderArgs & { readonly action: string }, theme: Theme): Text {
60
+ const agent = args.agent ?? "";
61
+ const target = agent.length > 0 ? agent : (args.chainName ?? "");
62
+ const title = theme.fg("toolTitle", theme.bold("subagent "));
63
+ return new Text(
64
+ `${title}${args.action}${target.length > 0 ? ` ${theme.fg("accent", target)}` : ""}`,
65
+ 0,
66
+ 0,
67
+ );
68
+ }
69
+
70
+ function renderExecution(
71
+ args: RenderArgs,
72
+ theme: Theme,
73
+ options: Pick<ParentToolOptions, "config" | "asyncByDefault">,
74
+ ): Text {
75
+ const title = theme.fg("toolTitle", theme.bold("subagent "));
76
+ const renderedArgs = applyForceTopLevelAsyncOverride(
77
+ args,
78
+ 0,
79
+ options.config.forceTopLevelAsync === true,
80
+ );
81
+ const asyncLabel = resolveAsyncExecutionMode(renderedArgs, options.asyncByDefault).effectiveAsync
82
+ ? theme.fg("warning", " [async]")
83
+ : "";
84
+ if (args.chain !== undefined && args.chain.length > 0) {
85
+ return new Text(`${title}chain (${args.chain.length})${asyncLabel}`, 0, 0);
86
+ }
87
+ if (args.tasks !== undefined && args.tasks.length > 0) {
88
+ return new Text(
89
+ `${title}parallel (${effectiveParallelTaskCount(args.tasks)})${asyncLabel}`,
90
+ 0,
91
+ 0,
92
+ );
93
+ }
94
+ const agent = args.agent ?? "";
95
+ return new Text(
96
+ `${title}${theme.fg("accent", agent.length > 0 ? agent : "?")}${asyncLabel}`,
97
+ 0,
98
+ 0,
99
+ );
100
+ }
101
+
102
+ export function registerParentSubagentTool(pi: ExtensionAPI, options: ParentToolOptions): void {
103
+ const tool: ToolDefinition<typeof SubagentParams, ReadonlyDetails> = {
104
+ name: "subagent",
105
+ defaultActive: false,
106
+ label: "Subagent",
107
+ description: `Delegate bounded work to configured Pi subagents, chains, or parallel reviewers; manage agent definitions; inspect/control async runs. Indexed status lists support global agent/state/text filters and sort/cursors; history pages bounded native previews and search finds saved visible words or one quoted phrase. Browse freshness is not canonical proof. Use exactly one execution mode (agent, tasks, or chain) or one management/control action. Before execution, use { action: "list" } to inspect configured agents/chains. Only execute agents listed as executable/non-disabled. Parallel tasks support output?,reads?,progress?. maxOutput accepts { bytes?: number, lines?: number }. Prefer acceptance for goal/spec handoffs and status/resume/interrupt/extend/nudge for active runs. Exact status is concise by default; full:true includes the full task/configuration. Review notes are parent-only, not sent to children; put actionable instructions in resume/nudge. Resume/answer preserves saved settings unless agent selects a current profile (including model/thinking/fallbacks); a separate model override wins. Live guidance never mutates model or acceptance.`,
108
+ parameters: SubagentParams,
109
+ async execute(id, params, signal, onUpdate, ctx) {
110
+ return options.adapt(
111
+ await options.executor.execute({
112
+ toolCallId: id,
113
+ params: normalizeSubagentParamsLike(params),
114
+ signal,
115
+ onUpdate,
116
+ ctx,
117
+ }),
118
+ ctx,
119
+ );
120
+ },
121
+ renderCall: (args, theme) => {
122
+ if (args.action !== undefined && args.action.length > 0) {
123
+ return renderManagement({ ...args, action: args.action }, theme);
124
+ }
125
+ return renderExecution(args, theme, options);
126
+ },
127
+ renderResult: renderSubagentResult,
128
+ };
129
+ pi.registerTool(tool);
130
+ }
@@ -0,0 +1,35 @@
1
+ import type {
2
+ AgentProgress,
3
+ Details,
4
+ SingleResult,
5
+ SubagentExecutionResult,
6
+ } from "../shared/types.ts";
7
+ import type { ReadonlyInput } from "../shared/types/inputs.ts";
8
+
9
+ /** A new result owns its progress buffers; native messages and accounting stay shared snapshots. */
10
+ export function copyProgress(progress: ReadonlyInput<AgentProgress>): AgentProgress {
11
+ return {
12
+ ...progress,
13
+ recentTools: progress.recentTools.map((tool) => ({ ...tool })),
14
+ recentOutput: [...progress.recentOutput],
15
+ };
16
+ }
17
+
18
+ export function copyResult(result: ReadonlyInput<SingleResult>): SingleResult {
19
+ return { ...result, progress: result.progress ? copyProgress(result.progress) : undefined };
20
+ }
21
+
22
+ export function copyDetails(details: ReadonlyInput<Details>): Details {
23
+ return {
24
+ ...details,
25
+ results: details.results.map(copyResult),
26
+ progress: details.progress?.map(copyProgress),
27
+ };
28
+ }
29
+
30
+ /** Preserve the native result envelope while giving the receiving tool its own content array. */
31
+ export function copyExecutionResult(
32
+ result: ReadonlyInput<SubagentExecutionResult>,
33
+ ): SubagentExecutionResult {
34
+ return { ...result, content: [...result.content] };
35
+ }
@@ -0,0 +1,72 @@
1
+ import { isUnknownArray } from "../shared/unknown.ts";
2
+
3
+ export const RUNTIME_CLEANUP_KEY = "__piSubagentRuntimeCleanup";
4
+ export const EVENT_UNSUBSCRIBES_KEY = "__piSubagentEventUnsubscribes";
5
+ const VISIBLE_NOTICES_KEY = "__piSubagentVisibleControlNotices";
6
+
7
+ export function sharedRuntimeValue(key: string): unknown {
8
+ return Reflect.get(globalThis, key);
9
+ }
10
+
11
+ export function setSharedRuntimeValue(key: string, value: unknown): void {
12
+ if (!Reflect.set(globalThis, key, value)) {
13
+ throw new Error(`Could not register subagent runtime value '${key}'.`);
14
+ }
15
+ }
16
+
17
+ export function removeSharedRuntimeValue(key: string, current: unknown): void {
18
+ if (sharedRuntimeValue(key) === current) {
19
+ Reflect.deleteProperty(globalThis, key);
20
+ }
21
+ }
22
+
23
+ function isCallback(value: unknown): value is () => unknown {
24
+ return typeof value === "function";
25
+ }
26
+
27
+ function cleanupCallback(value: unknown): void {
28
+ if (!isCallback(value)) {
29
+ return;
30
+ }
31
+ try {
32
+ const pending = value();
33
+ if (pending instanceof Promise) {
34
+ pending.catch((error: unknown) => {
35
+ console.error("Could not clean stale subagent runtime:", error);
36
+ });
37
+ }
38
+ } catch {
39
+ // Stale cleanup must not prevent the replacement extension from registering.
40
+ }
41
+ }
42
+
43
+ export function cleanupStaleRuntime(key = RUNTIME_CLEANUP_KEY): void {
44
+ cleanupCallback(sharedRuntimeValue(key));
45
+ }
46
+
47
+ export function isStaleExtensionContextError(error: unknown): boolean {
48
+ return error instanceof Error && error.message.includes("Extension context no longer active");
49
+ }
50
+
51
+ export function cleanupStaleSubscriptions(): void {
52
+ const previous = sharedRuntimeValue(EVENT_UNSUBSCRIBES_KEY);
53
+ if (isUnknownArray(previous)) {
54
+ for (const unsubscribe of previous) {
55
+ cleanupCallback(unsubscribe);
56
+ }
57
+ }
58
+ }
59
+
60
+ function isStringSet(value: unknown): value is Set<string> {
61
+ return value instanceof Set && [...value].every((entry: unknown) => typeof entry === "string");
62
+ }
63
+
64
+ export function visibleControlNotices(): Set<string> {
65
+ const previous = sharedRuntimeValue(VISIBLE_NOTICES_KEY);
66
+ if (isStringSet(previous)) {
67
+ return previous;
68
+ }
69
+ const notices = new Set<string>();
70
+ setSharedRuntimeValue(VISIBLE_NOTICES_KEY, notices);
71
+ return notices;
72
+ }
@@ -0,0 +1,49 @@
1
+ import * as fs from "node:fs";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
5
+ import { OWNED_RUN_ENTRY } from "../runs/shared/run-records.ts";
6
+ import { ensureSafeTempPath } from "../shared/temp-root.ts";
7
+ import type { SubagentState } from "../shared/types.ts";
8
+
9
+ export function getSubagentSessionRoot(parentSessionFile: string | null): string {
10
+ if (parentSessionFile !== null && parentSessionFile.length > 0) {
11
+ return path.join(path.dirname(parentSessionFile), path.basename(parentSessionFile, ".jsonl"));
12
+ }
13
+ return fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagent-session-"));
14
+ }
15
+
16
+ export function expandTilde(value: string): string {
17
+ return value.startsWith("~/") ? path.join(os.homedir(), value.slice(2)) : value;
18
+ }
19
+
20
+ export function ensureAccessibleDir(dir: string): void {
21
+ ensureSafeTempPath(dir);
22
+ fs.mkdirSync(dir, { recursive: true });
23
+ fs.accessSync(dir, fs.constants.R_OK | fs.constants.W_OK);
24
+ }
25
+
26
+ export function createRuntimeState(pi: ExtensionAPI): SubagentState {
27
+ return {
28
+ baseCwd: "",
29
+ currentSessionId: null,
30
+ asyncJobs: new Map(),
31
+ foregroundRuns: new Map(),
32
+ ownedRuns: new Map(),
33
+ persistOwnedRun: (run) => {
34
+ pi.appendEntry(OWNED_RUN_ENTRY, run);
35
+ },
36
+ cleanupTimers: new Map(),
37
+ lastUiContext: null,
38
+ poller: null,
39
+ completionSeen: new Map(),
40
+ watcher: null,
41
+ watcherRestartTimer: null,
42
+ resultFileCoalescer: {
43
+ schedule: () => false,
44
+ clear: () => {
45
+ /* The async tracker installs a real coalescer when its watcher starts. */
46
+ },
47
+ },
48
+ };
49
+ }