@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
@@ -1,467 +1,401 @@
1
1
  import * as path from "node:path";
2
- import { type AgentConfig } from "../../agents/agents.ts";
3
- import { loadRunsForAgent } from "../shared/run-history.ts";
4
- import {
5
- getStepAgents,
6
- isParallelStep,
7
- isDynamicParallelStep,
8
- type ChainStep,
9
- type ResolvedStepBehavior,
10
- type SequentialStep,
11
- } from "../../shared/settings.ts";
2
+ import type { ChainStep, ResolvedStepBehavior } from "../../shared/types/workflow.ts";
3
+ import { errorMessage } from "../../shared/unknown.ts";
4
+ import type { AgentConfig } from "../../shared/types/config.ts";
5
+ import { getStepAgents, isParallelStep, isDynamicParallelStep } from "../../shared/settings.ts";
12
6
  import { findDuplicateOutputPath, resolveSingleOutputPath } from "../shared/single-output.ts";
13
7
  import { resolveChildCwd } from "../../shared/utils.ts";
14
8
  import { validateAcceptanceInput } from "../shared/acceptance.ts";
15
- import { findWorktreeTaskCwdConflict, formatWorktreeTaskCwdConflict, type WorktreeSetup } from "../shared/worktree.ts";
16
- import { type Details, type SubagentExecutionResult } from "../../shared/types.ts";
17
- import { type SubagentParamsLike, type TaskParam } from "./subagent-params.ts";
18
-
19
- function validationErrorResult(mode: Details["mode"], text: string): SubagentExecutionResult {
20
- return { content: [{ type: "text", text }], isError: true, details: { mode, results: [] } };
9
+ import {
10
+ findWorktreeTaskCwdConflict,
11
+ formatWorktreeTaskCwdConflict,
12
+ type WorktreeSetup,
13
+ } from "../shared/worktree.ts";
14
+ import type { Details, SubagentExecutionResult, ReadonlyInput } from "../../shared/types.ts";
15
+ import type { SubagentParamsLike, TaskParam } from "./subagent-params.ts";
16
+ import { resolveForegroundTimeoutMs } from "./execution-timeout.ts";
17
+ export { resolveForegroundTimeoutMs, normalizeRoleForegroundTimeout } from "./execution-timeout.ts";
18
+ export { normalizeRepeatedParallelCounts } from "./invocation-expansion.ts";
19
+
20
+ function validationError(mode: Details["mode"], text: string): SubagentExecutionResult {
21
+ return { content: [{ type: "text", text }], isError: true, details: { mode, results: [] } };
21
22
  }
22
-
23
- const MIN_REVIEWER_FOREGROUND_TIMEOUT_MS = 900_000;
24
- const LONG_RUNNING_HISTORY_SAMPLE_SIZE = 20;
25
- const LONG_RUNNING_HISTORY_MIN_SAMPLES = 3;
26
- const LONG_RUNNING_HISTORY_HEADROOM = 1.25;
27
- const LONG_RUNNING_HISTORY_MAX_TIMEOUT_MS = 1_800_000;
28
-
29
- type TimeoutRole = "reviewer" | "planner" | "researcher";
30
-
31
- function resolveTimeoutRole(agentName: string | undefined): TimeoutRole | undefined {
32
- if (typeof agentName !== "string") return undefined;
33
- if (/(^|[._-])reviewer($|[._-])/i.test(agentName)) return "reviewer";
34
- if (/(^|[._-])planner($|[._-])/i.test(agentName)) return "planner";
35
- if (/(^|[._-])researcher($|[._-])/i.test(agentName)) return "researcher";
36
- return undefined;
23
+ function acceptanceForStep(step: ChainStep, index: number): string | undefined {
24
+ const prefix = `chain[${index}]`;
25
+ if (isParallelStep(step)) {
26
+ if (Object.hasOwn(step, "acceptance")) {
27
+ return `${prefix}.acceptance is not supported on static parallel groups; set acceptance on each parallel task.`;
28
+ }
29
+ for (const [taskIndex, task] of step.parallel.entries()) {
30
+ const errors = validateAcceptanceInput(
31
+ task.acceptance,
32
+ `${prefix}.parallel[${taskIndex}].acceptance`,
33
+ );
34
+ if (errors.length > 0) {
35
+ return errors.join(" ");
36
+ }
37
+ }
38
+ return;
39
+ }
40
+ if (isDynamicParallelStep(step)) {
41
+ if (Object.hasOwn(step, "acceptance")) {
42
+ return `${prefix}.acceptance is not supported on dynamic fanout groups; set acceptance on ${prefix}.parallel.acceptance for each materialized child.`;
43
+ }
44
+ const errors = validateAcceptanceInput(
45
+ step.parallel.acceptance,
46
+ `${prefix}.parallel.acceptance`,
47
+ );
48
+ return errors.length > 0 ? errors.join(" ") : undefined;
49
+ }
50
+ const errors = validateAcceptanceInput(step.acceptance, `${prefix}.acceptance`);
51
+ return errors.length > 0 ? errors.join(" ") : undefined;
37
52
  }
38
-
39
- function historicalForegroundTimeoutFloor(agentName: string): number | undefined {
40
- const durations = loadRunsForAgent(agentName)
41
- .filter((entry) => entry.status === "ok" && Number.isFinite(entry.duration) && entry.duration > 0)
42
- .slice(0, LONG_RUNNING_HISTORY_SAMPLE_SIZE)
43
- .map((entry) => entry.duration)
44
- .sort((left, right) => left - right);
45
- if (durations.length < LONG_RUNNING_HISTORY_MIN_SAMPLES) return undefined;
46
- const p75 = durations[Math.ceil(durations.length * 0.75) - 1];
47
- return p75 ? Math.min(LONG_RUNNING_HISTORY_MAX_TIMEOUT_MS, Math.ceil(p75 * LONG_RUNNING_HISTORY_HEADROOM)) : undefined;
53
+ function validateAcceptance(params: SubagentParamsLike): SubagentExecutionResult | undefined {
54
+ const errors = validateAcceptanceInput(params.acceptance);
55
+ if (errors.length > 0) {
56
+ return validationError("single", errors.join(" "));
57
+ }
58
+ for (const [index, task] of (params.tasks ?? []).entries()) {
59
+ const taskErrors = validateAcceptanceInput(task.acceptance, `tasks[${index}].acceptance`);
60
+ if (taskErrors.length > 0) {
61
+ return validationError("parallel", taskErrors.join(" "));
62
+ }
63
+ }
64
+ for (const [index, step] of (params.chain ?? []).entries()) {
65
+ const error = acceptanceForStep(step, index);
66
+ if (error !== undefined) {
67
+ return validationError("chain", error);
68
+ }
69
+ }
70
+ return;
48
71
  }
49
-
50
- function roleForegroundTimeoutFloor(agentName: string): number | undefined {
51
- const role = resolveTimeoutRole(agentName);
52
- if (!role) return undefined;
53
- const historical = historicalForegroundTimeoutFloor(agentName);
54
- if (role === "reviewer") return Math.max(MIN_REVIEWER_FOREGROUND_TIMEOUT_MS, historical ?? 0);
55
- return historical;
56
- }
57
-
58
- export function resolveForegroundTimeoutMs(params: SubagentParamsLike): { timeoutMs?: number; error?: string } {
59
- const rawTimeout = (params as { timeoutMs?: unknown }).timeoutMs;
60
- const rawMaxRuntime = (params as { maxRuntimeMs?: unknown }).maxRuntimeMs;
61
- for (const [name, value] of [["timeoutMs", rawTimeout], ["maxRuntimeMs", rawMaxRuntime]] as const) {
62
- if (value !== undefined && (typeof value !== "number" || !Number.isInteger(value) || value < 1)) {
63
- return { error: `${name} must be a positive integer.` };
64
- }
65
- }
66
- if (rawTimeout !== undefined && rawMaxRuntime !== undefined && rawTimeout !== rawMaxRuntime) {
67
- return { error: "timeoutMs and maxRuntimeMs are aliases; provide only one or use identical values." };
68
- }
69
- const timeoutMs = typeof rawTimeout === "number" ? rawTimeout : typeof rawMaxRuntime === "number" ? rawMaxRuntime : undefined;
70
- return timeoutMs === undefined ? {} : { timeoutMs };
72
+ interface InvocationModes {
73
+ readonly hasChain: boolean;
74
+ readonly hasTasks: boolean;
75
+ readonly hasSingle: boolean;
76
+ readonly allowClarifyTaskPrompt: boolean;
71
77
  }
72
-
73
- function timeoutRoleAgentsInRequest(params: SubagentParamsLike): string[] {
74
- const names = new Set<string>();
75
- if ((params.chain?.length ?? 0) > 0) {
76
- for (const step of params.chain ?? []) {
77
- for (const agent of getStepAgents(step as ChainStep)) {
78
- if (resolveTimeoutRole(agent)) names.add(agent);
79
- }
80
- }
81
- return [...names];
82
- }
83
- if ((params.tasks?.length ?? 0) > 0) {
84
- for (const task of params.tasks ?? []) {
85
- if (resolveTimeoutRole(task.agent)) names.add(task.agent);
86
- }
87
- return [...names];
88
- }
89
- if (resolveTimeoutRole(params.agent)) names.add(params.agent!);
90
- return [...names];
78
+ function validateMode(
79
+ params: SubagentParamsLike,
80
+ agents: readonly AgentConfig[],
81
+ modes: InvocationModes,
82
+ ): SubagentExecutionResult | undefined {
83
+ if (params.tasks?.length === 0) {
84
+ return validationError("parallel", "tasks must contain at least one task.");
85
+ }
86
+ if (params.worktree !== undefined && !modes.hasTasks) {
87
+ return validationError(
88
+ getRequestedModeLabel(params),
89
+ "Top-level worktree is supported only with tasks parallel mode.",
90
+ );
91
+ }
92
+ if (modes.hasSingle && params.task !== undefined && invalidTask(params.task)) {
93
+ return validationError("single", "task must be a non-empty string when provided.");
94
+ }
95
+ if (Number(modes.hasChain) + Number(modes.hasTasks) + Number(modes.hasSingle) !== 1) {
96
+ const names = agents.map((agent) => agent.name).join(", ");
97
+ return validationError(
98
+ "single",
99
+ `Provide exactly one mode. Agents: ${names.length > 0 ? names : "none"}`,
100
+ );
101
+ }
102
+ return;
91
103
  }
92
-
93
- export function normalizeRoleForegroundTimeout(params: SubagentParamsLike, timeoutMs: number | undefined): number | undefined {
94
- if (timeoutMs === undefined) return timeoutMs;
95
- let normalized = timeoutMs;
96
- for (const agentName of timeoutRoleAgentsInRequest(params)) {
97
- const floor = roleForegroundTimeoutFloor(agentName);
98
- if (floor !== undefined && normalized < floor) normalized = floor;
99
- }
100
- return normalized;
104
+ export function validateExecutionInput(
105
+ params: SubagentParamsLike,
106
+ agents: readonly AgentConfig[],
107
+ modes: InvocationModes,
108
+ ): SubagentExecutionResult | null {
109
+ const error = validateAcceptance(params) ?? validateMode(params, agents, modes);
110
+ if (error) {
111
+ return error;
112
+ }
113
+ const timeout = resolveForegroundTimeoutMs(params);
114
+ if (timeout.error !== undefined) {
115
+ return validationError(getRequestedModeLabel(params), timeout.error);
116
+ }
117
+ const agentError = modes.hasSingle ? validateSingleAgent(params.agent, agents) : undefined;
118
+ if (agentError) {
119
+ return agentError;
120
+ }
121
+ if (modes.hasTasks && params.tasks) {
122
+ return validateTasks(params.tasks, agents);
123
+ }
124
+ if (modes.hasChain && params.chain) {
125
+ return validateChain(params, agents, modes.allowClarifyTaskPrompt);
126
+ }
127
+ return null;
101
128
  }
102
-
103
- function validateAcceptanceForExecution(params: SubagentParamsLike): SubagentExecutionResult | null {
104
- const topLevelErrors = validateAcceptanceInput(params.acceptance);
105
- if (topLevelErrors.length > 0) return validationErrorResult("single", topLevelErrors.join(" "));
106
- for (const [index, task] of (params.tasks ?? []).entries()) {
107
- const errors = validateAcceptanceInput(task.acceptance, `tasks[${index}].acceptance`);
108
- if (errors.length > 0) return validationErrorResult("parallel", errors.join(" "));
109
- }
110
- for (const [stepIndex, step] of (params.chain ?? []).entries()) {
111
- if (isParallelStep(step)) {
112
- if (Object.hasOwn(step, "acceptance")) return validationErrorResult("chain", `chain[${stepIndex}].acceptance is not supported on static parallel groups; set acceptance on each parallel task.`);
113
- for (const [taskIndex, task] of step.parallel.entries()) {
114
- const errors = validateAcceptanceInput(task.acceptance, `chain[${stepIndex}].parallel[${taskIndex}].acceptance`);
115
- if (errors.length > 0) return validationErrorResult("chain", errors.join(" "));
116
- }
117
- } else if (isDynamicParallelStep(step)) {
118
- if (Object.hasOwn(step, "acceptance")) return validationErrorResult("chain", `chain[${stepIndex}].acceptance is not supported on dynamic fanout groups; set acceptance on chain[${stepIndex}].parallel.acceptance for each materialized child.`);
119
- const errors = validateAcceptanceInput(step.parallel.acceptance, `chain[${stepIndex}].parallel.acceptance`);
120
- if (errors.length > 0) return validationErrorResult("chain", errors.join(" "));
121
- } else {
122
- const stepErrors = validateAcceptanceInput(step.acceptance, `chain[${stepIndex}].acceptance`);
123
- if (stepErrors.length > 0) return validationErrorResult("chain", stepErrors.join(" "));
124
- }
125
- }
126
- return null;
129
+ function validateSingleAgent(
130
+ name: string | undefined,
131
+ agents: readonly AgentConfig[],
132
+ ): SubagentExecutionResult | undefined {
133
+ if (name !== undefined && name.length > 0 && !agents.some((agent) => agent.name === name)) {
134
+ return validationError("single", `Unknown agent: ${name}`);
135
+ }
136
+ return;
127
137
  }
128
-
129
- const SEQUENTIAL_CHAIN_STEP_KEYS = new Set(["agent", "task", "phase", "label", "as", "outputSchema", "cwd", "output", "outputMode", "reads", "progress", "skill", "model", "acceptance"]);
130
- const STATIC_PARALLEL_STEP_KEYS = new Set(["parallel", "concurrency", "failFast", "worktree", "cwd"]);
131
- const DYNAMIC_PARALLEL_STEP_KEYS = new Set(["expand", "parallel", "collect", "concurrency", "failFast", "phase", "label"]);
132
-
133
- function unsupportedChainStepFields(step: object, allowed: Set<string>): string[] {
134
- return Object.keys(step).filter((key) => !allowed.has(key));
138
+ function invalidTask(task: unknown): boolean {
139
+ return typeof task !== "string" || task.trim().length === 0;
135
140
  }
136
-
137
- export function validateExecutionInput(
138
- params: SubagentParamsLike,
139
- agents: AgentConfig[],
140
- hasChain: boolean,
141
- hasTasks: boolean,
142
- hasSingle: boolean,
143
- allowClarifyTaskPrompt: boolean,
141
+ function validateTasks(
142
+ tasks: readonly TaskParam[],
143
+ agents: readonly AgentConfig[],
144
144
  ): SubagentExecutionResult | null {
145
- const acceptanceError = validateAcceptanceForExecution(params);
146
- if (acceptanceError) return acceptanceError;
147
-
148
- if (params.tasks && params.tasks.length === 0) return validationErrorResult("parallel", "tasks must contain at least one task.");
149
- if (params.worktree !== undefined && !hasTasks) return validationErrorResult(getRequestedModeLabel(params), "Top-level worktree is supported only with tasks parallel mode.");
150
- if (hasSingle && params.task !== undefined && (typeof params.task !== "string" || params.task.trim().length === 0)) {
151
- return validationErrorResult("single", "task must be a non-empty string when provided.");
152
- }
153
-
154
- if (Number(hasChain) + Number(hasTasks) + Number(hasSingle) !== 1) {
155
- return {
156
- content: [
157
- {
158
- type: "text",
159
- text: `Provide exactly one mode. Agents: ${agents.map((a) => a.name).join(", ") || "none"}`,
160
- },
161
- ],
162
- isError: true,
163
- details: { mode: "single" as const, results: [] },
164
- };
165
- }
166
-
167
- const timeoutResolution = resolveForegroundTimeoutMs(params);
168
- if (timeoutResolution.error) return validationErrorResult(getRequestedModeLabel(params), timeoutResolution.error);
169
-
170
- if (hasSingle && params.agent && !agents.find((agent) => agent.name === params.agent)) {
171
- return {
172
- content: [{ type: "text", text: `Unknown agent: ${params.agent}` }],
173
- isError: true,
174
- details: { mode: "single" as const, results: [] },
175
- };
176
- }
177
-
178
- if (hasTasks && params.tasks) {
179
- for (let i = 0; i < params.tasks.length; i++) {
180
- const task = params.tasks[i]!;
181
- if (typeof task.task !== "string" || task.task.trim().length === 0) return validationErrorResult("parallel", `tasks[${i}].task must be a non-empty string.`);
182
- if (!agents.find((agent) => agent.name === task.agent)) {
183
- return {
184
- content: [{ type: "text", text: `Unknown agent: ${task.agent} (task ${i + 1})` }],
185
- isError: true,
186
- details: { mode: "parallel" as const, results: [] },
187
- };
188
- }
189
- }
190
- }
191
-
192
- if (hasChain && params.chain) {
193
- if (params.chain.length === 0) {
194
- return {
195
- content: [{ type: "text", text: "Chain must have at least one step" }],
196
- isError: true,
197
- details: { mode: "chain" as const, results: [] },
198
- };
199
- }
200
- const firstStep = params.chain[0] as ChainStep;
201
- if (isParallelStep(firstStep)) {
202
- const missingTaskIndex = firstStep.parallel.findIndex((t) => !t.task);
203
- if (missingTaskIndex !== -1) {
204
- return {
205
- content: [{ type: "text", text: `First parallel step: task ${missingTaskIndex + 1} must have a task (no previous output to reference)` }],
206
- isError: true,
207
- details: { mode: "chain" as const, results: [] },
208
- };
209
- }
210
- } else if (isDynamicParallelStep(firstStep)) {
211
- return {
212
- content: [{ type: "text", text: "First step in chain cannot be dynamic fanout; expand.from requires a prior structured named output" }],
213
- isError: true,
214
- details: { mode: "chain" as const, results: [] },
215
- };
216
- } else if (!(firstStep as SequentialStep).task && !params.task && !allowClarifyTaskPrompt) {
217
- return {
218
- content: [{ type: "text", text: "First step in chain must have a task" }],
219
- isError: true,
220
- details: { mode: "chain" as const, results: [] },
221
- };
222
- }
223
- for (let i = 0; i < params.chain.length; i++) {
224
- const step = params.chain[i] as ChainStep;
225
- const allowedKeys = isParallelStep(step) ? STATIC_PARALLEL_STEP_KEYS : isDynamicParallelStep(step) ? DYNAMIC_PARALLEL_STEP_KEYS : SEQUENTIAL_CHAIN_STEP_KEYS;
226
- const unsupportedFields = unsupportedChainStepFields(step, allowedKeys);
227
- if (unsupportedFields.length > 0) return validationErrorResult("chain", `chain[${i}] fields are not supported for this step mode: ${unsupportedFields.join(", ")}.`);
228
- if (Object.hasOwn(step, "task") && (typeof (step as { task?: unknown }).task !== "string" || !(step as { task: string }).task.trim())) {
229
- return validationErrorResult("chain", `chain[${i}].task must be a non-empty string when provided.`);
230
- }
231
- if (isParallelStep(step)) {
232
- const emptyTaskIndex = step.parallel.findIndex((task) => Object.hasOwn(task, "task") && (typeof task.task !== "string" || !task.task.trim()));
233
- if (emptyTaskIndex >= 0) return validationErrorResult("chain", `chain[${i}].parallel[${emptyTaskIndex}].task must be a non-empty string when provided.`);
234
- } else if (isDynamicParallelStep(step) && Object.hasOwn(step.parallel, "task") && (typeof step.parallel.task !== "string" || !step.parallel.task.trim())) {
235
- return validationErrorResult("chain", `chain[${i}].parallel.task must be a non-empty string when provided.`);
236
- }
237
- const stepAgents = getStepAgents(step);
238
- for (const agentName of stepAgents) {
239
- if (!agents.find((a) => a.name === agentName)) {
240
- return {
241
- content: [{ type: "text", text: `Unknown agent: ${agentName} (step ${i + 1})` }],
242
- isError: true,
243
- details: { mode: "chain" as const, results: [] },
244
- };
245
- }
246
- }
247
- if (isParallelStep(step) && step.parallel.length === 0) {
248
- return {
249
- content: [{ type: "text", text: `Parallel step ${i + 1} must have at least one task` }],
250
- isError: true,
251
- details: { mode: "chain" as const, results: [] },
252
- };
253
- }
254
- }
255
- }
256
-
257
- return null;
145
+ for (const [index, task] of tasks.entries()) {
146
+ if (invalidTask(task.task)) {
147
+ return validationError("parallel", `tasks[${index}].task must be a non-empty string.`);
148
+ }
149
+ if (!agents.some((agent) => agent.name === task.agent)) {
150
+ return validationError("parallel", `Unknown agent: ${task.agent} (task ${index + 1})`);
151
+ }
152
+ }
153
+ return null;
258
154
  }
259
-
260
- function getRequestedModeLabel(params: SubagentParamsLike): Details["mode"] {
261
- if ((params.chain?.length ?? 0) > 0) return "chain";
262
- if ((params.tasks?.length ?? 0) > 0) return "parallel";
263
- if (params.agent) return "single";
264
- return "single";
155
+ function firstStepError(
156
+ step: ChainStep,
157
+ params: SubagentParamsLike,
158
+ clarify: boolean,
159
+ ): string | undefined {
160
+ if (isParallelStep(step)) {
161
+ const missing = step.parallel.findIndex(
162
+ (task) => task.task === undefined || task.task.length === 0,
163
+ );
164
+ return missing < 0
165
+ ? undefined
166
+ : `First parallel step: task ${missing + 1} must have a task (no previous output to reference)`;
167
+ }
168
+ if (isDynamicParallelStep(step)) {
169
+ return "First step in chain cannot be dynamic fanout; expand.from requires a prior structured named output";
170
+ }
171
+ if (
172
+ (step.task === undefined || step.task.length === 0) &&
173
+ (params.task === undefined || params.task.length === 0) &&
174
+ !clarify
175
+ ) {
176
+ return "First step in chain must have a task";
177
+ }
178
+ return;
265
179
  }
266
-
267
-
268
- export function buildRequestedModeError(params: SubagentParamsLike, message: string): SubagentExecutionResult {
269
- return withForkContext(
270
- {
271
- content: [{ type: "text", text: message }],
272
- isError: true,
273
- details: { mode: getRequestedModeLabel(params), results: [] },
274
- },
275
- params.context,
276
- );
180
+ const SEQUENTIAL_KEYS = new Set([
181
+ "agent",
182
+ "task",
183
+ "phase",
184
+ "label",
185
+ "as",
186
+ "outputSchema",
187
+ "cwd",
188
+ "output",
189
+ "outputMode",
190
+ "reads",
191
+ "progress",
192
+ "skill",
193
+ "model",
194
+ "acceptance",
195
+ ]);
196
+ const PARALLEL_KEYS = new Set(["parallel", "concurrency", "failFast", "worktree", "cwd"]);
197
+ const DYNAMIC_KEYS = new Set([
198
+ "expand",
199
+ "parallel",
200
+ "collect",
201
+ "concurrency",
202
+ "failFast",
203
+ "phase",
204
+ "label",
205
+ ]);
206
+ function allowedStepKeys(step: ChainStep): ReadonlySet<string> {
207
+ if (isParallelStep(step)) {
208
+ return PARALLEL_KEYS;
209
+ }
210
+ return isDynamicParallelStep(step) ? DYNAMIC_KEYS : SEQUENTIAL_KEYS;
277
211
  }
278
-
279
- function expandTopLevelTaskCounts(tasks: TaskParam[]): { tasks?: TaskParam[]; error?: string } {
280
- const expanded: TaskParam[] = [];
281
- for (let taskIndex = 0; taskIndex < tasks.length; taskIndex++) {
282
- const task = tasks[taskIndex]!;
283
- const rawCount = (task as TaskParam & { count?: unknown }).count;
284
- if (rawCount !== undefined && (typeof rawCount !== "number" || !Number.isInteger(rawCount) || rawCount < 1)) {
285
- return { error: `tasks[${taskIndex}].count must be an integer >= 1` };
286
- }
287
- const { count, ...concreteTask } = task;
288
- for (let repeat = 0; repeat < (rawCount ?? 1); repeat++) {
289
- expanded.push({ ...concreteTask });
290
- }
291
- }
292
- return { tasks: expanded };
212
+ function stepTaskError(step: ChainStep, index: number): string | undefined {
213
+ if ("task" in step && Object.hasOwn(step, "task") && invalidTask(step.task)) {
214
+ return `chain[${index}].task must be a non-empty string when provided.`;
215
+ }
216
+ if (isParallelStep(step)) {
217
+ const empty = step.parallel.findIndex(
218
+ (task) => Object.hasOwn(task, "task") && invalidTask(task.task),
219
+ );
220
+ if (empty >= 0) {
221
+ return `chain[${index}].parallel[${empty}].task must be a non-empty string when provided.`;
222
+ }
223
+ }
224
+ if (
225
+ isDynamicParallelStep(step) &&
226
+ Object.hasOwn(step.parallel, "task") &&
227
+ invalidTask(step.parallel.task)
228
+ ) {
229
+ return `chain[${index}].parallel.task must be a non-empty string when provided.`;
230
+ }
231
+ return;
293
232
  }
294
-
295
- function expandChainParallelCounts(chain: ChainStep[]): { chain?: ChainStep[]; error?: string } {
296
- const expandedChain: ChainStep[] = [];
297
- for (let stepIndex = 0; stepIndex < chain.length; stepIndex++) {
298
- const step = chain[stepIndex]!;
299
- if (!isParallelStep(step)) {
300
- expandedChain.push(step);
301
- continue;
302
- }
303
- const expandedParallel = [];
304
- for (let taskIndex = 0; taskIndex < step.parallel.length; taskIndex++) {
305
- const task = step.parallel[taskIndex]!;
306
- const rawCount = (task as typeof task & { count?: unknown }).count;
307
- if (rawCount !== undefined && (typeof rawCount !== "number" || !Number.isInteger(rawCount) || rawCount < 1)) {
308
- return { error: `chain[${stepIndex}].parallel[${taskIndex}].count must be an integer >= 1` };
309
- }
310
- const { count, ...concreteTask } = task;
311
- for (let repeat = 0; repeat < (rawCount ?? 1); repeat++) {
312
- expandedParallel.push({ ...concreteTask });
313
- }
314
- }
315
- expandedChain.push({ ...step, parallel: expandedParallel });
316
- }
317
- return { chain: expandedChain };
233
+ function validateChain(
234
+ params: SubagentParamsLike,
235
+ agents: readonly AgentConfig[],
236
+ clarify: boolean,
237
+ ): SubagentExecutionResult | null {
238
+ const chain = params.chain ?? [];
239
+ const first = chain.at(0);
240
+ if (!first) {
241
+ return validationError("chain", "Chain must have at least one step");
242
+ }
243
+ const firstError = firstStepError(first, params, clarify);
244
+ if (firstError !== undefined) {
245
+ return validationError("chain", firstError);
246
+ }
247
+ for (const [index, step] of chain.entries()) {
248
+ const allowed = allowedStepKeys(step);
249
+ const unsupported = Object.keys(step).filter((key) => !allowed.has(key));
250
+ if (unsupported.length > 0) {
251
+ return validationError(
252
+ "chain",
253
+ `chain[${index}] fields are not supported for this step mode: ${unsupported.join(", ")}.`,
254
+ );
255
+ }
256
+ const taskError = stepTaskError(step, index);
257
+ if (taskError !== undefined) {
258
+ return validationError("chain", taskError);
259
+ }
260
+ const missing = getStepAgents(step).find(
261
+ (name) => !agents.some((agent) => agent.name === name),
262
+ );
263
+ if (missing !== undefined) {
264
+ return validationError("chain", `Unknown agent: ${missing} (step ${index + 1})`);
265
+ }
266
+ if (isParallelStep(step) && step.parallel.length === 0) {
267
+ return validationError("chain", `Parallel step ${index + 1} must have at least one task`);
268
+ }
269
+ }
270
+ return null;
318
271
  }
319
-
320
- export function normalizeRepeatedParallelCounts(params: SubagentParamsLike): { params?: SubagentParamsLike; error?: SubagentExecutionResult } {
321
- if (params.tasks) {
322
- const expandedTasks = expandTopLevelTaskCounts(params.tasks);
323
- if (expandedTasks.error) {
324
- return { error: buildRequestedModeError(params, expandedTasks.error) };
325
- }
326
- return { params: { ...params, tasks: expandedTasks.tasks } };
327
- }
328
- if (params.chain) {
329
- const expandedChain = expandChainParallelCounts(params.chain);
330
- if (expandedChain.error) {
331
- return { error: buildRequestedModeError(params, expandedChain.error) };
332
- }
333
- return { params: { ...params, chain: expandedChain.chain } };
334
- }
335
- return { params };
272
+ function getRequestedModeLabel(params: SubagentParamsLike): Details["mode"] {
273
+ if ((params.chain?.length ?? 0) > 0) {
274
+ return "chain";
275
+ }
276
+ if ((params.tasks?.length ?? 0) > 0) {
277
+ return "parallel";
278
+ }
279
+ return "single";
280
+ }
281
+ export function buildRequestedModeError(
282
+ params: SubagentParamsLike,
283
+ message: string,
284
+ ): SubagentExecutionResult {
285
+ return withForkContext(validationError(getRequestedModeLabel(params), message), params.context);
336
286
  }
337
-
338
287
  export function withForkContext(
339
- result: SubagentExecutionResult,
340
- context: SubagentParamsLike["context"],
288
+ result: SubagentExecutionResult,
289
+ context: SubagentParamsLike["context"],
341
290
  ): SubagentExecutionResult {
342
- if (context !== "fork" || !result.details) return result;
343
- return {
344
- ...result,
345
- details: {
346
- ...result.details,
347
- context: "fork",
348
- },
349
- };
291
+ if (context !== "fork") {
292
+ return result;
293
+ }
294
+ return { ...result, details: { ...result.details, context: "fork" } };
350
295
  }
351
-
352
296
  export function toExecutionErrorResult(
353
- params: SubagentParamsLike,
354
- error: unknown,
355
- context: SubagentParamsLike["context"] = params.context,
297
+ params: SubagentParamsLike,
298
+ error: unknown,
299
+ context: SubagentParamsLike["context"] = params.context,
356
300
  ): SubagentExecutionResult {
357
- const message = error instanceof Error ? error.message : String(error);
358
- return withForkContext(
359
- {
360
- content: [{ type: "text", text: message }],
361
- isError: true,
362
- details: { mode: getRequestedModeLabel(params), results: [] },
363
- },
364
- context,
365
- );
301
+ const message = errorMessage(error);
302
+ return withForkContext(validationError(getRequestedModeLabel(params), message), context);
303
+ }
304
+ function sessionAgents(step: ChainStep, maximum: number): readonly (string | undefined)[] {
305
+ if (isParallelStep(step)) {
306
+ return step.parallel.map((task) => task.agent);
307
+ }
308
+ if (isDynamicParallelStep(step)) {
309
+ return Array.from({ length: step.expand.maxItems ?? maximum }, () => step.parallel.agent);
310
+ }
311
+ return [getStepAgents(step)[0]];
366
312
  }
367
-
368
313
  export function collectChainSessionFiles(
369
- chain: ChainStep[],
370
- sessionFileForIndex: (idx?: number) => string | undefined,
371
- sessionFileForAgentIndex: (agentName: string | undefined, idx?: number) => string | undefined,
372
- dynamicFanoutMaxItems?: number,
314
+ chain: readonly ChainStep[],
315
+ sessionFileForIndex: (index?: number) => string | undefined,
316
+ sessionFileForAgentIndex: (agent: string | undefined, index?: number) => string | undefined,
317
+ dynamicFanoutMaxItems = 0,
373
318
  ): (string | undefined)[] {
374
- const sessionFiles: (string | undefined)[] = [];
375
- let flatIndex = 0;
376
- for (const step of chain) {
377
- if (isParallelStep(step)) {
378
- for (let i = 0; i < step.parallel.length; i++) {
379
- const agentName = step.parallel[i]?.agent;
380
- sessionFiles.push(sessionFileForAgentIndex(agentName, flatIndex) ?? sessionFileForIndex(flatIndex));
381
- flatIndex++;
382
- }
383
- continue;
384
- }
385
- if (isDynamicParallelStep(step)) {
386
- const maxItems = step.expand.maxItems ?? dynamicFanoutMaxItems ?? 0;
387
- for (let i = 0; i < maxItems; i++) {
388
- sessionFiles.push(sessionFileForAgentIndex(step.parallel.agent, flatIndex) ?? sessionFileForIndex(flatIndex));
389
- flatIndex++;
390
- }
391
- continue;
392
- }
393
- const agentName = getStepAgents(step)[0];
394
- sessionFiles.push(sessionFileForAgentIndex(agentName, flatIndex) ?? sessionFileForIndex(flatIndex));
395
- flatIndex++;
396
- }
397
- return sessionFiles;
319
+ return chain
320
+ .flatMap((step) => sessionAgents(step, dynamicFanoutMaxItems))
321
+ .map((agent, index) => sessionFileForAgentIndex(agent, index) ?? sessionFileForIndex(index));
398
322
  }
399
-
400
323
  export function buildParallelModeError(message: string): SubagentExecutionResult {
401
- return {
402
- content: [{ type: "text", text: message }],
403
- isError: true,
404
- details: { mode: "parallel" as const, results: [] },
405
- };
324
+ return validationError("parallel", message);
406
325
  }
407
-
408
326
  export function buildParallelWorktreeTaskCwdError(
409
- tasks: ReadonlyArray<{ agent: string; cwd?: string }>,
410
- sharedCwd: string,
327
+ tasks: ReadonlyArray<{ readonly agent: string; readonly cwd?: string }>,
328
+ sharedCwd: string,
411
329
  ): string | undefined {
412
- const conflict = findWorktreeTaskCwdConflict(tasks, sharedCwd);
413
- if (!conflict) return undefined;
414
- return formatWorktreeTaskCwdConflict(conflict, sharedCwd);
330
+ const conflict = findWorktreeTaskCwdConflict(tasks, sharedCwd);
331
+ return conflict ? formatWorktreeTaskCwdConflict(conflict, sharedCwd) : undefined;
415
332
  }
416
-
417
- export function buildChainWorktreeTaskCwdError(chain: ChainStep[], sharedCwd: string): string | undefined {
418
- for (let stepIndex = 0; stepIndex < chain.length; stepIndex++) {
419
- const step = chain[stepIndex]!;
420
- if (!isParallelStep(step) || !step.worktree) continue;
421
- const stepCwd = resolveChildCwd(sharedCwd, step.cwd);
422
- const conflict = findWorktreeTaskCwdConflict(step.parallel, stepCwd);
423
- if (!conflict) continue;
424
- const detail = formatWorktreeTaskCwdConflict(conflict, stepCwd);
425
- return `parallel chain step ${stepIndex + 1}: ${detail}`;
426
- }
427
- return undefined;
333
+ export function buildChainWorktreeTaskCwdError(
334
+ chain: readonly ChainStep[],
335
+ sharedCwd: string,
336
+ ): string | undefined {
337
+ for (const [index, step] of chain.entries()) {
338
+ if (!isParallelStep(step) || step.worktree !== true) {
339
+ continue;
340
+ }
341
+ const cwd = resolveChildCwd(sharedCwd, step.cwd);
342
+ const conflict = findWorktreeTaskCwdConflict(step.parallel, cwd);
343
+ if (conflict) {
344
+ return `parallel chain step ${index + 1}: ${formatWorktreeTaskCwdConflict(conflict, cwd)}`;
345
+ }
346
+ }
347
+ return;
428
348
  }
429
-
430
349
  export function resolveParallelTaskCwd(
431
- task: TaskParam,
432
- paramsCwd: string,
433
- worktreeSetup: WorktreeSetup | undefined,
434
- index: number,
350
+ task: TaskParam,
351
+ cwd: string,
352
+ worktree: ReadonlyInput<WorktreeSetup> | undefined,
353
+ index: number,
435
354
  ): string {
436
- if (worktreeSetup) return worktreeSetup.worktrees[index]!.agentCwd;
437
- return resolveChildCwd(paramsCwd, task.cwd);
355
+ if (!worktree) {
356
+ return resolveChildCwd(cwd, task.cwd);
357
+ }
358
+ const assigned = worktree.worktrees.at(index);
359
+ if (!assigned) {
360
+ throw new Error(`Missing worktree assignment for child ${index}.`);
361
+ }
362
+ return assigned.agentCwd;
438
363
  }
439
-
440
364
  export function findDuplicateParallelOutputPath(input: {
441
- tasks: TaskParam[];
442
- behaviors: ResolvedStepBehavior[];
443
- paramsCwd: string;
444
- ctxCwd: string;
445
- worktreeSetup?: WorktreeSetup;
365
+ readonly tasks: readonly TaskParam[];
366
+ readonly behaviors: readonly ResolvedStepBehavior[];
367
+ readonly paramsCwd: string;
368
+ readonly ctxCwd: string;
369
+ readonly worktreeSetup?: ReadonlyInput<WorktreeSetup>;
446
370
  }): string | undefined {
447
- return findDuplicateOutputPath(input.tasks.map((task, index) => {
448
- const behavior = input.behaviors[index];
449
- if (!behavior?.output) return { agent: task.agent };
450
- const taskCwd = resolveParallelTaskCwd(task, input.paramsCwd, input.worktreeSetup, index);
451
- return {
452
- agent: task.agent,
453
- outputPath: resolveSingleOutputPath(behavior.output, input.ctxCwd, taskCwd),
454
- };
455
- }));
371
+ return findDuplicateOutputPath(
372
+ input.tasks.map((task, index) => {
373
+ const output = input.behaviors.at(index)?.output;
374
+ if (output === false || output === undefined || output.length === 0) {
375
+ return { agent: task.agent };
376
+ }
377
+ return {
378
+ agent: task.agent,
379
+ outputPath: resolveSingleOutputPath(
380
+ output,
381
+ input.ctxCwd,
382
+ resolveParallelTaskCwd(task, input.paramsCwd, input.worktreeSetup, index),
383
+ ),
384
+ };
385
+ }),
386
+ );
456
387
  }
457
-
458
388
  export function findDuplicateAbsoluteParallelOutputPath(input: {
459
- tasks: TaskParam[];
460
- behaviors: ResolvedStepBehavior[];
389
+ readonly tasks: readonly TaskParam[];
390
+ readonly behaviors: readonly ResolvedStepBehavior[];
461
391
  }): string | undefined {
462
- return findDuplicateOutputPath(input.tasks.map((task, index) => {
463
- const behavior = input.behaviors[index];
464
- if (typeof behavior?.output !== "string" || !path.isAbsolute(behavior.output)) return { agent: task.agent };
465
- return { agent: task.agent, outputPath: path.resolve(behavior.output) };
466
- }));
392
+ return findDuplicateOutputPath(
393
+ input.tasks.map((task, index) => {
394
+ const output = input.behaviors.at(index)?.output;
395
+ if (typeof output !== "string" || !path.isAbsolute(output)) {
396
+ return { agent: task.agent };
397
+ }
398
+ return { agent: task.agent, outputPath: path.resolve(output) };
399
+ }),
400
+ );
467
401
  }