@bastani/atomic 0.9.9 → 0.9.10

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 (864) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/README.md +2 -0
  3. package/dist/builtin/cursor/CHANGELOG.md +12 -0
  4. package/dist/builtin/cursor/package.json +3 -3
  5. package/dist/builtin/intercom/CHANGELOG.md +30 -0
  6. package/dist/builtin/intercom/README.md +12 -4
  7. package/dist/builtin/intercom/broker/broker.ts +96 -14
  8. package/dist/builtin/intercom/broker/client-message-validation.ts +39 -0
  9. package/dist/builtin/intercom/broker/client.ts +101 -92
  10. package/dist/builtin/intercom/broker/group-isolation.ts +28 -0
  11. package/dist/builtin/intercom/broker/send-handler.ts +62 -10
  12. package/dist/builtin/intercom/broker/send-signature.ts +3 -0
  13. package/dist/builtin/intercom/broker/supervisor-channel.ts +126 -0
  14. package/dist/builtin/intercom/closed-workflow-stage-message.ts +66 -0
  15. package/dist/builtin/intercom/config.ts +10 -0
  16. package/dist/builtin/intercom/contact-supervisor-tool.ts +14 -10
  17. package/dist/builtin/intercom/foreground-detach-handoff.ts +12 -2
  18. package/dist/builtin/intercom/group.ts +46 -0
  19. package/dist/builtin/intercom/inbound-message-admission.ts +79 -0
  20. package/dist/builtin/intercom/incoming-message-delivery.ts +49 -0
  21. package/dist/builtin/intercom/index-heavy.ts +148 -94
  22. package/dist/builtin/intercom/index.ts +66 -4
  23. package/dist/builtin/intercom/intercom-test-seams.ts +6 -0
  24. package/dist/builtin/intercom/intercom-tool.ts +71 -20
  25. package/dist/builtin/intercom/intercom-utils.ts +15 -2
  26. package/dist/builtin/intercom/late-stage-message-router.ts +148 -0
  27. package/dist/builtin/intercom/lifecycle.ts +10 -4
  28. package/dist/builtin/intercom/package.json +2 -2
  29. package/dist/builtin/intercom/reconnect-backoff.ts +6 -0
  30. package/dist/builtin/intercom/reply-tracker.ts +8 -0
  31. package/dist/builtin/intercom/skills/intercom/SKILL.md +2 -0
  32. package/dist/builtin/intercom/stable-delivery-retry.ts +32 -0
  33. package/dist/builtin/intercom/subagent-relay.ts +67 -14
  34. package/dist/builtin/intercom/supervisor-authorization-registry.ts +22 -0
  35. package/dist/builtin/intercom/terminal-ordering-barrier.ts +144 -25
  36. package/dist/builtin/intercom/types.ts +18 -5
  37. package/dist/builtin/intercom/workflow-reply-tracker.ts +19 -0
  38. package/dist/builtin/intercom/workflow-stage-admission.ts +43 -0
  39. package/dist/builtin/intercom/workflow-stage-delivery-failure.ts +77 -0
  40. package/dist/builtin/mcp/CHANGELOG.md +22 -0
  41. package/dist/builtin/mcp/README.md +6 -2
  42. package/dist/builtin/mcp/config.ts +8 -8
  43. package/dist/builtin/mcp/direct-tool-executor.ts +7 -6
  44. package/dist/builtin/mcp/package.json +3 -3
  45. package/dist/builtin/mcp/proxy-call.ts +5 -4
  46. package/dist/builtin/mcp/sampling-handler.ts +7 -2
  47. package/dist/builtin/mcp/tool-call-timeout.ts +101 -0
  48. package/dist/builtin/mcp/tool-result-renderer.ts +3 -2
  49. package/dist/builtin/mcp/types.ts +5 -0
  50. package/dist/builtin/mcp/ui-server.ts +3 -2
  51. package/dist/builtin/subagents/CHANGELOG.md +42 -0
  52. package/dist/builtin/subagents/README.md +6 -3
  53. package/dist/builtin/subagents/agents/code-simplifier.md +1 -1
  54. package/dist/builtin/subagents/agents/codebase-analyzer.md +1 -1
  55. package/dist/builtin/subagents/agents/codebase-locator.md +1 -1
  56. package/dist/builtin/subagents/agents/codebase-online-researcher.md +1 -1
  57. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +1 -1
  58. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +1 -1
  59. package/dist/builtin/subagents/agents/codebase-research-locator.md +1 -1
  60. package/dist/builtin/subagents/agents/debugger.md +1 -1
  61. package/dist/builtin/subagents/agents/worker.md +1 -1
  62. package/dist/builtin/subagents/package.json +4 -4
  63. package/dist/builtin/subagents/skills/subagent/SKILL.md +1 -1
  64. package/dist/builtin/subagents/src/extension/index.ts +37 -61
  65. package/dist/builtin/subagents/src/extension/notification-content.ts +80 -0
  66. package/dist/builtin/subagents/src/extension/schemas.ts +9 -0
  67. package/dist/builtin/subagents/src/extension/tool-description.ts +1 -0
  68. package/dist/builtin/subagents/src/intercom/supervisor-authorization.ts +23 -0
  69. package/dist/builtin/subagents/src/runs/background/async-execution-chain.ts +4 -0
  70. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +2 -0
  71. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +4 -0
  72. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +75 -13
  73. package/dist/builtin/subagents/src/runs/background/async-status.ts +19 -0
  74. package/dist/builtin/subagents/src/runs/background/completion-notification.ts +4 -3
  75. package/dist/builtin/subagents/src/runs/background/notify.ts +76 -15
  76. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +1 -1
  77. package/dist/builtin/subagents/src/runs/background/subagent-runner-dynamic.ts +13 -0
  78. package/dist/builtin/subagents/src/runs/background/subagent-runner-parallel.ts +1 -0
  79. package/dist/builtin/subagents/src/runs/background/subagent-runner-sequential.ts +1 -0
  80. package/dist/builtin/subagents/src/runs/background/subagent-runner-step.ts +2 -1
  81. package/dist/builtin/subagents/src/runs/background/subagent-runner-types.ts +4 -0
  82. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +13 -0
  83. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +19 -2
  84. package/dist/builtin/subagents/src/runs/foreground/detached-cleanup-barrier.ts +26 -0
  85. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +19 -30
  86. package/dist/builtin/subagents/src/runs/foreground/execution-intercom-detach.ts +47 -0
  87. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +60 -2
  88. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +21 -0
  89. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +21 -2
  90. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +6 -1
  91. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +2 -0
  92. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -0
  93. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +1 -1
  94. package/dist/builtin/subagents/src/runs/shared/intercom-group.ts +50 -0
  95. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +16 -0
  96. package/dist/builtin/subagents/src/runs/shared/worktree-post-create.ts +75 -0
  97. package/dist/builtin/subagents/src/runs/shared/worktree-root.ts +51 -0
  98. package/dist/builtin/subagents/src/runs/shared/worktree.ts +69 -77
  99. package/dist/builtin/subagents/src/shared/types-config.ts +6 -0
  100. package/dist/builtin/subagents/src/slash/slash-commands.ts +3 -2
  101. package/dist/builtin/subagents/src/tui/render-result-compact.ts +5 -3
  102. package/dist/builtin/subagents/src/tui/render-result.ts +5 -3
  103. package/dist/builtin/subagents/src/tui/render-widget-graph.ts +7 -4
  104. package/dist/builtin/web-access/CHANGELOG.md +22 -0
  105. package/dist/builtin/web-access/extract-frames.ts +14 -13
  106. package/dist/builtin/web-access/extract.ts +2 -2
  107. package/dist/builtin/web-access/gemini-api.ts +0 -3
  108. package/dist/builtin/web-access/gemini-web-config.ts +1 -3
  109. package/dist/builtin/web-access/gemini-web.ts +1 -0
  110. package/dist/builtin/web-access/package.json +2 -2
  111. package/dist/builtin/web-access/perplexity.ts +0 -3
  112. package/dist/builtin/web-access/result-renderers.ts +7 -5
  113. package/dist/builtin/web-access/subprocess.ts +100 -0
  114. package/dist/builtin/web-access/summary-review.ts +14 -3
  115. package/dist/builtin/web-access/video-extract.ts +12 -17
  116. package/dist/builtin/web-access/web-search-browser.ts +18 -10
  117. package/dist/builtin/web-access/web-search-summary.ts +9 -2
  118. package/dist/builtin/web-access/youtube-extract.ts +22 -25
  119. package/dist/builtin/workflows/CHANGELOG.md +153 -0
  120. package/dist/builtin/workflows/README.md +76 -38
  121. package/dist/builtin/workflows/ambient.d.ts +30 -0
  122. package/dist/builtin/workflows/builtin/adversarial-verification-prompts.ts +15 -0
  123. package/dist/builtin/workflows/builtin/adversarial-verification-runner.ts +93 -0
  124. package/dist/builtin/workflows/builtin/adversarial-verification.d.ts +11 -0
  125. package/dist/builtin/workflows/builtin/adversarial-verification.ts +24 -0
  126. package/dist/builtin/workflows/builtin/classify-and-act-prompts.ts +11 -0
  127. package/dist/builtin/workflows/builtin/classify-and-act-runner.ts +110 -0
  128. package/dist/builtin/workflows/builtin/classify-and-act.d.ts +24 -0
  129. package/dist/builtin/workflows/builtin/classify-and-act.ts +35 -0
  130. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +8 -2
  131. package/dist/builtin/workflows/builtin/fan-out-and-synthesize-prompts.ts +11 -0
  132. package/dist/builtin/workflows/builtin/fan-out-and-synthesize-runner.ts +96 -0
  133. package/dist/builtin/workflows/builtin/fan-out-and-synthesize.d.ts +23 -0
  134. package/dist/builtin/workflows/builtin/fan-out-and-synthesize.ts +32 -0
  135. package/dist/builtin/workflows/builtin/generate-and-filter-prompts.ts +15 -0
  136. package/dist/builtin/workflows/builtin/generate-and-filter-runner.ts +75 -0
  137. package/dist/builtin/workflows/builtin/generate-and-filter.d.ts +11 -0
  138. package/dist/builtin/workflows/builtin/generate-and-filter.ts +26 -0
  139. package/dist/builtin/workflows/builtin/goal-models.ts +72 -0
  140. package/dist/builtin/workflows/builtin/goal-runner.ts +2 -64
  141. package/dist/builtin/workflows/builtin/index.d.ts +44 -0
  142. package/dist/builtin/workflows/builtin/index.ts +6 -0
  143. package/dist/builtin/workflows/builtin/loop-until-done-prompts.ts +79 -0
  144. package/dist/builtin/workflows/builtin/loop-until-done-runner.ts +189 -0
  145. package/dist/builtin/workflows/builtin/loop-until-done.d.ts +34 -0
  146. package/dist/builtin/workflows/builtin/loop-until-done.ts +31 -0
  147. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +6 -1
  148. package/dist/builtin/workflows/builtin/pattern-artifact-root.ts +28 -0
  149. package/dist/builtin/workflows/builtin/ralph-models.ts +26 -5
  150. package/dist/builtin/workflows/builtin/ralph-runner.ts +1 -0
  151. package/dist/builtin/workflows/builtin/tournament-prompts.ts +79 -0
  152. package/dist/builtin/workflows/builtin/tournament-runner.ts +188 -0
  153. package/dist/builtin/workflows/builtin/tournament.d.ts +33 -0
  154. package/dist/builtin/workflows/builtin/tournament.ts +34 -0
  155. package/dist/builtin/workflows/package.json +2 -2
  156. package/dist/builtin/workflows/src/authoring.d.ts +2 -6
  157. package/dist/builtin/workflows/src/durable/backend.ts +163 -120
  158. package/dist/builtin/workflows/src/durable/completed-catalog.ts +37 -64
  159. package/dist/builtin/workflows/src/durable/completed-inspection.ts +4 -72
  160. package/dist/builtin/workflows/src/durable/dbos-backend.ts +242 -195
  161. package/dist/builtin/workflows/src/durable/dbos-embedded-postgres.ts +207 -0
  162. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +42 -42
  163. package/dist/builtin/workflows/src/durable/dbos-lifecycle.ts +155 -0
  164. package/dist/builtin/workflows/src/durable/dbos-local-postgres.ts +126 -0
  165. package/dist/builtin/workflows/src/durable/dbos-metadata.ts +105 -58
  166. package/dist/builtin/workflows/src/durable/dbos-prompt-reservations.ts +320 -0
  167. package/dist/builtin/workflows/src/durable/dbos-sdk-handle.ts +161 -0
  168. package/dist/builtin/workflows/src/durable/dbos-status-transition.ts +62 -0
  169. package/dist/builtin/workflows/src/durable/dbos-tombstone.ts +2 -2
  170. package/dist/builtin/workflows/src/durable/durable-hash.ts +20 -0
  171. package/dist/builtin/workflows/src/durable/factory.ts +23 -83
  172. package/dist/builtin/workflows/src/durable/format-version.ts +4 -10
  173. package/dist/builtin/workflows/src/durable/index.ts +16 -20
  174. package/dist/builtin/workflows/src/durable/local-command.ts +63 -0
  175. package/dist/builtin/workflows/src/durable/prompt-reservation-state.ts +177 -0
  176. package/dist/builtin/workflows/src/durable/prompt-reservations.ts +36 -0
  177. package/dist/builtin/workflows/src/durable/resume-catalog.ts +2 -200
  178. package/dist/builtin/workflows/src/durable/resume-eligibility.ts +42 -2
  179. package/dist/builtin/workflows/src/durable/resume-runtime.ts +121 -118
  180. package/dist/builtin/workflows/src/durable/retention-policy.ts +42 -0
  181. package/dist/builtin/workflows/src/durable/run-timing.ts +98 -0
  182. package/dist/builtin/workflows/src/durable/scoped-backend.ts +62 -14
  183. package/dist/builtin/workflows/src/durable/stage-primitive.ts +15 -2
  184. package/dist/builtin/workflows/src/durable/tool-primitive.ts +11 -7
  185. package/dist/builtin/workflows/src/durable/types.ts +25 -18
  186. package/dist/builtin/workflows/src/durable/ui-primitive.ts +117 -29
  187. package/dist/builtin/workflows/src/durable/workflow-status-transition.ts +30 -0
  188. package/dist/builtin/workflows/src/engine/primitives/parallel.ts +20 -5
  189. package/dist/builtin/workflows/src/engine/primitives/task.ts +3 -2
  190. package/dist/builtin/workflows/src/engine/primitives/ui.ts +6 -3
  191. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +14 -22
  192. package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +14 -14
  193. package/dist/builtin/workflows/src/engine/run.ts +35 -37
  194. package/dist/builtin/workflows/src/engine/runtime.ts +3 -0
  195. package/dist/builtin/workflows/src/engine/workflow-activity.ts +9 -0
  196. package/dist/builtin/workflows/src/extension/completed-stage-intercom-ask.ts +155 -0
  197. package/dist/builtin/workflows/src/extension/config-file-loader.ts +13 -0
  198. package/dist/builtin/workflows/src/extension/config-loader.ts +20 -0
  199. package/dist/builtin/workflows/src/extension/dispatcher.ts +56 -17
  200. package/dist/builtin/workflows/src/extension/extension-factory.ts +13 -10
  201. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +37 -59
  202. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +16 -18
  203. package/dist/builtin/workflows/src/extension/lifecycle-notification-delivery.ts +83 -0
  204. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +80 -41
  205. package/dist/builtin/workflows/src/extension/postmortem-deps.ts +73 -0
  206. package/dist/builtin/workflows/src/extension/public-types.ts +11 -51
  207. package/dist/builtin/workflows/src/extension/render-call.ts +3 -9
  208. package/dist/builtin/workflows/src/extension/render-result.ts +22 -7
  209. package/dist/builtin/workflows/src/extension/runtime-active-block-claim.ts +78 -0
  210. package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +50 -29
  211. package/dist/builtin/workflows/src/extension/runtime.ts +70 -219
  212. package/dist/builtin/workflows/src/extension/ui-surface.ts +107 -3
  213. package/dist/builtin/workflows/src/extension/wiring.ts +76 -7
  214. package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +10 -5
  215. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +27 -5
  216. package/dist/builtin/workflows/src/extension/workflow-durable-resume-command.ts +49 -19
  217. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +8 -8
  218. package/dist/builtin/workflows/src/extension/workflow-resume-picker-rows.ts +81 -0
  219. package/dist/builtin/workflows/src/extension/workflow-resume-shadow.ts +55 -0
  220. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +193 -145
  221. package/dist/builtin/workflows/src/extension/workflow-schema.ts +9 -133
  222. package/dist/builtin/workflows/src/extension/workflow-status-summary.ts +189 -0
  223. package/dist/builtin/workflows/src/extension/workflow-targets.ts +1 -1
  224. package/dist/builtin/workflows/src/extension/workflow-tool-content.ts +78 -3
  225. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +185 -89
  226. package/dist/builtin/workflows/src/extension/workflow-tool-send.ts +92 -11
  227. package/dist/builtin/workflows/src/extension/workflow-tool.ts +18 -24
  228. package/dist/builtin/workflows/src/runs/background/durable-resume-transition.ts +63 -0
  229. package/dist/builtin/workflows/src/runs/background/quit.ts +139 -29
  230. package/dist/builtin/workflows/src/runs/background/resume-acknowledgements.ts +97 -0
  231. package/dist/builtin/workflows/src/runs/background/run-inspect.ts +111 -0
  232. package/dist/builtin/workflows/src/runs/background/runner.ts +46 -17
  233. package/dist/builtin/workflows/src/runs/background/startup-admission.ts +77 -0
  234. package/dist/builtin/workflows/src/runs/background/status.ts +133 -224
  235. package/dist/builtin/workflows/src/runs/background/workflow-lifecycle-aggregate.ts +44 -0
  236. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +57 -256
  237. package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +7 -4
  238. package/dist/builtin/workflows/src/runs/foreground/executor-lifecycle.ts +12 -1
  239. package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +39 -0
  240. package/dist/builtin/workflows/src/runs/foreground/executor-queued-user-message.ts +75 -0
  241. package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +44 -12
  242. package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +63 -12
  243. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +30 -4
  244. package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +3 -0
  245. package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +4 -1
  246. package/dist/builtin/workflows/src/runs/foreground/executor-task-prompts.ts +0 -67
  247. package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +6 -0
  248. package/dist/builtin/workflows/src/runs/foreground/executor.ts +0 -1
  249. package/dist/builtin/workflows/src/runs/foreground/postmortem-stage-chat.ts +169 -0
  250. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +38 -1
  251. package/dist/builtin/workflows/src/runs/foreground/stage-runner-candidate.ts +21 -0
  252. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +21 -3
  253. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +85 -84
  254. package/dist/builtin/workflows/src/runs/foreground/stage-runner-message-admission.ts +195 -0
  255. package/dist/builtin/workflows/src/runs/foreground/stage-runner-options.ts +12 -5
  256. package/dist/builtin/workflows/src/runs/foreground/stage-runner-replacement.ts +42 -0
  257. package/dist/builtin/workflows/src/runs/foreground/stage-runner-send-user-message.ts +100 -8
  258. package/dist/builtin/workflows/src/runs/foreground/stage-runner-session-options.ts +51 -0
  259. package/dist/builtin/workflows/src/runs/foreground/stage-runner-session.ts +19 -0
  260. package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +28 -2
  261. package/dist/builtin/workflows/src/runs/shared/prompt-callsite.ts +4 -6
  262. package/dist/builtin/workflows/src/runs/shared/worktree-git-runner.ts +89 -0
  263. package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +29 -133
  264. package/dist/builtin/workflows/src/runs/shared/worktree-post-create.ts +130 -0
  265. package/dist/builtin/workflows/src/runs/shared/worktree-root.ts +84 -0
  266. package/dist/builtin/workflows/src/runs/shared/worktree-setup.ts +77 -63
  267. package/dist/builtin/workflows/src/runs/shared/worktree-types.ts +4 -0
  268. package/dist/builtin/workflows/src/sdk-surface.ts +1 -1
  269. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +29 -22
  270. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +26 -24
  271. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +5 -0
  272. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +5 -0
  273. package/dist/builtin/workflows/src/shared/intercom-group.ts +51 -0
  274. package/dist/builtin/workflows/src/shared/persistence-restore-helpers.ts +6 -0
  275. package/dist/builtin/workflows/src/shared/persistence-restore.ts +4 -0
  276. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +3 -0
  277. package/dist/builtin/workflows/src/shared/prompt-callsite-context.ts +13 -0
  278. package/dist/builtin/workflows/src/shared/returned-run-status.ts +2 -1
  279. package/dist/builtin/workflows/src/shared/session-transcript.ts +74 -0
  280. package/dist/builtin/workflows/src/shared/store-stage-methods.ts +1 -0
  281. package/dist/builtin/workflows/src/shared/store-types.ts +8 -0
  282. package/dist/builtin/workflows/src/shared/timing.ts +4 -1
  283. package/dist/builtin/workflows/src/shared/types.ts +2 -6
  284. package/dist/builtin/workflows/src/tui/chat-surface-message.ts +2 -42
  285. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +2 -2
  286. package/dist/builtin/workflows/src/tui/graph-view-constants.ts +7 -3
  287. package/dist/builtin/workflows/src/tui/graph-view-input.ts +29 -67
  288. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +15 -10
  289. package/dist/builtin/workflows/src/tui/graph-view-state.ts +0 -2
  290. package/dist/builtin/workflows/src/tui/graph-view-types.ts +3 -9
  291. package/dist/builtin/workflows/src/tui/host-input-form.ts +62 -0
  292. package/dist/builtin/workflows/src/tui/mouse-input.ts +63 -0
  293. package/dist/builtin/workflows/src/tui/node-card.ts +1 -0
  294. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +67 -42
  295. package/dist/builtin/workflows/src/tui/overlay-terminal-modes.ts +49 -0
  296. package/dist/builtin/workflows/src/tui/session-overlays.ts +3 -104
  297. package/dist/builtin/workflows/src/tui/session-picker.ts +3 -12
  298. package/dist/builtin/workflows/src/tui/stage-chat-composer-drafts.ts +19 -0
  299. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +30 -10
  300. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +19 -9
  301. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +25 -38
  302. package/dist/builtin/workflows/src/tui/stage-chat-view-render-helpers.ts +1 -1
  303. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +7 -6
  304. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +7 -1
  305. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +3 -1
  306. package/dist/builtin/workflows/src/tui/store-widget-installer.ts +19 -20
  307. package/dist/builtin/workflows/src/tui/switcher.ts +4 -4
  308. package/dist/builtin/workflows/src/tui/widget.ts +46 -33
  309. package/dist/builtin/workflows/src/tui/workflow-attach-pane-handle.ts +26 -0
  310. package/dist/builtin/workflows/src/tui/workflow-attach-pane-types.ts +14 -2
  311. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +26 -27
  312. package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +208 -69
  313. package/dist/bun/cli.js +3 -0
  314. package/dist/bun/cli.js.map +1 -1
  315. package/dist/cli/session-picker.d.ts.map +1 -1
  316. package/dist/cli/session-picker.js +3 -0
  317. package/dist/cli/session-picker.js.map +1 -1
  318. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  319. package/dist/core/agent-session-auto-compaction.js +19 -2
  320. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  321. package/dist/core/agent-session-compaction.js +2 -2
  322. package/dist/core/agent-session-compaction.js.map +1 -1
  323. package/dist/core/agent-session-events.d.ts.map +1 -1
  324. package/dist/core/agent-session-events.js +5 -3
  325. package/dist/core/agent-session-events.js.map +1 -1
  326. package/dist/core/agent-session-export.js +1 -1
  327. package/dist/core/agent-session-export.js.map +1 -1
  328. package/dist/core/agent-session-extension-bindings.d.ts +2 -4
  329. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  330. package/dist/core/agent-session-extension-bindings.js +9 -2
  331. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  332. package/dist/core/agent-session-message-queue.d.ts +6 -0
  333. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  334. package/dist/core/agent-session-message-queue.js +107 -36
  335. package/dist/core/agent-session-message-queue.js.map +1 -1
  336. package/dist/core/agent-session-methods.d.ts +18 -7
  337. package/dist/core/agent-session-methods.d.ts.map +1 -1
  338. package/dist/core/agent-session-methods.js.map +1 -1
  339. package/dist/core/agent-session-models.d.ts +3 -1
  340. package/dist/core/agent-session-models.d.ts.map +1 -1
  341. package/dist/core/agent-session-models.js +1 -1
  342. package/dist/core/agent-session-models.js.map +1 -1
  343. package/dist/core/agent-session-post-tool-compaction.d.ts +16 -0
  344. package/dist/core/agent-session-post-tool-compaction.d.ts.map +1 -0
  345. package/dist/core/agent-session-post-tool-compaction.js +113 -0
  346. package/dist/core/agent-session-post-tool-compaction.js.map +1 -0
  347. package/dist/core/agent-session-prompt.d.ts +12 -1
  348. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  349. package/dist/core/agent-session-prompt.js +22 -5
  350. package/dist/core/agent-session-prompt.js.map +1 -1
  351. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  352. package/dist/core/agent-session-runtime.js +3 -0
  353. package/dist/core/agent-session-runtime.js.map +1 -1
  354. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  355. package/dist/core/agent-session-tool-hooks.js +21 -0
  356. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  357. package/dist/core/agent-session-tree.d.ts.map +1 -1
  358. package/dist/core/agent-session-tree.js +2 -1
  359. package/dist/core/agent-session-tree.js.map +1 -1
  360. package/dist/core/agent-session-types.d.ts +7 -0
  361. package/dist/core/agent-session-types.d.ts.map +1 -1
  362. package/dist/core/agent-session-types.js.map +1 -1
  363. package/dist/core/agent-session.d.ts +6 -0
  364. package/dist/core/agent-session.d.ts.map +1 -1
  365. package/dist/core/agent-session.js +18 -1
  366. package/dist/core/agent-session.js.map +1 -1
  367. package/dist/core/async/job-manager.d.ts +1 -0
  368. package/dist/core/async/job-manager.d.ts.map +1 -1
  369. package/dist/core/async/job-manager.js +29 -5
  370. package/dist/core/async/job-manager.js.map +1 -1
  371. package/dist/core/async/session-manager.d.ts +2 -4
  372. package/dist/core/async/session-manager.d.ts.map +1 -1
  373. package/dist/core/async/session-manager.js +5 -32
  374. package/dist/core/async/session-manager.js.map +1 -1
  375. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  376. package/dist/core/atomic-guide-command.js +2 -0
  377. package/dist/core/atomic-guide-command.js.map +1 -1
  378. package/dist/core/auth-storage.d.ts +20 -10
  379. package/dist/core/auth-storage.d.ts.map +1 -1
  380. package/dist/core/auth-storage.js +151 -92
  381. package/dist/core/auth-storage.js.map +1 -1
  382. package/dist/core/callback-activity.d.ts +27 -0
  383. package/dist/core/callback-activity.d.ts.map +1 -0
  384. package/dist/core/callback-activity.js +44 -0
  385. package/dist/core/callback-activity.js.map +1 -0
  386. package/dist/core/compaction/branch-summarization.d.ts +4 -1
  387. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  388. package/dist/core/compaction/branch-summarization.js +4 -3
  389. package/dist/core/compaction/branch-summarization.js.map +1 -1
  390. package/dist/core/compaction/compaction-boundary.d.ts +1 -1
  391. package/dist/core/compaction/compaction-boundary.d.ts.map +1 -1
  392. package/dist/core/compaction/compaction-boundary.js +10 -23
  393. package/dist/core/compaction/compaction-boundary.js.map +1 -1
  394. package/dist/core/compaction/compaction-runner.d.ts +4 -1
  395. package/dist/core/compaction/compaction-runner.d.ts.map +1 -1
  396. package/dist/core/compaction/compaction-runner.js +1 -1
  397. package/dist/core/compaction/compaction-runner.js.map +1 -1
  398. package/dist/core/compaction/compaction-types.d.ts +3 -2
  399. package/dist/core/compaction/compaction-types.d.ts.map +1 -1
  400. package/dist/core/compaction/compaction-types.js.map +1 -1
  401. package/dist/core/compaction/compaction.d.ts +6 -6
  402. package/dist/core/compaction/compaction.d.ts.map +1 -1
  403. package/dist/core/compaction/compaction.js +12 -9
  404. package/dist/core/compaction/compaction.js.map +1 -1
  405. package/dist/core/compaction/index.d.ts +1 -0
  406. package/dist/core/compaction/index.d.ts.map +1 -1
  407. package/dist/core/compaction/index.js +1 -0
  408. package/dist/core/compaction/index.js.map +1 -1
  409. package/dist/core/compaction/range-planner-diagnostics.d.ts +101 -0
  410. package/dist/core/compaction/range-planner-diagnostics.d.ts.map +1 -0
  411. package/dist/core/compaction/range-planner-diagnostics.js +116 -0
  412. package/dist/core/compaction/range-planner-diagnostics.js.map +1 -0
  413. package/dist/core/compaction/range-planner.d.ts +13 -3
  414. package/dist/core/compaction/range-planner.d.ts.map +1 -1
  415. package/dist/core/compaction/range-planner.js +117 -68
  416. package/dist/core/compaction/range-planner.js.map +1 -1
  417. package/dist/core/compaction/truncated-range-recovery.d.ts +47 -0
  418. package/dist/core/compaction/truncated-range-recovery.d.ts.map +1 -0
  419. package/dist/core/compaction/truncated-range-recovery.js +112 -0
  420. package/dist/core/compaction/truncated-range-recovery.js.map +1 -0
  421. package/dist/core/extensions/api-types.d.ts +2 -2
  422. package/dist/core/extensions/api-types.d.ts.map +1 -1
  423. package/dist/core/extensions/api-types.js.map +1 -1
  424. package/dist/core/extensions/context-types.d.ts +23 -1
  425. package/dist/core/extensions/context-types.d.ts.map +1 -1
  426. package/dist/core/extensions/context-types.js.map +1 -1
  427. package/dist/core/extensions/index.d.ts +1 -1
  428. package/dist/core/extensions/index.d.ts.map +1 -1
  429. package/dist/core/extensions/index.js.map +1 -1
  430. package/dist/core/extensions/loader-api.js +2 -2
  431. package/dist/core/extensions/loader-api.js.map +1 -1
  432. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  433. package/dist/core/extensions/loader-core.js +8 -1
  434. package/dist/core/extensions/loader-core.js.map +1 -1
  435. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  436. package/dist/core/extensions/loader-virtual-modules.js +9 -6
  437. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  438. package/dist/core/extensions/message-types.d.ts +17 -0
  439. package/dist/core/extensions/message-types.d.ts.map +1 -1
  440. package/dist/core/extensions/message-types.js.map +1 -1
  441. package/dist/core/extensions/provider-types.d.ts +3 -0
  442. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  443. package/dist/core/extensions/provider-types.js.map +1 -1
  444. package/dist/core/extensions/runner-events.d.ts.map +1 -1
  445. package/dist/core/extensions/runner-events.js +11 -10
  446. package/dist/core/extensions/runner-events.js.map +1 -1
  447. package/dist/core/extensions/runtime-types.d.ts +2 -2
  448. package/dist/core/extensions/runtime-types.d.ts.map +1 -1
  449. package/dist/core/extensions/runtime-types.js.map +1 -1
  450. package/dist/core/extensions/ui-types.d.ts +78 -0
  451. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  452. package/dist/core/extensions/ui-types.js.map +1 -1
  453. package/dist/core/model-registry-auth.d.ts +2 -1
  454. package/dist/core/model-registry-auth.d.ts.map +1 -1
  455. package/dist/core/model-registry-auth.js +25 -6
  456. package/dist/core/model-registry-auth.js.map +1 -1
  457. package/dist/core/model-registry-builtins.d.ts +3 -2
  458. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  459. package/dist/core/model-registry-builtins.js +12 -6
  460. package/dist/core/model-registry-builtins.js.map +1 -1
  461. package/dist/core/model-registry-dynamic.d.ts +1 -0
  462. package/dist/core/model-registry-dynamic.d.ts.map +1 -1
  463. package/dist/core/model-registry-dynamic.js +53 -13
  464. package/dist/core/model-registry-dynamic.js.map +1 -1
  465. package/dist/core/model-registry-loader.d.ts +2 -1
  466. package/dist/core/model-registry-loader.d.ts.map +1 -1
  467. package/dist/core/model-registry-loader.js +2 -2
  468. package/dist/core/model-registry-loader.js.map +1 -1
  469. package/dist/core/model-registry-types.d.ts +10 -3
  470. package/dist/core/model-registry-types.d.ts.map +1 -1
  471. package/dist/core/model-registry-types.js.map +1 -1
  472. package/dist/core/model-registry.d.ts +15 -1
  473. package/dist/core/model-registry.d.ts.map +1 -1
  474. package/dist/core/model-registry.js +214 -30
  475. package/dist/core/model-registry.js.map +1 -1
  476. package/dist/core/models-store.d.ts +25 -0
  477. package/dist/core/models-store.d.ts.map +1 -0
  478. package/dist/core/models-store.js +73 -0
  479. package/dist/core/models-store.js.map +1 -0
  480. package/dist/core/oauth-compat.d.ts +17 -0
  481. package/dist/core/oauth-compat.d.ts.map +1 -0
  482. package/dist/core/oauth-compat.js +2 -0
  483. package/dist/core/oauth-compat.js.map +1 -0
  484. package/dist/core/oauth-provider-bridge.d.ts +40 -0
  485. package/dist/core/oauth-provider-bridge.d.ts.map +1 -0
  486. package/dist/core/oauth-provider-bridge.js +169 -0
  487. package/dist/core/oauth-provider-bridge.js.map +1 -0
  488. package/dist/core/output-guard.d.ts +2 -0
  489. package/dist/core/output-guard.d.ts.map +1 -1
  490. package/dist/core/output-guard.js +14 -0
  491. package/dist/core/output-guard.js.map +1 -1
  492. package/dist/core/remote-catalog-provider.d.ts +5 -0
  493. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  494. package/dist/core/remote-catalog-provider.js +138 -0
  495. package/dist/core/remote-catalog-provider.js.map +1 -0
  496. package/dist/core/sdk.d.ts.map +1 -1
  497. package/dist/core/sdk.js +8 -3
  498. package/dist/core/sdk.js.map +1 -1
  499. package/dist/core/session-manager-core.d.ts +1 -1
  500. package/dist/core/session-manager-core.d.ts.map +1 -1
  501. package/dist/core/session-manager-core.js +1 -1
  502. package/dist/core/session-manager-core.js.map +1 -1
  503. package/dist/core/session-manager-entries.d.ts +1 -1
  504. package/dist/core/session-manager-entries.d.ts.map +1 -1
  505. package/dist/core/session-manager-entries.js.map +1 -1
  506. package/dist/core/session-manager-history.d.ts +2 -2
  507. package/dist/core/session-manager-history.js +2 -2
  508. package/dist/core/session-manager-history.js.map +1 -1
  509. package/dist/core/session-manager-list.d.ts.map +1 -1
  510. package/dist/core/session-manager-list.js +65 -23
  511. package/dist/core/session-manager-list.js.map +1 -1
  512. package/dist/core/session-manager-types.d.ts +3 -2
  513. package/dist/core/session-manager-types.d.ts.map +1 -1
  514. package/dist/core/session-manager-types.js.map +1 -1
  515. package/dist/core/slash-commands.d.ts.map +1 -1
  516. package/dist/core/slash-commands.js +9 -5
  517. package/dist/core/slash-commands.js.map +1 -1
  518. package/dist/core/tools/bash.d.ts.map +1 -1
  519. package/dist/core/tools/bash.js +2 -3
  520. package/dist/core/tools/bash.js.map +1 -1
  521. package/dist/core/tools/find.js +2 -2
  522. package/dist/core/tools/find.js.map +1 -1
  523. package/dist/core/tools/grep.js +2 -2
  524. package/dist/core/tools/grep.js.map +1 -1
  525. package/dist/core/tools/ls.js +2 -2
  526. package/dist/core/tools/ls.js.map +1 -1
  527. package/dist/core/tools/read.d.ts.map +1 -1
  528. package/dist/core/tools/read.js +4 -3
  529. package/dist/core/tools/read.js.map +1 -1
  530. package/dist/core/tools/todos-render.d.ts.map +1 -1
  531. package/dist/core/tools/todos-render.js +3 -2
  532. package/dist/core/tools/todos-render.js.map +1 -1
  533. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  534. package/dist/core/tools/tool-definition-wrapper.js +3 -2
  535. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  536. package/dist/core/tools/write.js +2 -2
  537. package/dist/core/tools/write.js.map +1 -1
  538. package/dist/core/workflow-stage-admission.d.ts +29 -0
  539. package/dist/core/workflow-stage-admission.d.ts.map +1 -0
  540. package/dist/core/workflow-stage-admission.js +81 -0
  541. package/dist/core/workflow-stage-admission.js.map +1 -0
  542. package/dist/index-extensions.d.ts +1 -1
  543. package/dist/index-extensions.d.ts.map +1 -1
  544. package/dist/index-extensions.js.map +1 -1
  545. package/dist/index.d.ts +4 -1
  546. package/dist/index.d.ts.map +1 -1
  547. package/dist/index.js +4 -1
  548. package/dist/index.js.map +1 -1
  549. package/dist/main-types.d.ts +13 -0
  550. package/dist/main-types.d.ts.map +1 -0
  551. package/dist/main-types.js +2 -0
  552. package/dist/main-types.js.map +1 -0
  553. package/dist/main.d.ts +2 -5
  554. package/dist/main.d.ts.map +1 -1
  555. package/dist/main.js +25 -17
  556. package/dist/main.js.map +1 -1
  557. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  558. package/dist/modes/interactive/components/assistant-message.js +17 -12
  559. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  560. package/dist/modes/interactive/components/atomic-banner.d.ts +7 -0
  561. package/dist/modes/interactive/components/atomic-banner.d.ts.map +1 -1
  562. package/dist/modes/interactive/components/atomic-banner.js +20 -0
  563. package/dist/modes/interactive/components/atomic-banner.js.map +1 -1
  564. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  565. package/dist/modes/interactive/components/bash-execution.js +5 -3
  566. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  567. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  568. package/dist/modes/interactive/components/branch-summary-message.js +3 -4
  569. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  570. package/dist/modes/interactive/components/chat-message-renderer.d.ts +4 -0
  571. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  572. package/dist/modes/interactive/components/chat-message-renderer.js +4 -0
  573. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  574. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  575. package/dist/modes/interactive/components/chat-session-host-events.js +79 -8
  576. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  577. package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
  578. package/dist/modes/interactive/components/chat-session-host-rendering.js +4 -2
  579. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  580. package/dist/modes/interactive/components/chat-session-host.d.ts +1 -0
  581. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  582. package/dist/modes/interactive/components/chat-session-host.js +4 -1
  583. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  584. package/dist/modes/interactive/components/compaction-boundary-message.d.ts.map +1 -1
  585. package/dist/modes/interactive/components/compaction-boundary-message.js +3 -4
  586. package/dist/modes/interactive/components/compaction-boundary-message.js.map +1 -1
  587. package/dist/modes/interactive/components/host-input-form-mount.d.ts +14 -0
  588. package/dist/modes/interactive/components/host-input-form-mount.d.ts.map +1 -0
  589. package/dist/modes/interactive/components/host-input-form-mount.js +79 -0
  590. package/dist/modes/interactive/components/host-input-form-mount.js.map +1 -0
  591. package/dist/modes/interactive/components/host-input-form.d.ts +52 -0
  592. package/dist/modes/interactive/components/host-input-form.d.ts.map +1 -0
  593. package/dist/modes/interactive/components/host-input-form.js +278 -0
  594. package/dist/modes/interactive/components/host-input-form.js.map +1 -0
  595. package/dist/modes/interactive/components/host-session-picker.d.ts +46 -0
  596. package/dist/modes/interactive/components/host-session-picker.d.ts.map +1 -0
  597. package/dist/modes/interactive/components/host-session-picker.js +183 -0
  598. package/dist/modes/interactive/components/host-session-picker.js.map +1 -0
  599. package/dist/modes/interactive/components/index.d.ts +1 -1
  600. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  601. package/dist/modes/interactive/components/index.js +1 -1
  602. package/dist/modes/interactive/components/index.js.map +1 -1
  603. package/dist/modes/interactive/components/keybinding-hints.d.ts +2 -0
  604. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  605. package/dist/modes/interactive/components/keybinding-hints.js +12 -0
  606. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  607. package/dist/modes/interactive/components/login-dialog.d.ts +3 -1
  608. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  609. package/dist/modes/interactive/components/login-dialog.js +8 -2
  610. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  611. package/dist/modes/interactive/components/model-selector.d.ts +7 -1
  612. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  613. package/dist/modes/interactive/components/model-selector.js +57 -10
  614. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  615. package/dist/modes/interactive/components/session-selector.d.ts +15 -0
  616. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  617. package/dist/modes/interactive/components/session-selector.js +35 -3
  618. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  619. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  620. package/dist/modes/interactive/components/skill-invocation-message.js +3 -2
  621. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  622. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  623. package/dist/modes/interactive/components/tool-execution.js +9 -0
  624. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  625. package/dist/modes/interactive/interactive-agent-events.js +24 -10
  626. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  627. package/dist/modes/interactive/interactive-auth-login.js +7 -1
  628. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  629. package/dist/modes/interactive/interactive-auth-routing.js +3 -3
  630. package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
  631. package/dist/modes/interactive/interactive-autocomplete.js +49 -0
  632. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  633. package/dist/modes/interactive/interactive-bash-compact.js +2 -0
  634. package/dist/modes/interactive/interactive-bash-compact.js.map +1 -1
  635. package/dist/modes/interactive/interactive-extension-context.js +14 -0
  636. package/dist/modes/interactive/interactive-extension-context.js.map +1 -1
  637. package/dist/modes/interactive/interactive-extension-runtime.js +1 -1
  638. package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
  639. package/dist/modes/interactive/interactive-global-clear.d.ts +13 -0
  640. package/dist/modes/interactive/interactive-global-clear.d.ts.map +1 -0
  641. package/dist/modes/interactive/interactive-global-clear.js +11 -0
  642. package/dist/modes/interactive/interactive-global-clear.js.map +1 -0
  643. package/dist/modes/interactive/interactive-input-handling.js +17 -10
  644. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  645. package/dist/modes/interactive/interactive-mode-base.d.ts +6 -1
  646. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  647. package/dist/modes/interactive/interactive-mode-base.js +25 -2
  648. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  649. package/dist/modes/interactive/interactive-mode-deps.d.ts +4 -3
  650. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  651. package/dist/modes/interactive/interactive-mode-deps.js +2 -2
  652. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  653. package/dist/modes/interactive/interactive-mode-helpers.d.ts +4 -1
  654. package/dist/modes/interactive/interactive-mode-helpers.d.ts.map +1 -1
  655. package/dist/modes/interactive/interactive-mode-helpers.js +14 -1
  656. package/dist/modes/interactive/interactive-mode-helpers.js.map +1 -1
  657. package/dist/modes/interactive/interactive-mode-surface.d.ts +3 -2
  658. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  659. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  660. package/dist/modes/interactive/interactive-mode-types.d.ts +3 -0
  661. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  662. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  663. package/dist/modes/interactive/interactive-model-routing.js +7 -4
  664. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  665. package/dist/modes/interactive/interactive-queueing.js +2 -2
  666. package/dist/modes/interactive/interactive-queueing.js.map +1 -1
  667. package/dist/modes/interactive/interactive-render-chat.js +25 -4
  668. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  669. package/dist/modes/interactive/interactive-session-routing.js +3 -0
  670. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  671. package/dist/modes/interactive/interactive-slash-commands.js +5 -2
  672. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  673. package/dist/modes/interactive/interactive-startup.d.ts +1 -1
  674. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  675. package/dist/modes/interactive/interactive-startup.js +22 -9
  676. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  677. package/dist/modes/interactive/interactive-terminal-title.d.ts +6 -0
  678. package/dist/modes/interactive/interactive-terminal-title.d.ts.map +1 -0
  679. package/dist/modes/interactive/interactive-terminal-title.js +7 -0
  680. package/dist/modes/interactive/interactive-terminal-title.js.map +1 -0
  681. package/dist/modes/interactive-engine/activity-watchdog.d.ts +45 -0
  682. package/dist/modes/interactive-engine/activity-watchdog.d.ts.map +1 -0
  683. package/dist/modes/interactive-engine/activity-watchdog.js +74 -0
  684. package/dist/modes/interactive-engine/activity-watchdog.js.map +1 -0
  685. package/dist/modes/interactive-engine/create-isolated-runtime.d.ts +14 -0
  686. package/dist/modes/interactive-engine/create-isolated-runtime.d.ts.map +1 -0
  687. package/dist/modes/interactive-engine/create-isolated-runtime.js +56 -0
  688. package/dist/modes/interactive-engine/create-isolated-runtime.js.map +1 -0
  689. package/dist/modes/interactive-engine/engine-args.d.ts +10 -0
  690. package/dist/modes/interactive-engine/engine-args.d.ts.map +1 -0
  691. package/dist/modes/interactive-engine/engine-args.js +55 -0
  692. package/dist/modes/interactive-engine/engine-args.js.map +1 -0
  693. package/dist/modes/interactive-engine/engine-child-liveness.d.ts +7 -0
  694. package/dist/modes/interactive-engine/engine-child-liveness.d.ts.map +1 -0
  695. package/dist/modes/interactive-engine/engine-child-liveness.js +50 -0
  696. package/dist/modes/interactive-engine/engine-child-liveness.js.map +1 -0
  697. package/dist/modes/interactive-engine/engine-custom-ui.d.ts +47 -0
  698. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -0
  699. package/dist/modes/interactive-engine/engine-custom-ui.js +276 -0
  700. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -0
  701. package/dist/modes/interactive-engine/engine-input-form.d.ts +13 -0
  702. package/dist/modes/interactive-engine/engine-input-form.d.ts.map +1 -0
  703. package/dist/modes/interactive-engine/engine-input-form.js +49 -0
  704. package/dist/modes/interactive-engine/engine-input-form.js.map +1 -0
  705. package/dist/modes/interactive-engine/engine-monitor.d.ts +18 -0
  706. package/dist/modes/interactive-engine/engine-monitor.d.ts.map +1 -0
  707. package/dist/modes/interactive-engine/engine-monitor.js +63 -0
  708. package/dist/modes/interactive-engine/engine-monitor.js.map +1 -0
  709. package/dist/modes/interactive-engine/engine-render-service.d.ts +17 -0
  710. package/dist/modes/interactive-engine/engine-render-service.d.ts.map +1 -0
  711. package/dist/modes/interactive-engine/engine-render-service.js +150 -0
  712. package/dist/modes/interactive-engine/engine-render-service.js.map +1 -0
  713. package/dist/modes/interactive-engine/engine-session-picker.d.ts +22 -0
  714. package/dist/modes/interactive-engine/engine-session-picker.d.ts.map +1 -0
  715. package/dist/modes/interactive-engine/engine-session-picker.js +106 -0
  716. package/dist/modes/interactive-engine/engine-session-picker.js.map +1 -0
  717. package/dist/modes/interactive-engine/extension-ui-bridge.d.ts +23 -0
  718. package/dist/modes/interactive-engine/extension-ui-bridge.d.ts.map +1 -0
  719. package/dist/modes/interactive-engine/extension-ui-bridge.js +126 -0
  720. package/dist/modes/interactive-engine/extension-ui-bridge.js.map +1 -0
  721. package/dist/modes/interactive-engine/input-form-host.d.ts +15 -0
  722. package/dist/modes/interactive-engine/input-form-host.d.ts.map +1 -0
  723. package/dist/modes/interactive-engine/input-form-host.js +44 -0
  724. package/dist/modes/interactive-engine/input-form-host.js.map +1 -0
  725. package/dist/modes/interactive-engine/isolated-runtime.d.ts +75 -0
  726. package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -0
  727. package/dist/modes/interactive-engine/isolated-runtime.js +448 -0
  728. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -0
  729. package/dist/modes/interactive-engine/protocol.d.ts +184 -0
  730. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -0
  731. package/dist/modes/interactive-engine/protocol.js +254 -0
  732. package/dist/modes/interactive-engine/protocol.js.map +1 -0
  733. package/dist/modes/interactive-engine/remote-command-catalog.d.ts +33 -0
  734. package/dist/modes/interactive-engine/remote-command-catalog.d.ts.map +1 -0
  735. package/dist/modes/interactive-engine/remote-command-catalog.js +51 -0
  736. package/dist/modes/interactive-engine/remote-command-catalog.js.map +1 -0
  737. package/dist/modes/interactive-engine/remote-component.d.ts +16 -0
  738. package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -0
  739. package/dist/modes/interactive-engine/remote-component.js +209 -0
  740. package/dist/modes/interactive-engine/remote-component.js.map +1 -0
  741. package/dist/modes/interactive-engine/remote-frame-clamp.d.ts +25 -0
  742. package/dist/modes/interactive-engine/remote-frame-clamp.d.ts.map +1 -0
  743. package/dist/modes/interactive-engine/remote-frame-clamp.js +43 -0
  744. package/dist/modes/interactive-engine/remote-frame-clamp.js.map +1 -0
  745. package/dist/modes/interactive-engine/remote-renderer.d.ts +59 -0
  746. package/dist/modes/interactive-engine/remote-renderer.d.ts.map +1 -0
  747. package/dist/modes/interactive-engine/remote-renderer.js +123 -0
  748. package/dist/modes/interactive-engine/remote-renderer.js.map +1 -0
  749. package/dist/modes/interactive-engine/session-picker-host.d.ts +25 -0
  750. package/dist/modes/interactive-engine/session-picker-host.d.ts.map +1 -0
  751. package/dist/modes/interactive-engine/session-picker-host.js +75 -0
  752. package/dist/modes/interactive-engine/session-picker-host.js.map +1 -0
  753. package/dist/modes/interactive-engine/terminal-mode-controller.d.ts +43 -0
  754. package/dist/modes/interactive-engine/terminal-mode-controller.d.ts.map +1 -0
  755. package/dist/modes/interactive-engine/terminal-mode-controller.js +109 -0
  756. package/dist/modes/interactive-engine/terminal-mode-controller.js.map +1 -0
  757. package/dist/modes/rpc/bounded-writer.d.ts +27 -0
  758. package/dist/modes/rpc/bounded-writer.d.ts.map +1 -0
  759. package/dist/modes/rpc/bounded-writer.js +103 -0
  760. package/dist/modes/rpc/bounded-writer.js.map +1 -0
  761. package/dist/modes/rpc/jsonl.d.ts +15 -12
  762. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  763. package/dist/modes/rpc/jsonl.js +102 -28
  764. package/dist/modes/rpc/jsonl.js.map +1 -1
  765. package/dist/modes/rpc/rpc-client-api.d.ts +83 -0
  766. package/dist/modes/rpc/rpc-client-api.d.ts.map +1 -0
  767. package/dist/modes/rpc/rpc-client-api.js +64 -0
  768. package/dist/modes/rpc/rpc-client-api.js.map +1 -0
  769. package/dist/modes/rpc/rpc-client-process.d.ts +19 -0
  770. package/dist/modes/rpc/rpc-client-process.d.ts.map +1 -0
  771. package/dist/modes/rpc/rpc-client-process.js +79 -0
  772. package/dist/modes/rpc/rpc-client-process.js.map +1 -0
  773. package/dist/modes/rpc/rpc-client-waits.d.ts +8 -0
  774. package/dist/modes/rpc/rpc-client-waits.d.ts.map +1 -0
  775. package/dist/modes/rpc/rpc-client-waits.js +33 -0
  776. package/dist/modes/rpc/rpc-client-waits.js.map +1 -0
  777. package/dist/modes/rpc/rpc-client.d.ts +48 -124
  778. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  779. package/dist/modes/rpc/rpc-client.js +295 -249
  780. package/dist/modes/rpc/rpc-client.js.map +1 -1
  781. package/dist/modes/rpc/rpc-command-handler.d.ts +5 -1
  782. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  783. package/dist/modes/rpc/rpc-command-handler.js +79 -3
  784. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  785. package/dist/modes/rpc/rpc-event-buffer.d.ts +11 -0
  786. package/dist/modes/rpc/rpc-event-buffer.d.ts.map +1 -0
  787. package/dist/modes/rpc/rpc-event-buffer.js +30 -0
  788. package/dist/modes/rpc/rpc-event-buffer.js.map +1 -0
  789. package/dist/modes/rpc/rpc-extension-ui.d.ts +7 -1
  790. package/dist/modes/rpc/rpc-extension-ui.d.ts.map +1 -1
  791. package/dist/modes/rpc/rpc-extension-ui.js +54 -32
  792. package/dist/modes/rpc/rpc-extension-ui.js.map +1 -1
  793. package/dist/modes/rpc/rpc-input-scheduler.d.ts +16 -0
  794. package/dist/modes/rpc/rpc-input-scheduler.d.ts.map +1 -0
  795. package/dist/modes/rpc/rpc-input-scheduler.js +69 -0
  796. package/dist/modes/rpc/rpc-input-scheduler.js.map +1 -0
  797. package/dist/modes/rpc/rpc-input.d.ts +2 -1
  798. package/dist/modes/rpc/rpc-input.d.ts.map +1 -1
  799. package/dist/modes/rpc/rpc-input.js +4 -9
  800. package/dist/modes/rpc/rpc-input.js.map +1 -1
  801. package/dist/modes/rpc/rpc-keybindings-reload.d.ts +27 -0
  802. package/dist/modes/rpc/rpc-keybindings-reload.d.ts.map +1 -0
  803. package/dist/modes/rpc/rpc-keybindings-reload.js +69 -0
  804. package/dist/modes/rpc/rpc-keybindings-reload.js.map +1 -0
  805. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  806. package/dist/modes/rpc/rpc-mode.js +63 -8
  807. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  808. package/dist/modes/rpc/rpc-output-buffer.d.ts +10 -0
  809. package/dist/modes/rpc/rpc-output-buffer.d.ts.map +1 -0
  810. package/dist/modes/rpc/rpc-output-buffer.js +70 -0
  811. package/dist/modes/rpc/rpc-output-buffer.js.map +1 -0
  812. package/dist/modes/rpc/rpc-session-binding.d.ts +16 -1
  813. package/dist/modes/rpc/rpc-session-binding.d.ts.map +1 -1
  814. package/dist/modes/rpc/rpc-session-binding.js +16 -3
  815. package/dist/modes/rpc/rpc-session-binding.js.map +1 -1
  816. package/dist/modes/rpc/rpc-types.d.ts +109 -0
  817. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  818. package/dist/modes/rpc/rpc-types.js.map +1 -1
  819. package/dist/package-manager-cli-parser.d.ts +2 -0
  820. package/dist/package-manager-cli-parser.d.ts.map +1 -1
  821. package/dist/package-manager-cli-parser.js +24 -5
  822. package/dist/package-manager-cli-parser.js.map +1 -1
  823. package/dist/package-manager-cli.d.ts +7 -0
  824. package/dist/package-manager-cli.d.ts.map +1 -1
  825. package/dist/package-manager-cli.js +65 -1
  826. package/dist/package-manager-cli.js.map +1 -1
  827. package/dist/utils/shell.d.ts +1 -0
  828. package/dist/utils/shell.d.ts.map +1 -1
  829. package/dist/utils/shell.js +46 -0
  830. package/dist/utils/shell.js.map +1 -1
  831. package/docs/changelog.mdx +11 -0
  832. package/docs/compaction.md +53 -17
  833. package/docs/custom-provider.md +24 -5
  834. package/docs/development.md +9 -7
  835. package/docs/docs.json +1 -0
  836. package/docs/extensions.md +30 -16
  837. package/docs/intercom.md +489 -0
  838. package/docs/json.md +1 -1
  839. package/docs/keybindings.md +1 -1
  840. package/docs/packages.md +1 -0
  841. package/docs/quickstart.md +11 -5
  842. package/docs/rpc.md +9 -7
  843. package/docs/sdk.md +6 -0
  844. package/docs/session-format.md +7 -6
  845. package/docs/sessions.md +4 -2
  846. package/docs/settings.md +2 -2
  847. package/docs/subagents.md +7 -2
  848. package/docs/tui.md +61 -2
  849. package/docs/usage.md +6 -5
  850. package/docs/workflows.md +2572 -1379
  851. package/examples/extensions/handoff.ts +1 -1
  852. package/examples/extensions/qna.ts +1 -1
  853. package/examples/extensions/summarize.ts +1 -1
  854. package/npm-shrinkwrap.json +225 -76
  855. package/package.json +7 -6
  856. package/dist/builtin/workflows/src/durable/file-backend.ts +0 -439
  857. package/dist/builtin/workflows/src/durable/file-lock.ts +0 -153
  858. package/dist/builtin/workflows/src/durable/file-state.ts +0 -104
  859. package/dist/builtin/workflows/src/extension/runtime-direct.ts +0 -96
  860. package/dist/builtin/workflows/src/extension/workflow-tool-helpers.ts +0 -66
  861. package/dist/builtin/workflows/src/runs/foreground/executor-direct-output.ts +0 -91
  862. package/dist/builtin/workflows/src/runs/foreground/executor-direct.ts +0 -282
  863. package/dist/builtin/workflows/src/shared/resumable-workflow-notices.ts +0 -43
  864. package/dist/builtin/workflows/src/tui/session-confirm.ts +0 -299
@@ -1,41 +1,25 @@
1
- /**
2
- * Durable workflow backend seam.
3
- *
4
- * This interface abstracts durable checkpoint storage so the workflow engine
5
- * can persist `ctx.*` operation results without coupling to a specific storage
6
- * backend. The default implementation is the zero-infrastructure
7
- * per-workflow file backend, rooted under `~/.atomic/workflow-durable`, so
8
- * cross-session resume works without user setup. {@link InMemoryDurableBackend}
9
- * remains available for isolated tests and explicit custom overrides. The
10
- * {@link DbosDurableBackend} adapter (in dbos-backend.ts) wraps the real
11
- * `@dbos-inc/dbos-sdk` when configured.
12
- *
13
- * Design:
14
- * - Only `ctx.*` blocks write checkpoints (tool, ui, stage).
15
- * - Checkpoints are keyed by (workflowId, kind, checkpointId) for uniqueness.
16
- * - Tool/ui checkpoints also key on a content hash so identical calls are
17
- * idempotent (completed side effects are not repeated on resume).
18
- * - The backend is the checkpoint source of truth; session JSONL entries are
19
- * a discovery cache.
20
- *
21
- * cross-ref: issue #1498 — DBOS integration behind a backend seam.
22
- */
1
+ /** Durable workflow backend seam for DBOS and explicit in-memory tests. */
23
2
 
24
3
  import type { WorkflowSerializableValue } from "../shared/types.js";
25
- import { createHash } from "node:crypto";
26
4
  import { isDurableWorkflowResumable } from "./resume-eligibility.js";
27
- import { DURABLE_FORMAT_VERSION } from "./format-version.js";
5
+ import { inactivePromptReservationToken, PromptReservationState, type PromptReservationToken } from "./prompt-reservation-state.js";
6
+ import { withCurrentStageTopology } from "./dbos-envelope.js";
28
7
  import type {
29
8
  DurableCheckpoint,
30
- DurableCheckpointEntry,
9
+ DurableWorkflowMetadata,
31
10
  DurableToolCheckpoint,
32
11
  DurableUiCheckpoint,
33
12
  DurableStageCheckpoint,
34
13
  DurableWorkflowHandle,
35
14
  DurableWorkflowStatus,
36
15
  ResumableWorkflowEntry,
37
- WorkflowSerializableObject,
38
16
  } from "./types.js";
17
+ export interface DurableWorkflowCatalogEntries {
18
+ readonly resumable: readonly ResumableWorkflowEntry[];
19
+ readonly completed: readonly ResumableWorkflowEntry[];
20
+ readonly completedAll?: readonly ResumableWorkflowEntry[];
21
+ }
22
+ export { durableHash } from "./durable-hash.js";
39
23
 
40
24
  // ---------------------------------------------------------------------------
41
25
  // Backend interface
@@ -49,19 +33,13 @@ export type WorkflowRegistrationInput =
49
33
  Omit<DurableWorkflowHandle, "completedCheckpoints" | "pendingPrompts" | "updatedAt">
50
34
  & Partial<Pick<DurableWorkflowHandle, "completedCheckpoints" | "pendingPrompts" | "updatedAt">>;
51
35
 
52
- /**
53
- * Abstract durable checkpoint store. Implementations:
54
- * - per-workflow file backend JSON-file-backed; default cross-process resume.
55
- * - {@link DbosDurableBackend} — wraps `@dbos-inc/dbos-sdk` + Postgres.
56
- * - {@link InMemoryDurableBackend} process-local; explicit test/custom use.
57
- */
36
+ export type DurableInactiveDeleteResult =
37
+ | { readonly ok: true }
38
+ | { readonly ok: false; readonly reason: "not_found" | "running" };
39
+
40
+ /** DBOS is the sole persistent implementation. In-memory is an explicit test seam. */
58
41
  export interface DurableWorkflowBackend {
59
- /**
60
- * True when the backend persists across processes (file/DBOS). When false
61
- * (in-memory), the engine skips session-cache persistence since there is no
62
- * cross-session state to discover. This keeps in-process test runs from
63
- * polluting session JSONL with discovery cache entries.
64
- */
42
+ /** Whether state survives the current process. */
65
43
  readonly persistent: boolean;
66
44
  /** Register or update a workflow's top-level metadata. */
67
45
  registerWorkflow(handle: WorkflowRegistrationInput): void;
@@ -69,15 +47,11 @@ export interface DurableWorkflowBackend {
69
47
  /** Record a completed checkpoint. Idempotent: same (kind, checkpointId) is a no-op. */
70
48
  recordCheckpoint(checkpoint: DurableCheckpoint): void;
71
49
 
72
- /**
73
- * Optional async checkpoint persistence. DBOS-backed implementations use this
74
- * so ctx.tool/ctx.ui can await durable writes before returning side-effect
75
- * results to workflow code.
76
- */
77
- recordCheckpointAsync?(checkpoint: DurableCheckpoint): Promise<void>;
50
+ /** Persist a checkpoint before exposing its side effect. */
51
+ recordCheckpointAsync(checkpoint: DurableCheckpoint): Promise<void>;
78
52
 
79
- /** Optional: wait for serialized durable writes to settle. */
80
- flush?(): Promise<void>;
53
+ /** Wait for all serialized writes to settle. */
54
+ flush(): Promise<void>;
81
55
 
82
56
  /**
83
57
  * Look up a cached tool output by content hash. Returns `undefined` if the
@@ -109,9 +83,24 @@ export interface DurableWorkflowBackend {
109
83
 
110
84
  /** Get the top-level workflow handle, or `undefined` if not registered. */
111
85
  getWorkflow(workflowId: string): DurableWorkflowHandle | undefined;
86
+ /**
87
+ * Return one authoritative loadable handle snapshot. Persistent backends use
88
+ * this narrow seam to refresh once and classify from that same generation.
89
+ */
90
+ getLoadableWorkflow(workflowId: string): DurableWorkflowHandle | undefined;
112
91
 
113
92
  /** Update workflow status (running/paused/completed/failed/cancelled/blocked). */
114
93
  setWorkflowStatus(workflowId: string, status: DurableWorkflowStatus, pendingPrompts?: number, resumable?: boolean): void;
94
+ /** Atomically update status only when the authoritative status is expected. */
95
+ transitionWorkflowStatus(
96
+ workflowId: string,
97
+ expectedStatuses: readonly DurableWorkflowStatus[],
98
+ status: DurableWorkflowStatus,
99
+ pendingPrompts?: number,
100
+ resumable?: boolean,
101
+ ): Promise<boolean>;
102
+ /** Atomically adjust unresolved UI prompt count, clamped at zero. */
103
+ adjustPendingPrompts(workflowId: string, delta: number): void;
115
104
 
116
105
  /**
117
106
  * List resumable root workflows: running/paused runs with progress and
@@ -120,12 +109,16 @@ export interface DurableWorkflowBackend {
120
109
  listResumableWorkflows(): readonly ResumableWorkflowEntry[];
121
110
  /** List successful completed root workflows with durable checkpoint progress. */
122
111
  listCompletedWorkflows(): readonly ResumableWorkflowEntry[];
112
+ /** Current DBOS-backed resumable and completed catalog. */
113
+ prepareWorkflowCatalog(): Promise<DurableWorkflowCatalogEntries>;
123
114
 
124
- /** Export a session-cache entry for the given workflow (for JSONL persistence). */
125
- toCacheEntry(workflowId: string): DurableCheckpointEntry | undefined;
115
+ /** Shape the current DBOS metadata payload. */
116
+ toMetadata(workflowId: string): Omit<DurableWorkflowMetadata, "promptReservationEpoch"> | undefined;
126
117
 
127
118
  /** Permanently remove one root workflow and its durable checkpoints. */
128
119
  deleteWorkflow(workflowId: string): Promise<void>;
120
+ /** Atomically delete only when authoritative state is not currently running. */
121
+ deleteWorkflowIfInactive(workflowId: string): Promise<DurableInactiveDeleteResult>;
129
122
 
130
123
  /** Whether a workflow id may be exposed or resumed from live/restored metadata. */
131
124
  isWorkflowLoadable(workflowId: string): boolean;
@@ -133,47 +126,18 @@ export interface DurableWorkflowBackend {
133
126
  /** Clear all state (for tests). */
134
127
  reset(): void;
135
128
 
136
- /**
137
- * Optional: hydrate a single workflow's checkpoints from the persistent
138
- * store (DBOS) into the in-memory mirror. Implementations that do not need
139
- * async hydration (in-memory, file) omit this method.
140
- */
141
- hydrateWorkflow?(workflowId: string): Promise<void>;
142
-
143
- /**
144
- * Optional: hydrate all resumable workflows from the persistent store (DBOS)
145
- * into the in-memory mirror. Called before listing/resuming in a fresh
146
- * process. Implementations that do not need async hydration omit this.
147
- */
148
- hydrateResumableWorkflows?(): Promise<void>;
129
+ /** Hydrate one workflow from persistent storage. */
130
+ hydrateWorkflow(workflowId: string): Promise<void>;
131
+ /** Hydrate all catalog candidates from persistent storage. */
132
+ hydrateResumableWorkflows(): Promise<void>;
133
+ promptReservationScope(workflowId: string): { readonly rootWorkflowId: string; readonly scope: string };
134
+ pendingPromptToken(workflowId: string, reservationId: string): PromptReservationToken | undefined;
135
+ reservePendingPrompt(workflowId: string, reservationId: string): PromptReservationToken;
136
+ releasePendingPrompt(workflowId: string, reservationId: string, token: PromptReservationToken): void;
149
137
  }
150
138
 
151
- // ---------------------------------------------------------------------------
152
- // Hashing helpers
153
- // ---------------------------------------------------------------------------
154
139
 
155
- /**
156
- * Compute a deterministic content digest for a JSON-serializable value.
157
- * Uses canonical JSON stringification (sorted keys) for stability and SHA-256
158
- * for collision resistance. The earlier 32-bit DJB2 hash demonstrably
159
- * collided across distinct tool/stage identities and could cause completed
160
- * side effects to be skipped (or merged) incorrectly on resume.
161
- *
162
- * cross-ref: issue #1498 — collision-resistant durable replay identities.
163
- */
164
- export function durableHash(value: WorkflowSerializableValue | WorkflowSerializableObject): string {
165
- const canonical = canonicalJsonString(value);
166
- const digest = createHash("sha256").update(canonical).digest("hex");
167
- return `h${digest.slice(0, 32)}`;
168
- }
169
140
 
170
- function canonicalJsonString(value: unknown): string {
171
- if (value === null || typeof value !== "object") return JSON.stringify(value);
172
- if (Array.isArray(value)) return `[${value.map(canonicalJsonString).join(",")}]`;
173
- const obj = value as Record<string, unknown>;
174
- const keys = Object.keys(obj).sort();
175
- return `{${keys.map((k) => `${JSON.stringify(k)}:${canonicalJsonString(obj[k])}`).join(",")}}`;
176
- }
177
141
 
178
142
  // ---------------------------------------------------------------------------
179
143
  // In-memory backend
@@ -192,14 +156,11 @@ function checkpointKey(c: DurableCheckpoint): string {
192
156
  return `${c.kind}:${c.checkpointId}`;
193
157
  }
194
158
 
195
- /**
196
- * Process-local durable backend for tests and explicit custom overrides.
197
- * Checkpoints live in memory for the lifetime of the process; the production
198
- * default is the cross-process per-workflow file backend.
199
- */
159
+ /** Process-local current-interface backend for explicit test injection. */
200
160
  export class InMemoryDurableBackend implements DurableWorkflowBackend {
201
- public readonly persistent = false;
161
+ public readonly persistent: boolean = false;
202
162
  private readonly workflows = new Map<string, InMemoryWorkflowRecord>();
163
+ private readonly promptReservations = new Map<string, PromptReservationState>();
203
164
  private readonly deletedWorkflowIds = new Set<string>();
204
165
 
205
166
  registerWorkflow(handle: WorkflowRegistrationInput): void {
@@ -225,31 +186,39 @@ export class InMemoryDurableBackend implements DurableWorkflowBackend {
225
186
  ...(handle.label !== undefined ? { label: handle.label } : {}),
226
187
  ...(handle.rootWorkflowId !== undefined ? { rootWorkflowId: handle.rootWorkflowId } : {}),
227
188
  ...(handle.resumable !== undefined ? { resumable: handle.resumable } : {}),
189
+ ...(handle.ownerExecutorId !== undefined ? { ownerExecutorId: handle.ownerExecutorId } : existing?.handle.ownerExecutorId !== undefined ? { ownerExecutorId: existing.handle.ownerExecutorId } : {}),
228
190
  };
229
191
  if (existing) existing.handle = full;
230
192
  else this.workflows.set(handle.workflowId, { handle: full, checkpoints: new Map(), toolByHash: new Map(), uiByHash: new Map(), stageOutputByReplayKey: new Map(), stageSessionByReplayKey: new Map() });
193
+ if (handle.pendingPrompts !== undefined) this.promptReservations.delete(handle.workflowId);
231
194
  }
232
-
233
195
  recordCheckpoint(checkpoint: DurableCheckpoint): void {
234
- const rec = this.workflows.get(checkpoint.workflowId);
196
+ const currentCheckpoint = withCurrentStageTopology(checkpoint);
197
+ const rec = this.workflows.get(currentCheckpoint.workflowId);
235
198
  if (!rec) return;
236
- const key = checkpointKey(checkpoint);
237
- if (rec.checkpoints.has(key)) return; // idempotent
238
- rec.checkpoints.set(key, checkpoint);
239
- if (checkpoint.kind === "tool") rec.toolByHash.set(checkpoint.argsHash, checkpoint);
240
- else if (checkpoint.kind === "ui") rec.uiByHash.set(checkpoint.promptHash, checkpoint);
199
+ const key = checkpointKey(currentCheckpoint);
200
+ if (rec.checkpoints.has(key)) return;
201
+ rec.checkpoints.set(key, currentCheckpoint);
202
+ if (currentCheckpoint.kind === "tool") rec.toolByHash.set(currentCheckpoint.argsHash, currentCheckpoint);
203
+ else if (currentCheckpoint.kind === "ui") rec.uiByHash.set(currentCheckpoint.promptHash, currentCheckpoint);
241
204
  else {
242
- if ("output" in checkpoint) rec.stageOutputByReplayKey.set(checkpoint.replayKey, checkpoint);
243
- if (checkpoint.sessionId !== undefined || checkpoint.sessionFile !== undefined) {
244
- const existing = rec.stageSessionByReplayKey.get(checkpoint.replayKey);
245
- if (existing === undefined || checkpoint.completedAt >= existing.completedAt) {
246
- rec.stageSessionByReplayKey.set(checkpoint.replayKey, checkpoint);
205
+ if ("output" in currentCheckpoint) rec.stageOutputByReplayKey.set(currentCheckpoint.replayKey, currentCheckpoint);
206
+ if (currentCheckpoint.sessionId !== undefined || currentCheckpoint.sessionFile !== undefined) {
207
+ const existing = rec.stageSessionByReplayKey.get(currentCheckpoint.replayKey);
208
+ if (existing === undefined || currentCheckpoint.completedAt >= existing.completedAt) {
209
+ rec.stageSessionByReplayKey.set(currentCheckpoint.replayKey, currentCheckpoint);
247
210
  }
248
211
  }
249
212
  }
250
- rec.handle = { ...rec.handle, completedCheckpoints: rec.checkpoints.size, updatedAt: checkpoint.completedAt };
213
+ rec.handle = { ...rec.handle, completedCheckpoints: rec.checkpoints.size, updatedAt: currentCheckpoint.completedAt };
214
+ }
215
+
216
+ async recordCheckpointAsync(checkpoint: DurableCheckpoint): Promise<void> {
217
+ this.recordCheckpoint(checkpoint);
251
218
  }
252
219
 
220
+ async flush(): Promise<void> {}
221
+
253
222
  getToolOutput(workflowId: string, argsHash: string): WorkflowSerializableValue | undefined {
254
223
  return this.workflows.get(workflowId)?.toolByHash.get(argsHash)?.output;
255
224
  }
@@ -288,11 +257,79 @@ export class InMemoryDurableBackend implements DurableWorkflowBackend {
288
257
  getWorkflow(workflowId: string): DurableWorkflowHandle | undefined {
289
258
  return this.workflows.get(workflowId)?.handle;
290
259
  }
260
+ getLoadableWorkflow(workflowId: string): DurableWorkflowHandle | undefined {
261
+ return this.getWorkflow(workflowId);
262
+ }
263
+
264
+ async hydrateWorkflow(_workflowId: string): Promise<void> {}
265
+
266
+ async hydrateResumableWorkflows(): Promise<void> {}
267
+
268
+ async prepareWorkflowCatalog(): Promise<DurableWorkflowCatalogEntries> {
269
+ return { resumable: this.listResumableWorkflows(), completed: this.listCompletedWorkflows() };
270
+ }
291
271
 
292
272
  setWorkflowStatus(workflowId: string, status: DurableWorkflowStatus, pendingPrompts?: number, resumable?: boolean): void {
293
273
  const rec = this.workflows.get(workflowId);
294
274
  if (!rec) return;
295
275
  rec.handle = { ...rec.handle, status, updatedAt: Date.now(), ...(pendingPrompts !== undefined ? { pendingPrompts } : {}), ...(resumable !== undefined ? { resumable } : {}) };
276
+ if (pendingPrompts !== undefined) this.promptReservations.delete(workflowId);
277
+ }
278
+
279
+ async transitionWorkflowStatus(workflowId: string, expected: readonly DurableWorkflowStatus[], status: DurableWorkflowStatus, pendingPrompts?: number, resumable?: boolean): Promise<boolean> {
280
+ const current = this.workflows.get(workflowId)?.handle.status;
281
+ if (current === undefined || !expected.includes(current)) return false;
282
+ this.setWorkflowStatus(workflowId, status, pendingPrompts, resumable);
283
+ return true;
284
+ }
285
+
286
+ adjustPendingPrompts(workflowId: string, delta: number): void {
287
+ const state = this.promptState(workflowId);
288
+ if (state === undefined) return;
289
+ state.adjust(delta);
290
+ this.setPromptCount(workflowId, state.pendingPrompts);
291
+ }
292
+
293
+ promptReservationScope(workflowId: string): { readonly rootWorkflowId: string; readonly scope: string } {
294
+ return { rootWorkflowId: workflowId, scope: "root" };
295
+ }
296
+
297
+ pendingPromptToken(workflowId: string, reservationId: string): PromptReservationToken | undefined {
298
+ const state = this.promptState(workflowId);
299
+ const token = state?.claim(reservationId);
300
+ if (state !== undefined && token !== undefined) this.setPromptCount(workflowId, state.pendingPrompts);
301
+ return token;
302
+ }
303
+
304
+ reservePendingPrompt(workflowId: string, reservationId: string): PromptReservationToken {
305
+ const state = this.promptState(workflowId);
306
+ if (state === undefined) return inactivePromptReservationToken(reservationId);
307
+ const token = state.reserve(reservationId);
308
+ this.setPromptCount(workflowId, state.pendingPrompts);
309
+ return token;
310
+ }
311
+
312
+ releasePendingPrompt(workflowId: string, reservationId: string, token: PromptReservationToken): void {
313
+ const state = this.promptState(workflowId);
314
+ if (state === undefined) return;
315
+ state.release(reservationId, token);
316
+ this.setPromptCount(workflowId, state.pendingPrompts);
317
+ }
318
+
319
+ private promptState(workflowId: string): PromptReservationState | undefined {
320
+ const rec = this.workflows.get(workflowId);
321
+ if (rec === undefined) return undefined;
322
+ let state = this.promptReservations.get(workflowId);
323
+ if (state === undefined) {
324
+ state = new PromptReservationState(rec.handle.pendingPrompts);
325
+ this.promptReservations.set(workflowId, state);
326
+ }
327
+ return state;
328
+ }
329
+
330
+ private setPromptCount(workflowId: string, pendingPrompts: number): void {
331
+ const rec = this.workflows.get(workflowId);
332
+ if (rec !== undefined) rec.handle = { ...rec.handle, pendingPrompts, updatedAt: Date.now() };
296
333
  }
297
334
 
298
335
  listResumableWorkflows(): readonly ResumableWorkflowEntry[] {
@@ -307,19 +344,22 @@ export class InMemoryDurableBackend implements DurableWorkflowBackend {
307
344
  .map((rec) => toResumableEntry(rec.handle));
308
345
  }
309
346
 
310
- toCacheEntry(workflowId: string): DurableCheckpointEntry | undefined {
347
+
348
+ /** Shape the current DBOS metadata payload. */
349
+ toMetadata(workflowId: string): Omit<DurableWorkflowMetadata, "promptReservationEpoch"> | undefined {
311
350
  const rec = this.workflows.get(workflowId);
312
351
  if (!rec) return undefined;
313
352
  const h = rec.handle;
314
353
  return {
315
- formatVersion: DURABLE_FORMAT_VERSION,
316
- type: "workflow.durable.checkpoint",
317
354
  workflowId: h.workflowId,
318
355
  name: h.name,
319
356
  inputs: h.inputs,
320
357
  status: h.status,
358
+ createdAt: h.createdAt,
321
359
  completedCheckpoints: h.completedCheckpoints,
322
360
  pendingPrompts: h.pendingPrompts,
361
+ ...(h.ownerExecutorId !== undefined ? { ownerExecutorId: h.ownerExecutorId } : {}),
362
+ ...(h.sessionFile !== undefined ? { sessionFile: h.sessionFile } : {}),
323
363
  ...(h.label !== undefined ? { label: h.label } : {}),
324
364
  ...(h.rootWorkflowId !== undefined ? { rootWorkflowId: h.rootWorkflowId } : {}),
325
365
  ...(h.resumable !== undefined ? { resumable: h.resumable } : {}),
@@ -327,36 +367,34 @@ export class InMemoryDurableBackend implements DurableWorkflowBackend {
327
367
  ...(h.workflowCwd !== undefined ? { workflowCwd: h.workflowCwd } : {}),
328
368
  ...(h.repositoryRoot !== undefined ? { repositoryRoot: h.repositoryRoot } : {}),
329
369
  ...(h.gitWorktreeRoot !== undefined ? { gitWorktreeRoot: h.gitWorktreeRoot } : {}),
330
- ts: h.updatedAt,
370
+ updatedAt: h.updatedAt,
331
371
  };
332
372
  }
333
373
 
334
374
  async deleteWorkflow(workflowId: string): Promise<void> {
335
375
  this.workflows.delete(workflowId);
376
+ this.promptReservations.delete(workflowId);
336
377
  this.deletedWorkflowIds.add(workflowId);
337
378
  }
338
379
 
380
+ async deleteWorkflowIfInactive(workflowId: string): Promise<DurableInactiveDeleteResult> {
381
+ const handle = this.workflows.get(workflowId)?.handle;
382
+ if (handle === undefined) return { ok: false, reason: "not_found" };
383
+ if (handle.status === "running") return { ok: false, reason: "running" };
384
+ await this.deleteWorkflow(workflowId);
385
+ return { ok: true };
386
+ }
387
+
339
388
  isWorkflowLoadable(workflowId: string): boolean {
340
389
  return !this.deletedWorkflowIds.has(workflowId);
341
390
  }
342
391
 
343
392
  reset(): void {
344
393
  this.workflows.clear();
394
+ this.promptReservations.clear();
345
395
  this.deletedWorkflowIds.clear();
346
396
  }
347
397
 
348
- /** Export all records (for FileDurableBackend serialization or debugging). */
349
- exportAll(): readonly { readonly handle: DurableWorkflowHandle; readonly checkpoints: readonly DurableCheckpoint[] }[] {
350
- return [...this.workflows.values()].map((rec) => ({ handle: rec.handle, checkpoints: [...rec.checkpoints.values()] }));
351
- }
352
-
353
- /** Import records (for FileDurableBackend deserialization). */
354
- importAll(records: readonly { readonly handle: DurableWorkflowHandle; readonly checkpoints: readonly DurableCheckpoint[] }[]): void {
355
- for (const rec of records) {
356
- this.registerWorkflow(rec.handle);
357
- for (const cp of rec.checkpoints) this.recordCheckpoint(cp);
358
- }
359
- }
360
398
  }
361
399
 
362
400
  function isRootWorkflow(handle: DurableWorkflowHandle): boolean {
@@ -371,6 +409,11 @@ function isCompletedHandle(handle: DurableWorkflowHandle): boolean {
371
409
  return handle.status === "completed" && hasResumeProgress(handle);
372
410
  }
373
411
 
412
+ /** Convert a durable workflow handle into a resume-catalog entry. */
413
+ export function resumableEntryFromHandle(handle: DurableWorkflowHandle): ResumableWorkflowEntry {
414
+ return toResumableEntry(handle);
415
+ }
416
+
374
417
  function toResumableEntry(handle: DurableWorkflowHandle): ResumableWorkflowEntry {
375
418
  return {
376
419
  workflowId: handle.workflowId,
@@ -1,11 +1,12 @@
1
- import { readFileSync, statSync } from "node:fs";
2
1
  import type { RunSnapshot, StageSnapshot } from "../shared/store-types.js";
3
2
  import type { WorkflowInputValues } from "../shared/types.js";
3
+ import { isReopenableSessionTranscript } from "../shared/session-transcript.js";
4
4
  import type { DurableWorkflowBackend } from "./backend.js";
5
- import type {
6
- DurableCheckpoint,
7
- DurableStageCheckpoint,
8
- ResumableWorkflowEntry,
5
+ import {
6
+ DURABLE_STAGE_TOPOLOGY_VERSION,
7
+ type DurableCheckpoint,
8
+ type DurableStageCheckpoint,
9
+ type ResumableWorkflowEntry,
9
10
  } from "./types.js";
10
11
  import { resolveDurableEntry } from "./resume-runtime.js";
11
12
 
@@ -15,15 +16,6 @@ export type CompletedWorkflowResolution =
15
16
  | { readonly kind: "not_found" }
16
17
  | { readonly kind: "stale"; readonly entry: ResumableWorkflowEntry };
17
18
 
18
- interface SessionTranscriptEntry {
19
- readonly type?: string;
20
- readonly id?: string;
21
- readonly timestamp?: string;
22
- readonly message?: {
23
- readonly role?: string;
24
- readonly content?: string | object;
25
- };
26
- }
27
19
 
28
20
  interface StageDraft {
29
21
  readonly replayKey: string;
@@ -40,6 +32,7 @@ interface StageDraft {
40
32
  readonly fastMode?: boolean;
41
33
  readonly attemptedModels?: readonly string[];
42
34
  readonly modelAttempts?: DurableStageCheckpoint["modelAttempts"];
35
+ readonly topology?: DurableStageCheckpoint["topology"];
43
36
  }
44
37
 
45
38
  /** Authoritative completed rows. This path is deliberately separate from resumability. */
@@ -67,9 +60,10 @@ export function resolveCompletedWorkflow(
67
60
  if (resolved !== undefined) {
68
61
  if ("kind" in resolved) return { kind: "ambiguous", matches: resolved.matches };
69
62
  const snapshot = completedWorkflowSnapshot(backend, resolved);
70
- return snapshot === undefined
71
- ? { kind: "stale", entry: resolved }
72
- : { kind: "found", entry: resolved, snapshot };
63
+ if (snapshot === undefined) {
64
+ return { kind: "stale", entry: resolved };
65
+ }
66
+ return { kind: "found", entry: resolved, snapshot };
73
67
  }
74
68
 
75
69
  const authoritative = resolveDurableEntry(workflowIdOrPrefix, listCompletedFromBackend(backend));
@@ -109,49 +103,6 @@ function validatedStageTranscript(stage: StageSnapshot): StageSnapshot {
109
103
  return withoutSessionFile;
110
104
  }
111
105
 
112
- function isReopenableSessionTranscript(path: string): boolean {
113
- try {
114
- const stats = statSync(path);
115
- if (!stats.isFile() || stats.size === 0) return false;
116
- const lines = readFileSync(path, "utf8").split("\n").filter((line) => line.trim().length > 0);
117
- if (lines.length < 2) return false;
118
- const entries: SessionTranscriptEntry[] = [];
119
- for (const line of lines) {
120
- const parsed = JSON.parse(line) as object;
121
- if (typeof parsed !== "object" || parsed === null) return false;
122
- entries.push(parsed as SessionTranscriptEntry);
123
- }
124
- const header = entries[0];
125
- return header?.type === "session" && typeof header.id === "string" && entries.some(isUsableContextMessage);
126
- } catch {
127
- return false;
128
- }
129
- }
130
-
131
- function isUsableContextMessage(entry: SessionTranscriptEntry): boolean {
132
- return entry.type === "message"
133
- && typeof entry.id === "string"
134
- && typeof entry.timestamp === "string"
135
- && typeof entry.message?.role === "string"
136
- && hasUsableMessageContent(entry.message.content);
137
- }
138
-
139
- function hasUsableMessageContent(content: string | object | undefined): boolean {
140
- if (typeof content === "string") return content.trim().length > 0;
141
- return Array.isArray(content) && content.some(hasUsableContentBlock);
142
- }
143
-
144
- function hasUsableContentBlock(block: object): boolean {
145
- if (typeof block !== "object" || block === null) return false;
146
- const contentBlock = block as {
147
- readonly text?: string;
148
- readonly thinking?: string;
149
- readonly data?: string;
150
- readonly name?: string;
151
- };
152
- return [contentBlock.text, contentBlock.thinking, contentBlock.data, contentBlock.name]
153
- .some((value) => typeof value === "string" && value.trim().length > 0);
154
- }
155
106
 
156
107
  function stageSnapshotsFromCheckpoints(
157
108
  checkpoints: readonly DurableCheckpoint[],
@@ -165,7 +116,7 @@ function stageSnapshotsFromCheckpoints(
165
116
  }
166
117
  const ordered = [...drafts.values()].sort((a, b) => a.firstCompletedAt - b.firstCompletedAt);
167
118
  if (ordered.length === 0) return [syntheticCheckpointStage(checkpoints.length, fallbackCompletedAt)];
168
- return ordered.map(stageSnapshotFromDraft);
119
+ return stageSnapshotsFromDrafts(ordered);
169
120
  }
170
121
 
171
122
  function mergeStageDraft(
@@ -187,6 +138,7 @@ function mergeStageDraft(
187
138
  ...valueOrExisting("fastMode", checkpoint, existing),
188
139
  ...valueOrExisting("attemptedModels", checkpoint, existing),
189
140
  ...valueOrExisting("modelAttempts", checkpoint, existing),
141
+ ...valueOrExisting("topology", checkpoint, existing),
190
142
  };
191
143
  }
192
144
 
@@ -199,14 +151,35 @@ function valueOrExisting<
199
151
  return existingValue === undefined ? {} : { [key]: existingValue } as Pick<StageDraft, K>;
200
152
  }
201
153
 
202
- function stageSnapshotFromDraft(draft: StageDraft, index: number): StageSnapshot {
154
+ function stageSnapshotsFromDrafts(drafts: readonly StageDraft[]): StageSnapshot[] {
155
+ const reconstructedIds = drafts.map((_, index) => `completed-stage-${index + 1}`);
156
+ const sourceToReconstructed = new Map<string, string>();
157
+ for (let index = 0; index < drafts.length; index += 1) {
158
+ const topology = drafts[index]!.topology;
159
+ if (topology?.version !== DURABLE_STAGE_TOPOLOGY_VERSION
160
+ || sourceToReconstructed.has(topology.stageId)) return [];
161
+ sourceToReconstructed.set(topology.stageId, reconstructedIds[index]!);
162
+ }
163
+ if (drafts.some((draft) => draft.topology!.parentIds.some((parentId) => !sourceToReconstructed.has(parentId)))) return [];
164
+ return drafts.map((draft, index) => stageSnapshotFromDraft(
165
+ draft,
166
+ reconstructedIds[index]!,
167
+ draft.topology!.parentIds.map((parentId) => sourceToReconstructed.get(parentId)!),
168
+ ));
169
+ }
170
+
171
+ function stageSnapshotFromDraft(
172
+ draft: StageDraft,
173
+ id: string,
174
+ parentIds: readonly string[],
175
+ ): StageSnapshot {
203
176
  const startedAt = draft.startedAt ?? draft.firstCompletedAt;
204
177
  const endedAt = draft.endedAt ?? draft.firstCompletedAt;
205
178
  return {
206
- id: `completed-stage-${index + 1}`,
179
+ id,
207
180
  name: draft.name,
208
181
  status: "completed",
209
- parentIds: [],
182
+ parentIds,
210
183
  startedAt,
211
184
  endedAt,
212
185
  durationMs: draft.durationMs ?? Math.max(0, endedAt - startedAt),