@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,295 +1,459 @@
1
- import type { DynamicParallelStep, ParallelTaskItem } from "../../shared/settings.ts";
2
- import type { ArtifactPaths, ChainOutputMap, JsonSchemaObject, SingleResult } from "../../shared/types.ts";
1
+ import { isRecord, isUnknownArray, recordAt, type UnknownRecord } from "../../shared/unknown.ts";
2
+ import type { DynamicParallelStep, ParallelTaskItem } from "../../shared/types/workflow.ts";
3
+ import type {
4
+ ReadonlyInput,
5
+ ArtifactPaths,
6
+ ChainOutputMap,
7
+ JsonSchemaObject,
8
+ SingleResult,
9
+ } from "../../shared/types.ts";
3
10
  import { getSingleResultOutput } from "../../shared/utils.ts";
4
11
  import { validateStructuredOutputValue } from "./structured-output.ts";
5
12
 
6
- export class DynamicFanoutError extends Error {}
13
+ import {
14
+ DynamicFanoutError,
15
+ assertJsonPointer,
16
+ resolveJsonPointer,
17
+ scalarToKey,
18
+ normalizeItemKeyForId,
19
+ resolveItemTemplate,
20
+ } from "./dynamic-item.ts";
21
+ export {
22
+ DynamicFanoutError,
23
+ assertJsonPointer,
24
+ resolveJsonPointer,
25
+ normalizeItemKeyForId,
26
+ resolveItemTemplate,
27
+ } from "./dynamic-item.ts";
7
28
 
8
29
  export interface DynamicFanoutConfig {
9
- maxItems?: number;
10
- allowRunnerFields?: boolean;
30
+ readonly maxItems?: number;
31
+ readonly allowRunnerFields?: boolean;
11
32
  }
12
33
 
13
34
  export interface DynamicMaterializedItem {
14
- index: number;
15
- key: string;
16
- idKey: string;
17
- item: unknown;
35
+ readonly index: number;
36
+ readonly key: string;
37
+ readonly idKey: string;
38
+ readonly item: unknown;
18
39
  }
19
40
 
20
41
  export interface DynamicCollectedResult {
21
- key: string;
22
- index: number;
23
- item: unknown;
24
- agent: string;
25
- exitCode: number | null;
26
- text: string;
27
- structured?: unknown;
28
- error?: string;
29
- outputPath?: string;
30
- artifactPaths?: ArtifactPaths;
42
+ key: string;
43
+ index: number;
44
+ item: unknown;
45
+ agent: string;
46
+ exitCode: number | null;
47
+ text: string;
48
+ structured?: unknown;
49
+ error?: string;
50
+ outputPath?: string;
51
+ artifactPaths?: ArtifactPaths;
31
52
  }
32
53
 
33
54
  export interface DynamicMaterializedGroup {
34
- items: DynamicMaterializedItem[];
35
- parallel: ParallelTaskItem[];
55
+ items: DynamicMaterializedItem[];
56
+ parallel: ParallelTaskItem[];
36
57
  }
37
58
 
38
59
  const SAFE_OUTPUT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
39
60
  const ITEM_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
40
61
  const ITEM_REF_PATTERN = /\{([A-Za-z_][A-Za-z0-9_]*)(?:\.([^{}]+))?\}/g;
41
62
  const RESERVED_TEMPLATE_NAMES = new Set(["task", "previous", "chain_dir", "outputs"]);
42
- const DYNAMIC_STEP_KEYS = new Set(["expand", "parallel", "collect", "concurrency", "failFast", "phase", "label", "acceptance"]);
43
- const RUNNER_DYNAMIC_STEP_KEYS = new Set([...DYNAMIC_STEP_KEYS, "effectiveAcceptance", "sessionFiles"]);
44
- const DYNAMIC_EXPAND_KEYS = new Set(["from", "item", "key", "maxItems", "onEmpty"]);
45
- const DYNAMIC_EXPAND_FROM_KEYS = new Set(["output", "path"]);
46
- const DYNAMIC_PARALLEL_KEYS = new Set(["agent", "task", "phase", "label", "outputSchema", "cwd", "output", "outputMode", "reads", "progress", "skill", "model", "acceptance"]);
47
- const RUNNER_DYNAMIC_PARALLEL_KEYS = new Set([
48
- ...DYNAMIC_PARALLEL_KEYS,
49
- "outputName", "structured", "inheritProjectContext", "inheritSkills", "skills", "outputPath", "outputPathFromAgentDefault", "allowSubagents", "maxSubagentDepth",
50
- "structuredOutput", "structuredOutputSchema", "tools", "extensions", "mcpDirectTools", "completionGuard", "systemPrompt",
51
- "systemPromptMode", "thinking", "modelCandidates", "sessionFile", "effectiveAcceptance", "maxExecutionTimeMs", "maxTokens", "launch",
52
- ]);
53
- const DYNAMIC_COLLECT_KEYS = new Set(["as", "outputSchema"]);
63
+ const DYNAMIC_STEP_KEYS = [
64
+ "expand",
65
+ "parallel",
66
+ "collect",
67
+ "concurrency",
68
+ "failFast",
69
+ "phase",
70
+ "label",
71
+ "acceptance",
72
+ ];
73
+ const RUNNER_DYNAMIC_STEP_KEYS = [...DYNAMIC_STEP_KEYS, "effectiveAcceptance", "sessionFiles"];
74
+ const DYNAMIC_EXPAND_KEYS = ["from", "item", "key", "maxItems", "onEmpty"];
75
+ const DYNAMIC_EXPAND_FROM_KEYS = ["output", "path"];
76
+ const DYNAMIC_PARALLEL_KEYS = [
77
+ "agent",
78
+ "task",
79
+ "phase",
80
+ "label",
81
+ "outputSchema",
82
+ "cwd",
83
+ "output",
84
+ "outputMode",
85
+ "reads",
86
+ "progress",
87
+ "skill",
88
+ "model",
89
+ "acceptance",
90
+ ];
91
+ const RUNNER_DYNAMIC_PARALLEL_KEYS = [
92
+ ...DYNAMIC_PARALLEL_KEYS,
93
+ "outputName",
94
+ "structured",
95
+ "inheritProjectContext",
96
+ "inheritSkills",
97
+ "skills",
98
+ "outputPath",
99
+ "outputPathFromAgentDefault",
100
+ "allowSubagents",
101
+ "maxSubagentDepth",
102
+ "structuredOutput",
103
+ "structuredOutputSchema",
104
+ "tools",
105
+ "extensions",
106
+ "mcpDirectTools",
107
+ "completionGuard",
108
+ "systemPrompt",
109
+ "systemPromptMode",
110
+ "thinking",
111
+ "modelCandidates",
112
+ "sessionFile",
113
+ "effectiveAcceptance",
114
+ "maxExecutionTimeMs",
115
+ "maxTokens",
116
+ "launch",
117
+ ];
118
+ const DYNAMIC_COLLECT_KEYS = ["as", "outputSchema"];
54
119
 
55
120
  export function isSafeOutputName(name: string): boolean {
56
- return SAFE_OUTPUT_NAME_PATTERN.test(name);
121
+ return SAFE_OUTPUT_NAME_PATTERN.test(name);
57
122
  }
58
123
 
59
- export function assertJsonPointer(pointer: string, label: string): void {
60
- if (pointer === "") return;
61
- if (!pointer.startsWith("/")) {
62
- throw new DynamicFanoutError(`${label} must be a JSON Pointer starting with '/'.`);
63
- }
64
- for (const segment of pointer.slice(1).split("/")) {
65
- if (/~(?![01])/.test(segment)) {
66
- throw new DynamicFanoutError(`${label} contains invalid JSON Pointer escape.`);
67
- }
68
- }
124
+ function validateObjectKeys(
125
+ value: unknown,
126
+ allowed: readonly string[],
127
+ label: string,
128
+ ): UnknownRecord {
129
+ if (!isRecord(value)) {
130
+ throw new DynamicFanoutError(`${label} must be an object.`);
131
+ }
132
+ for (const key of Object.keys(value)) {
133
+ if (!allowed.includes(key)) {
134
+ throw new DynamicFanoutError(`${label} does not support field '${key}'.`);
135
+ }
136
+ }
137
+ return value;
69
138
  }
70
139
 
71
- function decodePointerSegment(segment: string): string {
72
- return segment.replace(/~1/g, "/").replace(/~0/g, "~");
140
+ const VALID_ITEM_REF_PATTERN = new RegExp(ITEM_REF_PATTERN.source);
141
+
142
+ function validateTemplateReference(
143
+ raw: string,
144
+ reference: string,
145
+ itemName: string,
146
+ label: string,
147
+ ): void {
148
+ if (reference === itemName || reference.startsWith(`${itemName}.`)) {
149
+ if (
150
+ !VALID_ITEM_REF_PATTERN.test(raw) ||
151
+ reference === `${itemName}.` ||
152
+ reference.includes("..")
153
+ ) {
154
+ throw new DynamicFanoutError(`Invalid item reference '${raw}' in ${label}.`);
155
+ }
156
+ return;
157
+ }
158
+ const name = reference.match(/^[A-Za-z_][A-Za-z0-9_]*/)?.[0];
159
+ if (name === itemName) {
160
+ throw new DynamicFanoutError(`Invalid item reference '${raw}' in ${label}.`);
161
+ }
162
+ if (name === undefined || RESERVED_TEMPLATE_NAMES.has(name)) {
163
+ return;
164
+ }
165
+ throw new DynamicFanoutError(`Unsupported template reference '${raw}' in ${label}.`);
73
166
  }
74
167
 
75
- export function resolveJsonPointer(value: unknown, pointer: string, label: string): unknown {
76
- assertJsonPointer(pointer, label);
77
- if (pointer === "") return value;
78
- let current = value;
79
- for (const rawSegment of pointer.slice(1).split("/")) {
80
- const segment = decodePointerSegment(rawSegment);
81
- if (Array.isArray(current)) {
82
- if (!/^(0|[1-9][0-9]*)$/.test(segment)) {
83
- throw new DynamicFanoutError(`${label} segment '${segment}' does not address an array index.`);
84
- }
85
- const index = Number(segment);
86
- if (index >= current.length) throw new DynamicFanoutError(`${label} does not exist.`);
87
- current = current[index];
88
- continue;
89
- }
90
- if (!current || typeof current !== "object") {
91
- throw new DynamicFanoutError(`${label} does not exist.`);
92
- }
93
- const record = current as Record<string, unknown>;
94
- if (!Object.prototype.hasOwnProperty.call(record, segment)) {
95
- throw new DynamicFanoutError(`${label} does not exist.`);
96
- }
97
- current = record[segment];
98
- }
99
- return current;
168
+ export function assertNoUnresolvedItemReferences(
169
+ template: string,
170
+ itemName: string,
171
+ label: string,
172
+ ): void {
173
+ for (const match of template.matchAll(/\{([^{}]*)\}/g)) {
174
+ validateTemplateReference(match[0], match[1], itemName, label);
175
+ }
176
+ if (
177
+ template.includes(`{${itemName}.}`) ||
178
+ new RegExp(`\\{${itemName}(?:\\.|$)[^}]*$`).test(template)
179
+ ) {
180
+ throw new DynamicFanoutError(`Invalid item reference in ${label}.`);
181
+ }
100
182
  }
101
183
 
102
- function scalarToKey(value: unknown, label: string): string {
103
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
104
- const key = String(value);
105
- if (!key.trim()) throw new DynamicFanoutError(`${label} resolved to an empty key.`);
106
- if (/[\u0000-\u001F\u007F]/.test(key)) throw new DynamicFanoutError(`${label} resolved to an unsafe key.`);
107
- if (key.length > 200) throw new DynamicFanoutError(`${label} resolved to a key longer than 200 characters.`);
108
- return key;
109
- }
110
- throw new DynamicFanoutError(`${label} must resolve to a string, number, or boolean.`);
184
+ export function hasDynamicFanoutFields(step: unknown): boolean {
185
+ return (
186
+ isRecord(step) &&
187
+ (Object.prototype.hasOwnProperty.call(step, "expand") ||
188
+ Object.prototype.hasOwnProperty.call(step, "collect"))
189
+ );
111
190
  }
112
191
 
113
- export function normalizeItemKeyForId(key: string): string {
114
- const normalized = key
115
- .toLowerCase()
116
- .replace(/[^a-z0-9]+/g, "-")
117
- .replace(/^-+|-+$/g, "")
118
- .slice(0, 80);
119
- return normalized || "item";
192
+ function requireString(value: unknown, label: string): string {
193
+ if (typeof value !== "string") {
194
+ throw new DynamicFanoutError(`${label} must be a string.`);
195
+ }
196
+ return value;
120
197
  }
121
198
 
122
- function valueToTemplateText(value: unknown, reference: string): string {
123
- if (value === undefined) throw new DynamicFanoutError(`Unresolved item reference '${reference}'.`);
124
- if (typeof value === "string") return value;
125
- if (typeof value === "number" || typeof value === "boolean" || value === null) return String(value);
126
- return JSON.stringify(value);
199
+ function validateItemLimit(value: unknown, label: string): void {
200
+ if (value !== undefined && (typeof value !== "number" || !Number.isInteger(value) || value < 0)) {
201
+ throw new DynamicFanoutError(`${label} must be an integer >= 0.`);
202
+ }
127
203
  }
128
204
 
129
- function resolveItemPath(item: unknown, pathText: string | undefined, reference: string): unknown {
130
- if (!pathText) return item;
131
- const pointer = `/${pathText.split(".").map((segment) => segment.replace(/~/g, "~0").replace(/\//g, "~1")).join("/")}`;
132
- return resolveJsonPointer(item, pointer, reference);
205
+ function validateExpandFrom(from: UnknownRecord, prefix: string): void {
206
+ validateObjectKeys(from, DYNAMIC_EXPAND_FROM_KEYS, `${prefix} expand.from`);
207
+ const output = requireString(from.output, `${prefix} expand.from.output`);
208
+ if (!isSafeOutputName(output)) {
209
+ throw new DynamicFanoutError(`${prefix} has invalid expand.from.output '${output}'.`);
210
+ }
211
+ assertJsonPointer(
212
+ requireString(from.path, `${prefix} expand.from.path`),
213
+ `${prefix} expand.from.path`,
214
+ );
133
215
  }
134
216
 
135
- export function resolveItemTemplate(template: string, itemName: string, item: unknown): string {
136
- return template.replace(ITEM_REF_PATTERN, (raw, name: string, pathText: string | undefined) => {
137
- if (name !== itemName) return raw;
138
- if (pathText !== undefined && (!pathText.trim() || pathText.includes(".."))) {
139
- throw new DynamicFanoutError(`Invalid item reference '${raw}'.`);
140
- }
141
- return valueToTemplateText(resolveItemPath(item, pathText, raw), raw);
142
- });
217
+ function validateExpansion(expand: unknown, prefix: string, config: DynamicFanoutConfig): string {
218
+ const from = recordAt(expand, "from");
219
+ if (!isRecord(expand) || !from) {
220
+ throw new DynamicFanoutError(`${prefix} requires expand.from.`);
221
+ }
222
+ validateObjectKeys(expand, DYNAMIC_EXPAND_KEYS, `${prefix} expand`);
223
+ validateExpandFrom(from, prefix);
224
+ if (expand.key !== undefined) {
225
+ assertJsonPointer(requireString(expand.key, `${prefix} expand.key`), `${prefix} expand.key`);
226
+ }
227
+ const itemName = requireString(expand.item ?? "item", `${prefix} expand.item`);
228
+ if (!ITEM_NAME_PATTERN.test(itemName)) {
229
+ throw new DynamicFanoutError(`${prefix} has invalid expand.item '${itemName}'.`);
230
+ }
231
+ if (expand.maxItems === undefined && config.maxItems === undefined) {
232
+ throw new DynamicFanoutError(
233
+ `${prefix} requires expand.maxItems or config.chain.dynamicFanout.maxItems.`,
234
+ );
235
+ }
236
+ validateItemLimit(expand.maxItems, `${prefix} expand.maxItems`);
237
+ validateItemLimit(config.maxItems, "config.chain.dynamicFanout.maxItems");
238
+ return itemName;
143
239
  }
144
240
 
145
- function assertOnlyKeys(value: unknown, allowed: Set<string>, label: string): void {
146
- if (!value || typeof value !== "object" || Array.isArray(value)) throw new DynamicFanoutError(`${label} must be an object.`);
147
- for (const key of Object.keys(value)) {
148
- if (!allowed.has(key)) throw new DynamicFanoutError(`${label} does not support field '${key}'.`);
149
- }
241
+ function validateParallelTemplate(
242
+ parallel: unknown,
243
+ prefix: string,
244
+ itemName: string,
245
+ runnerFields: boolean,
246
+ ): void {
247
+ if (!isRecord(parallel)) {
248
+ throw new DynamicFanoutError(
249
+ `${prefix} requires a single parallel template object and cannot mix dynamic expand/collect with static parallel arrays.`,
250
+ );
251
+ }
252
+ validateObjectKeys(
253
+ parallel,
254
+ runnerFields ? RUNNER_DYNAMIC_PARALLEL_KEYS : DYNAMIC_PARALLEL_KEYS,
255
+ `${prefix} parallel`,
256
+ );
257
+ if ("expand" in parallel) {
258
+ throw new DynamicFanoutError(`${prefix} does not support nested dynamic fanout.`);
259
+ }
260
+ if (typeof parallel.agent !== "string" || parallel.agent.length === 0) {
261
+ throw new DynamicFanoutError(`${prefix} parallel.agent is required.`);
262
+ }
263
+ for (const [label, value] of [
264
+ ["parallel.task", parallel.task],
265
+ ["parallel.label", parallel.label],
266
+ ] as const) {
267
+ if (value === undefined) {
268
+ continue;
269
+ }
270
+ const template = requireString(value, `${prefix} ${label}`);
271
+ if (template.length > 0) {
272
+ assertNoUnresolvedItemReferences(template, itemName, `${prefix} ${label}`);
273
+ }
274
+ }
150
275
  }
151
276
 
152
- export function assertNoUnresolvedItemReferences(template: string, itemName: string, label: string): void {
153
- for (const match of template.matchAll(/\{([^{}]*)\}/g)) {
154
- const raw = match[0]!;
155
- const reference = match[1]!;
156
- if (reference === itemName || reference.startsWith(`${itemName}.`)) {
157
- if (!ITEM_REF_PATTERN.test(raw) || reference === `${itemName}.` || reference.includes("..")) {
158
- throw new DynamicFanoutError(`Invalid item reference '${raw}' in ${label}.`);
159
- }
160
- ITEM_REF_PATTERN.lastIndex = 0;
161
- continue;
162
- }
163
- ITEM_REF_PATTERN.lastIndex = 0;
164
- const name = reference.match(/^[A-Za-z_][A-Za-z0-9_]*/)?.[0];
165
- if (name === itemName) throw new DynamicFanoutError(`Invalid item reference '${raw}' in ${label}.`);
166
- if (name && RESERVED_TEMPLATE_NAMES.has(name)) continue;
167
- if (name) throw new DynamicFanoutError(`Unsupported template reference '${raw}' in ${label}.`);
168
- }
169
- ITEM_REF_PATTERN.lastIndex = 0;
170
- if (template.includes(`{${itemName}.}`) || new RegExp(`\\{${itemName}(?:\\.|$)[^}]*$`).test(template)) {
171
- throw new DynamicFanoutError(`Invalid item reference in ${label}.`);
172
- }
277
+ function validateCollection(collect: unknown, prefix: string): void {
278
+ if (!isRecord(collect) || typeof collect.as !== "string" || !isSafeOutputName(collect.as)) {
279
+ throw new DynamicFanoutError(`${prefix} requires collect.as with a safe output name.`);
280
+ }
281
+ validateObjectKeys(collect, DYNAMIC_COLLECT_KEYS, `${prefix} collect`);
173
282
  }
174
283
 
175
- export function hasDynamicFanoutFields(step: unknown): boolean {
176
- return !!step && typeof step === "object" && !Array.isArray(step)
177
- && (Object.prototype.hasOwnProperty.call(step, "expand") || Object.prototype.hasOwnProperty.call(step, "collect"));
284
+ /** Validates dynamic vocabulary and expansion semantics, not the entire child execution schema. */
285
+ export function validateDynamicStepShape(
286
+ step: unknown,
287
+ stepIndex: number,
288
+ config: DynamicFanoutConfig = {},
289
+ ): void {
290
+ const prefix = `Dynamic chain step ${stepIndex + 1}`;
291
+ if (
292
+ isRecord(step) &&
293
+ (Object.hasOwn(step, "acceptance") || Object.hasOwn(step, "effectiveAcceptance"))
294
+ ) {
295
+ throw new DynamicFanoutError(
296
+ `Dynamic fanout step ${stepIndex + 1} does not support group-level acceptance; set acceptance on the child template instead.`,
297
+ );
298
+ }
299
+ const record = validateObjectKeys(
300
+ step,
301
+ config.allowRunnerFields === true ? RUNNER_DYNAMIC_STEP_KEYS : DYNAMIC_STEP_KEYS,
302
+ prefix,
303
+ );
304
+ const itemName = validateExpansion(record.expand, prefix, config);
305
+ validateParallelTemplate(record.parallel, prefix, itemName, config.allowRunnerFields === true);
306
+ validateCollection(record.collect, prefix);
178
307
  }
179
308
 
180
- export function validateDynamicStepShape(step: DynamicParallelStep, stepIndex: number, config: DynamicFanoutConfig = {}): void {
181
- const prefix = `Dynamic chain step ${stepIndex + 1}`;
182
- if (Object.hasOwn(step, "acceptance") || Object.hasOwn(step, "effectiveAcceptance")) {
183
- throw new DynamicFanoutError(`Dynamic fanout step ${stepIndex + 1} does not support group-level acceptance; set acceptance on the child template instead.`);
184
- }
185
- assertOnlyKeys(step, config.allowRunnerFields ? RUNNER_DYNAMIC_STEP_KEYS : DYNAMIC_STEP_KEYS, prefix);
186
- if (!step.expand || !step.expand.from) throw new DynamicFanoutError(`${prefix} requires expand.from.`);
187
- assertOnlyKeys(step.expand, DYNAMIC_EXPAND_KEYS, `${prefix} expand`);
188
- assertOnlyKeys(step.expand.from, DYNAMIC_EXPAND_FROM_KEYS, `${prefix} expand.from`);
189
- if (!isSafeOutputName(step.expand.from.output)) throw new DynamicFanoutError(`${prefix} has invalid expand.from.output '${step.expand.from.output}'.`);
190
- assertJsonPointer(step.expand.from.path, `${prefix} expand.from.path`);
191
- if (step.expand.key !== undefined) assertJsonPointer(step.expand.key, `${prefix} expand.key`);
192
- const itemName = step.expand.item ?? "item";
193
- if (!ITEM_NAME_PATTERN.test(itemName)) throw new DynamicFanoutError(`${prefix} has invalid expand.item '${itemName}'.`);
194
- if (step.expand.maxItems === undefined && config.maxItems === undefined) {
195
- throw new DynamicFanoutError(`${prefix} requires expand.maxItems or config.chain.dynamicFanout.maxItems.`);
196
- }
197
- if (step.expand.maxItems !== undefined && (!Number.isInteger(step.expand.maxItems) || step.expand.maxItems < 0)) {
198
- throw new DynamicFanoutError(`${prefix} expand.maxItems must be an integer >= 0.`);
199
- }
200
- if (config.maxItems !== undefined && (!Number.isInteger(config.maxItems) || config.maxItems < 0)) {
201
- throw new DynamicFanoutError("config.chain.dynamicFanout.maxItems must be an integer >= 0.");
202
- }
203
- if (!step.parallel || Array.isArray(step.parallel)) throw new DynamicFanoutError(`${prefix} requires a single parallel template object and cannot mix dynamic expand/collect with static parallel arrays.`);
204
- assertOnlyKeys(step.parallel, config.allowRunnerFields ? RUNNER_DYNAMIC_PARALLEL_KEYS : DYNAMIC_PARALLEL_KEYS, `${prefix} parallel`);
205
- if ("expand" in (step.parallel as object)) throw new DynamicFanoutError(`${prefix} does not support nested dynamic fanout.`);
206
- if (!step.parallel.agent) throw new DynamicFanoutError(`${prefix} parallel.agent is required.`);
207
- if (!step.collect?.as || !isSafeOutputName(step.collect.as)) throw new DynamicFanoutError(`${prefix} requires collect.as with a safe output name.`);
208
- assertOnlyKeys(step.collect, DYNAMIC_COLLECT_KEYS, `${prefix} collect`);
209
- for (const [label, template] of [
210
- ["parallel.task", step.parallel.task],
211
- ["parallel.label", step.parallel.label],
212
- ] as const) {
213
- if (template) assertNoUnresolvedItemReferences(template, itemName, `${prefix} ${label}`);
214
- }
309
+ export function resolveDynamicFanoutItems(
310
+ step: ReadonlyInput<DynamicParallelStep>,
311
+ outputs: ReadonlyInput<ChainOutputMap>,
312
+ stepIndex: number,
313
+ config: DynamicFanoutConfig = {},
314
+ ): DynamicMaterializedItem[] {
315
+ validateDynamicStepShape(step, stepIndex, config);
316
+ const sourceName = step.expand.from.output;
317
+ const source = outputs[sourceName];
318
+ if (!Object.hasOwn(outputs, sourceName)) {
319
+ throw new DynamicFanoutError(
320
+ `Dynamic chain step ${stepIndex + 1} references unknown output '${sourceName}'.`,
321
+ );
322
+ }
323
+ if (source.structured === undefined) {
324
+ throw new DynamicFanoutError(
325
+ `Dynamic chain step ${stepIndex + 1} requires structured output '${sourceName}'.`,
326
+ );
327
+ }
328
+ const value = resolveJsonPointer(
329
+ source.structured,
330
+ step.expand.from.path,
331
+ `Dynamic chain step ${stepIndex + 1} expand.from.path`,
332
+ );
333
+ if (!isUnknownArray(value)) {
334
+ throw new DynamicFanoutError(
335
+ `Dynamic chain step ${stepIndex + 1} expand.from.path must resolve to an array.`,
336
+ );
337
+ }
338
+ const maxItems = step.expand.maxItems ?? config.maxItems;
339
+ if (maxItems === undefined) {
340
+ throw new DynamicFanoutError(
341
+ `Dynamic chain step ${stepIndex + 1} requires an effective maxItems.`,
342
+ );
343
+ }
344
+ if (value.length > maxItems) {
345
+ throw new DynamicFanoutError(
346
+ `Dynamic chain step ${stepIndex + 1} resolved ${value.length} items, exceeding maxItems ${maxItems}.`,
347
+ );
348
+ }
349
+ const seen = new Set<string>();
350
+ const seenIds = new Set<string>();
351
+ return value.map((item: unknown, index) => {
352
+ const key =
353
+ step.expand.key === undefined
354
+ ? String(index)
355
+ : scalarToKey(
356
+ resolveJsonPointer(
357
+ item,
358
+ step.expand.key,
359
+ `Dynamic chain step ${stepIndex + 1} expand.key`,
360
+ ),
361
+ `Dynamic chain step ${stepIndex + 1} expand.key`,
362
+ );
363
+ if (seen.has(key)) {
364
+ throw new DynamicFanoutError(
365
+ `Dynamic chain step ${stepIndex + 1} produced duplicate item key '${key}'.`,
366
+ );
367
+ }
368
+ seen.add(key);
369
+ const idKey = normalizeItemKeyForId(key);
370
+ if (seenIds.has(idKey)) {
371
+ throw new DynamicFanoutError(
372
+ `Dynamic chain step ${stepIndex + 1} produced colliding item id '${idKey}'.`,
373
+ );
374
+ }
375
+ seenIds.add(idKey);
376
+ return { index, key, idKey, item };
377
+ });
215
378
  }
216
379
 
217
- export function resolveDynamicFanoutItems(step: DynamicParallelStep, outputs: ChainOutputMap, stepIndex: number, config: DynamicFanoutConfig = {}): DynamicMaterializedItem[] {
218
- validateDynamicStepShape(step, stepIndex, config);
219
- const sourceName = step.expand.from.output;
220
- const source = outputs[sourceName];
221
- if (!source) throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} references unknown output '${sourceName}'.`);
222
- if (source.structured === undefined) throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} requires structured output '${sourceName}'.`);
223
- const value = resolveJsonPointer(source.structured, step.expand.from.path, `Dynamic chain step ${stepIndex + 1} expand.from.path`);
224
- if (!Array.isArray(value)) throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} expand.from.path must resolve to an array.`);
225
- const maxItems = step.expand.maxItems ?? config.maxItems;
226
- if (maxItems === undefined) throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} requires an effective maxItems.`);
227
- if (value.length > maxItems) throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} resolved ${value.length} items, exceeding maxItems ${maxItems}.`);
228
- const seen = new Set<string>();
229
- const seenIds = new Set<string>();
230
- return value.map((item, index) => {
231
- const key = step.expand.key === undefined
232
- ? String(index)
233
- : scalarToKey(resolveJsonPointer(item, step.expand.key, `Dynamic chain step ${stepIndex + 1} expand.key`), `Dynamic chain step ${stepIndex + 1} expand.key`);
234
- if (seen.has(key)) throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} produced duplicate item key '${key}'.`);
235
- seen.add(key);
236
- const idKey = normalizeItemKeyForId(key);
237
- if (seenIds.has(idKey)) throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} produced colliding item id '${idKey}'.`);
238
- seenIds.add(idKey);
239
- return { index, key, idKey, item };
240
- });
380
+ export function materializeDynamicParallelStep(
381
+ step: ReadonlyInput<DynamicParallelStep>,
382
+ outputs: ReadonlyInput<ChainOutputMap>,
383
+ stepIndex: number,
384
+ config: DynamicFanoutConfig = {},
385
+ ): DynamicMaterializedGroup {
386
+ const items = resolveDynamicFanoutItems(step, outputs, stepIndex, config);
387
+ if (items.length === 0) {
388
+ if ((step.expand.onEmpty ?? "skip") === "fail") {
389
+ throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} source array is empty.`);
390
+ }
391
+ return { items, parallel: [] };
392
+ }
393
+ const itemName = step.expand.item ?? "item";
394
+ const parallel = items.map((entry) => {
395
+ const task = resolveItemTemplate(step.parallel.task ?? "{previous}", itemName, entry.item);
396
+ const label =
397
+ (step.parallel.label ?? "").length > 0
398
+ ? resolveItemTemplate(step.parallel.label ?? "", itemName, entry.item)
399
+ : undefined;
400
+ return {
401
+ ...step.parallel,
402
+ task,
403
+ ...(label !== undefined ? { label } : {}),
404
+ };
405
+ });
406
+ return { items, parallel };
407
+ }
408
+
409
+ type CollectionChild = ReadonlyInput<
410
+ Pick<
411
+ SingleResult,
412
+ "agent" | "error" | "structuredOutput" | "artifactPaths" | "savedOutputPath" | "messages"
413
+ > & { exitCode: number | null; output?: string; finalOutput?: string }
414
+ >;
415
+
416
+ function collectionText(result: CollectionChild): string {
417
+ return typeof result.output === "string" ? result.output : getSingleResultOutput(result);
241
418
  }
242
419
 
243
- export function materializeDynamicParallelStep(step: DynamicParallelStep, outputs: ChainOutputMap, stepIndex: number, config: DynamicFanoutConfig = {}): DynamicMaterializedGroup {
244
- const items = resolveDynamicFanoutItems(step, outputs, stepIndex, config);
245
- if (items.length === 0) {
246
- if ((step.expand.onEmpty ?? "skip") === "fail") {
247
- throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} source array is empty.`);
248
- }
249
- return { items, parallel: [] };
250
- }
251
- const itemName = step.expand.item ?? "item";
252
- const parallel = items.map((entry) => {
253
- const task = resolveItemTemplate(step.parallel.task ?? "{previous}", itemName, entry.item);
254
- const label = step.parallel.label ? resolveItemTemplate(step.parallel.label, itemName, entry.item) : undefined;
255
- return {
256
- ...step.parallel,
257
- task,
258
- ...(label !== undefined ? { label } : {}),
259
- };
260
- });
261
- return { items, parallel };
420
+ function collectionMetadata(result: CollectionChild): Partial<DynamicCollectedResult> {
421
+ return {
422
+ ...(result.structuredOutput !== undefined ? { structured: result.structuredOutput } : {}),
423
+ ...((result.error ?? "").length > 0 ? { error: result.error } : {}),
424
+ ...((result.savedOutputPath ?? "").length > 0 ? { outputPath: result.savedOutputPath } : {}),
425
+ ...(result.artifactPaths ? { artifactPaths: result.artifactPaths } : {}),
426
+ };
262
427
  }
263
428
 
264
429
  export function collectDynamicResults(
265
- step: DynamicParallelStep,
266
- items: DynamicMaterializedItem[],
267
- results: Array<Pick<SingleResult, "agent" | "error" | "structuredOutput" | "artifactPaths" | "savedOutputPath"> & { exitCode: number | null; output?: string; finalOutput?: string }>,
430
+ step: ReadonlyInput<DynamicParallelStep>,
431
+ items: readonly DynamicMaterializedItem[],
432
+ results: readonly CollectionChild[],
268
433
  ): DynamicCollectedResult[] {
269
- return items.map((entry, index) => {
270
- const result = results[index];
271
- const text = result
272
- ? ("output" in result && typeof result.output === "string" ? result.output : getSingleResultOutput(result as SingleResult))
273
- : "";
274
- return {
275
- key: entry.key,
276
- index: entry.index,
277
- item: entry.item,
278
- agent: result?.agent ?? step.parallel.agent,
279
- exitCode: result?.exitCode ?? null,
280
- text,
281
- ...(result?.structuredOutput !== undefined ? { structured: result.structuredOutput } : {}),
282
- ...(result?.error ? { error: result.error } : {}),
283
- ...(result?.savedOutputPath ? { outputPath: result.savedOutputPath } : {}),
284
- ...(result?.artifactPaths ? { artifactPaths: result.artifactPaths } : {}),
285
- };
286
- });
434
+ return items.map((entry, index) => {
435
+ const result = Object.hasOwn(results, index) ? results[index] : undefined;
436
+ return {
437
+ key: entry.key,
438
+ index: entry.index,
439
+ item: entry.item,
440
+ agent: result?.agent ?? step.parallel.agent,
441
+ exitCode: result?.exitCode ?? null,
442
+ text: result ? collectionText(result) : "",
443
+ ...(result ? collectionMetadata(result) : {}),
444
+ };
445
+ });
287
446
  }
288
447
 
289
- export function validateDynamicCollection(schema: JsonSchemaObject | undefined, value: DynamicCollectedResult[]): void {
290
- if (!schema) return;
291
- const validation = validateStructuredOutputValue(schema, value);
292
- if (validation.status === "invalid") {
293
- throw new DynamicFanoutError(`Collected output validation failed: ${validation.message}`);
294
- }
448
+ export function validateDynamicCollection(
449
+ schema: ReadonlyInput<JsonSchemaObject> | undefined,
450
+ value: readonly ReadonlyInput<DynamicCollectedResult>[],
451
+ ): void {
452
+ if (!schema) {
453
+ return;
454
+ }
455
+ const validation = validateStructuredOutputValue(schema, value);
456
+ if (validation.status === "invalid") {
457
+ throw new DynamicFanoutError(`Collected output validation failed: ${validation.message}`);
458
+ }
295
459
  }