@bastani/atomic 0.9.16-alpha.2 → 0.9.16-alpha.3

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 (641) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/builtin/intercom/broker/spawn.ts +22 -2
  3. package/dist/builtin/intercom/index.bundle.mjs +61694 -0
  4. package/dist/builtin/intercom/package.json +3 -3
  5. package/dist/builtin/mcp/index.bundle.mjs +64901 -0
  6. package/dist/builtin/mcp/package.json +2 -2
  7. package/dist/builtin/subagents/package.json +2 -2
  8. package/dist/builtin/subagents/src/extension/index.bundle.mjs +85671 -0
  9. package/dist/builtin/web-access/index.bundle.mjs +67413 -0
  10. package/dist/builtin/web-access/package.json +2 -2
  11. package/dist/builtin/workflows/package.json +3 -3
  12. package/dist/builtin/workflows/src/extension/index.bundle.mjs +76391 -96336
  13. package/dist/builtin/workflows/src/index.bundle.mjs +73244 -0
  14. package/dist/core/builtin-install-layout.d.ts +22 -0
  15. package/dist/core/builtin-install-layout.d.ts.map +1 -0
  16. package/dist/core/builtin-install-layout.js +23 -0
  17. package/dist/core/builtin-install-layout.js.map +1 -0
  18. package/dist/core/builtin-packages.d.ts.map +1 -1
  19. package/dist/core/builtin-packages.js +8 -32
  20. package/dist/core/builtin-packages.js.map +1 -1
  21. package/npm-shrinkwrap.json +32 -32
  22. package/package.json +3 -3
  23. package/dist/builtin/intercom/closed-workflow-stage-message.ts +0 -66
  24. package/dist/builtin/intercom/config.ts +0 -121
  25. package/dist/builtin/intercom/contact-supervisor-tool.ts +0 -328
  26. package/dist/builtin/intercom/foreground-detach-handoff.ts +0 -164
  27. package/dist/builtin/intercom/group.ts +0 -85
  28. package/dist/builtin/intercom/inbound-idle-queue.ts +0 -82
  29. package/dist/builtin/intercom/inbound-message-admission.ts +0 -79
  30. package/dist/builtin/intercom/incoming-message-delivery.ts +0 -49
  31. package/dist/builtin/intercom/index-heavy.ts +0 -539
  32. package/dist/builtin/intercom/index.ts +0 -503
  33. package/dist/builtin/intercom/intercom-test-seams.ts +0 -6
  34. package/dist/builtin/intercom/intercom-tool.ts +0 -602
  35. package/dist/builtin/intercom/intercom-utils.ts +0 -427
  36. package/dist/builtin/intercom/late-stage-message-router.ts +0 -148
  37. package/dist/builtin/intercom/lazy-heavy-proxy.ts +0 -108
  38. package/dist/builtin/intercom/lazy-subagent-ack.ts +0 -25
  39. package/dist/builtin/intercom/lazy-tool-execution.ts +0 -39
  40. package/dist/builtin/intercom/lifecycle-lease.ts +0 -51
  41. package/dist/builtin/intercom/lifecycle.ts +0 -144
  42. package/dist/builtin/intercom/overlay.ts +0 -96
  43. package/dist/builtin/intercom/parent-ask-handoff.ts +0 -72
  44. package/dist/builtin/intercom/reconnect-backoff.ts +0 -6
  45. package/dist/builtin/intercom/reply-routing.ts +0 -17
  46. package/dist/builtin/intercom/reply-tracker.ts +0 -110
  47. package/dist/builtin/intercom/reply-waiter.ts +0 -115
  48. package/dist/builtin/intercom/result-renderers.ts +0 -77
  49. package/dist/builtin/intercom/runtime-group.ts +0 -13
  50. package/dist/builtin/intercom/session-target.ts +0 -54
  51. package/dist/builtin/intercom/source-ownership.ts +0 -31
  52. package/dist/builtin/intercom/stable-delivery-retry.ts +0 -32
  53. package/dist/builtin/intercom/subagent-relay.ts +0 -290
  54. package/dist/builtin/intercom/supervisor-authorization-registry.ts +0 -22
  55. package/dist/builtin/intercom/terminal-ordering-barrier.ts +0 -247
  56. package/dist/builtin/intercom/types.ts +0 -66
  57. package/dist/builtin/intercom/ui/compose.ts +0 -159
  58. package/dist/builtin/intercom/ui/inline-message.ts +0 -78
  59. package/dist/builtin/intercom/ui/session-list.ts +0 -195
  60. package/dist/builtin/intercom/workflow-reply-tracker.ts +0 -19
  61. package/dist/builtin/intercom/workflow-stage-admission.ts +0 -43
  62. package/dist/builtin/intercom/workflow-stage-delivery-failure.ts +0 -77
  63. package/dist/builtin/mcp/agent-dir.ts +0 -30
  64. package/dist/builtin/mcp/apps-cancellation.ts +0 -32
  65. package/dist/builtin/mcp/call-tool-result.ts +0 -9
  66. package/dist/builtin/mcp/caller-wait.ts +0 -50
  67. package/dist/builtin/mcp/cli.js +0 -191
  68. package/dist/builtin/mcp/command-registration.ts +0 -82
  69. package/dist/builtin/mcp/commands.ts +0 -424
  70. package/dist/builtin/mcp/config-write-utils.ts +0 -104
  71. package/dist/builtin/mcp/config.ts +0 -498
  72. package/dist/builtin/mcp/consent-manager.ts +0 -64
  73. package/dist/builtin/mcp/direct-tool-executor.ts +0 -280
  74. package/dist/builtin/mcp/direct-tools.ts +0 -216
  75. package/dist/builtin/mcp/errors.ts +0 -219
  76. package/dist/builtin/mcp/glimpse-ui.ts +0 -81
  77. package/dist/builtin/mcp/host-html-template.ts +0 -426
  78. package/dist/builtin/mcp/index.ts +0 -443
  79. package/dist/builtin/mcp/init.ts +0 -319
  80. package/dist/builtin/mcp/lifecycle.ts +0 -93
  81. package/dist/builtin/mcp/logger.ts +0 -169
  82. package/dist/builtin/mcp/mcp-auth-flow.ts +0 -372
  83. package/dist/builtin/mcp/mcp-auth.ts +0 -297
  84. package/dist/builtin/mcp/mcp-callback-server.ts +0 -306
  85. package/dist/builtin/mcp/mcp-oauth-provider.ts +0 -324
  86. package/dist/builtin/mcp/mcp-panel-renderer.ts +0 -243
  87. package/dist/builtin/mcp/mcp-panel-state.ts +0 -227
  88. package/dist/builtin/mcp/mcp-panel-types.ts +0 -86
  89. package/dist/builtin/mcp/mcp-panel.ts +0 -393
  90. package/dist/builtin/mcp/mcp-setup-panel.ts +0 -502
  91. package/dist/builtin/mcp/metadata-cache.ts +0 -201
  92. package/dist/builtin/mcp/metadata-hydration.ts +0 -52
  93. package/dist/builtin/mcp/npx-resolver.ts +0 -425
  94. package/dist/builtin/mcp/oauth-handler.ts +0 -60
  95. package/dist/builtin/mcp/onboarding-state.ts +0 -68
  96. package/dist/builtin/mcp/proxy-auth.ts +0 -61
  97. package/dist/builtin/mcp/proxy-call.ts +0 -447
  98. package/dist/builtin/mcp/proxy-connect.ts +0 -78
  99. package/dist/builtin/mcp/proxy-info-modes.ts +0 -409
  100. package/dist/builtin/mcp/proxy-modes.ts +0 -3
  101. package/dist/builtin/mcp/proxy-types.ts +0 -3
  102. package/dist/builtin/mcp/resource-tools.ts +0 -17
  103. package/dist/builtin/mcp/sampling-handler.ts +0 -273
  104. package/dist/builtin/mcp/server-manager.ts +0 -372
  105. package/dist/builtin/mcp/session-cleanup-barrier.ts +0 -43
  106. package/dist/builtin/mcp/startup-warmup.ts +0 -110
  107. package/dist/builtin/mcp/state-lease.ts +0 -12
  108. package/dist/builtin/mcp/state.ts +0 -41
  109. package/dist/builtin/mcp/tool-call-timeout.ts +0 -101
  110. package/dist/builtin/mcp/tool-metadata.ts +0 -152
  111. package/dist/builtin/mcp/tool-registrar.ts +0 -46
  112. package/dist/builtin/mcp/tool-result-renderer.ts +0 -66
  113. package/dist/builtin/mcp/types.ts +0 -445
  114. package/dist/builtin/mcp/ui-resource-handler.ts +0 -145
  115. package/dist/builtin/mcp/ui-server-http.ts +0 -81
  116. package/dist/builtin/mcp/ui-server.ts +0 -499
  117. package/dist/builtin/mcp/ui-session.ts +0 -378
  118. package/dist/builtin/mcp/ui-stream-types.ts +0 -89
  119. package/dist/builtin/mcp/utils.ts +0 -165
  120. package/dist/builtin/subagents/src/agents/agent-discovery.ts +0 -116
  121. package/dist/builtin/subagents/src/agents/agent-loaders.ts +0 -216
  122. package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +0 -221
  123. package/dist/builtin/subagents/src/agents/agent-management.ts +0 -315
  124. package/dist/builtin/subagents/src/agents/agent-overrides.ts +0 -450
  125. package/dist/builtin/subagents/src/agents/agent-paths.ts +0 -69
  126. package/dist/builtin/subagents/src/agents/agent-scope.ts +0 -6
  127. package/dist/builtin/subagents/src/agents/agent-selection.ts +0 -23
  128. package/dist/builtin/subagents/src/agents/agent-serializer.ts +0 -113
  129. package/dist/builtin/subagents/src/agents/agent-types.ts +0 -97
  130. package/dist/builtin/subagents/src/agents/agents.ts +0 -25
  131. package/dist/builtin/subagents/src/agents/frontmatter.ts +0 -74
  132. package/dist/builtin/subagents/src/agents/identity.ts +0 -37
  133. package/dist/builtin/subagents/src/agents/skills-paths.ts +0 -380
  134. package/dist/builtin/subagents/src/agents/skills.ts +0 -398
  135. package/dist/builtin/subagents/src/extension/api-lifecycle.ts +0 -64
  136. package/dist/builtin/subagents/src/extension/config.ts +0 -16
  137. package/dist/builtin/subagents/src/extension/control-notices.ts +0 -91
  138. package/dist/builtin/subagents/src/extension/index.ts +0 -420
  139. package/dist/builtin/subagents/src/extension/notification-content.ts +0 -85
  140. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +0 -11
  141. package/dist/builtin/subagents/src/extension/schemas.ts +0 -208
  142. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +0 -133
  143. package/dist/builtin/subagents/src/extension/tool-description.ts +0 -17
  144. package/dist/builtin/subagents/src/extension/tool-rendering.ts +0 -53
  145. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +0 -376
  146. package/dist/builtin/subagents/src/intercom/result-intercom.ts +0 -246
  147. package/dist/builtin/subagents/src/intercom/supervisor-authorization.ts +0 -30
  148. package/dist/builtin/subagents/src/runs/foreground/completion-notification.ts +0 -42
  149. package/dist/builtin/subagents/src/runs/foreground/detached-cleanup-barrier.ts +0 -26
  150. package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +0 -58
  151. package/dist/builtin/subagents/src/runs/foreground/execution-detach-route.ts +0 -19
  152. package/dist/builtin/subagents/src/runs/foreground/execution-intercom-detach.ts +0 -51
  153. package/dist/builtin/subagents/src/runs/foreground/execution-parent-ask-handoff.ts +0 -78
  154. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +0 -1
  155. package/dist/builtin/subagents/src/runs/foreground/execution-updates.ts +0 -26
  156. package/dist/builtin/subagents/src/runs/foreground/execution-utils.ts +0 -61
  157. package/dist/builtin/subagents/src/runs/foreground/execution.ts +0 -6
  158. package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +0 -512
  159. package/dist/builtin/subagents/src/runs/foreground/notify.ts +0 -355
  160. package/dist/builtin/subagents/src/runs/foreground/parent-ask-output.ts +0 -48
  161. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-burst-display.ts +0 -46
  162. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-burst.ts +0 -403
  163. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +0 -223
  164. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-cwd.ts +0 -6
  165. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +0 -139
  166. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-live-update.ts +0 -11
  167. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +0 -268
  168. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +0 -327
  169. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parent-ask-projection.ts +0 -11
  170. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-runtime.ts +0 -12
  171. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +0 -350
  172. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +0 -246
  173. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +0 -131
  174. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-worktree.ts +0 -102
  175. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +0 -217
  176. package/dist/builtin/subagents/src/runs/inprocess/child-policy.ts +0 -27
  177. package/dist/builtin/subagents/src/runs/inprocess/control-registry.ts +0 -55
  178. package/dist/builtin/subagents/src/runs/inprocess/control-status.ts +0 -72
  179. package/dist/builtin/subagents/src/runs/inprocess/index.ts +0 -27
  180. package/dist/builtin/subagents/src/runs/inprocess/prompt-behavior.ts +0 -168
  181. package/dist/builtin/subagents/src/runs/inprocess/runner.ts +0 -1280
  182. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/temp-cleanup.ts +0 -69
  183. package/dist/builtin/subagents/src/runs/inprocess.ts +0 -1
  184. package/dist/builtin/subagents/src/runs/shared/intercom-group.ts +0 -67
  185. package/dist/builtin/subagents/src/runs/shared/long-running-guard.ts +0 -182
  186. package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +0 -391
  187. package/dist/builtin/subagents/src/runs/shared/model-candidate-filter.ts +0 -56
  188. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +0 -88
  189. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +0 -70
  190. package/dist/builtin/subagents/src/runs/shared/progress-trend.ts +0 -69
  191. package/dist/builtin/subagents/src/runs/shared/run-history.ts +0 -64
  192. package/dist/builtin/subagents/src/runs/shared/single-output.ts +0 -169
  193. package/dist/builtin/subagents/src/runs/shared/subagent-control.ts +0 -234
  194. package/dist/builtin/subagents/src/runs/shared/worktree-post-create.ts +0 -111
  195. package/dist/builtin/subagents/src/runs/shared/worktree-root.ts +0 -67
  196. package/dist/builtin/subagents/src/runs/shared/worktree.ts +0 -552
  197. package/dist/builtin/subagents/src/shared/artifacts.ts +0 -240
  198. package/dist/builtin/subagents/src/shared/atomic-json.ts +0 -16
  199. package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +0 -330
  200. package/dist/builtin/subagents/src/shared/exclusive-file-publication.ts +0 -44
  201. package/dist/builtin/subagents/src/shared/fast-mode.ts +0 -87
  202. package/dist/builtin/subagents/src/shared/file-coalescer.ts +0 -40
  203. package/dist/builtin/subagents/src/shared/fork-context.ts +0 -79
  204. package/dist/builtin/subagents/src/shared/formatters.ts +0 -89
  205. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +0 -83
  206. package/dist/builtin/subagents/src/shared/model-info.ts +0 -101
  207. package/dist/builtin/subagents/src/shared/model-resolution.ts +0 -78
  208. package/dist/builtin/subagents/src/shared/session-identity.ts +0 -10
  209. package/dist/builtin/subagents/src/shared/session-tokens.ts +0 -45
  210. package/dist/builtin/subagents/src/shared/settings.ts +0 -118
  211. package/dist/builtin/subagents/src/shared/status-format.ts +0 -50
  212. package/dist/builtin/subagents/src/shared/types-config.ts +0 -206
  213. package/dist/builtin/subagents/src/shared/types-depth.ts +0 -46
  214. package/dist/builtin/subagents/src/shared/types-foreground-state.ts +0 -48
  215. package/dist/builtin/subagents/src/shared/types-output.ts +0 -63
  216. package/dist/builtin/subagents/src/shared/types-results.ts +0 -259
  217. package/dist/builtin/subagents/src/shared/types-runtime.ts +0 -115
  218. package/dist/builtin/subagents/src/shared/types.ts +0 -13
  219. package/dist/builtin/subagents/src/shared/utils.ts +0 -342
  220. package/dist/builtin/subagents/src/slash/bridge-settlement.ts +0 -87
  221. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +0 -455
  222. package/dist/builtin/subagents/src/slash/slash-bridge.ts +0 -194
  223. package/dist/builtin/subagents/src/slash/slash-commands.ts +0 -5
  224. package/dist/builtin/subagents/src/slash/slash-live-state.ts +0 -259
  225. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +0 -7
  226. package/dist/builtin/subagents/src/tui/render-helpers.ts +0 -90
  227. package/dist/builtin/subagents/src/tui/render-layout.ts +0 -157
  228. package/dist/builtin/subagents/src/tui/render-progress.ts +0 -89
  229. package/dist/builtin/subagents/src/tui/render-result-animation.ts +0 -47
  230. package/dist/builtin/subagents/src/tui/render-result-compact.ts +0 -248
  231. package/dist/builtin/subagents/src/tui/render-result.ts +0 -438
  232. package/dist/builtin/subagents/src/tui/render-stable-output.ts +0 -50
  233. package/dist/builtin/subagents/src/tui/render-status-progress.ts +0 -168
  234. package/dist/builtin/subagents/src/tui/render.ts +0 -23
  235. package/dist/builtin/web-access/activity.ts +0 -101
  236. package/dist/builtin/web-access/chrome-cookies.ts +0 -323
  237. package/dist/builtin/web-access/code-search.ts +0 -107
  238. package/dist/builtin/web-access/config-paths.ts +0 -11
  239. package/dist/builtin/web-access/content-tools.ts +0 -354
  240. package/dist/builtin/web-access/curator-page-assets/script-1.ts +0 -400
  241. package/dist/builtin/web-access/curator-page-assets/script-2.ts +0 -400
  242. package/dist/builtin/web-access/curator-page-assets/script-3.ts +0 -400
  243. package/dist/builtin/web-access/curator-page-assets/script-4.ts +0 -400
  244. package/dist/builtin/web-access/curator-page-assets/script-5.ts +0 -398
  245. package/dist/builtin/web-access/curator-page-assets/styles-1.ts +0 -394
  246. package/dist/builtin/web-access/curator-page-assets/styles-2.ts +0 -394
  247. package/dist/builtin/web-access/curator-page-assets/styles-3.ts +0 -393
  248. package/dist/builtin/web-access/curator-page.ts +0 -196
  249. package/dist/builtin/web-access/curator-server-helpers.ts +0 -115
  250. package/dist/builtin/web-access/curator-server.ts +0 -494
  251. package/dist/builtin/web-access/exa-mcp.ts +0 -218
  252. package/dist/builtin/web-access/exa.ts +0 -317
  253. package/dist/builtin/web-access/extract-frames.ts +0 -229
  254. package/dist/builtin/web-access/extract.ts +0 -500
  255. package/dist/builtin/web-access/flat-string.ts +0 -37
  256. package/dist/builtin/web-access/gemini-api.ts +0 -111
  257. package/dist/builtin/web-access/gemini-search.ts +0 -363
  258. package/dist/builtin/web-access/gemini-url-context.ts +0 -126
  259. package/dist/builtin/web-access/gemini-web-config.ts +0 -53
  260. package/dist/builtin/web-access/gemini-web.ts +0 -397
  261. package/dist/builtin/web-access/github-api.ts +0 -198
  262. package/dist/builtin/web-access/github-config.ts +0 -156
  263. package/dist/builtin/web-access/github-extract.ts +0 -487
  264. package/dist/builtin/web-access/index-heavy.ts +0 -164
  265. package/dist/builtin/web-access/index.ts +0 -401
  266. package/dist/builtin/web-access/lifecycle-lease.ts +0 -38
  267. package/dist/builtin/web-access/pdf-extract.ts +0 -192
  268. package/dist/builtin/web-access/perplexity.ts +0 -194
  269. package/dist/builtin/web-access/result-renderers.ts +0 -366
  270. package/dist/builtin/web-access/rsc-extract.ts +0 -338
  271. package/dist/builtin/web-access/storage.ts +0 -72
  272. package/dist/builtin/web-access/subprocess.ts +0 -102
  273. package/dist/builtin/web-access/summary-review.ts +0 -287
  274. package/dist/builtin/web-access/utils.ts +0 -44
  275. package/dist/builtin/web-access/video-extract.ts +0 -375
  276. package/dist/builtin/web-access/web-search-activity.ts +0 -102
  277. package/dist/builtin/web-access/web-search-browser.ts +0 -124
  278. package/dist/builtin/web-access/web-search-command.ts +0 -242
  279. package/dist/builtin/web-access/web-search-config.ts +0 -157
  280. package/dist/builtin/web-access/web-search-curator.ts +0 -214
  281. package/dist/builtin/web-access/web-search-features.ts +0 -181
  282. package/dist/builtin/web-access/web-search-formatting.ts +0 -117
  283. package/dist/builtin/web-access/web-search-return.ts +0 -143
  284. package/dist/builtin/web-access/web-search-summary.ts +0 -177
  285. package/dist/builtin/web-access/web-search-tool.ts +0 -286
  286. package/dist/builtin/web-access/web-search-types.ts +0 -50
  287. package/dist/builtin/web-access/web-search-workflow.ts +0 -10
  288. package/dist/builtin/web-access/youtube-extract.ts +0 -309
  289. package/dist/builtin/workflows/src/authoring/keep-context.ts +0 -46
  290. package/dist/builtin/workflows/src/authoring/typebox-defaults.d.ts +0 -41
  291. package/dist/builtin/workflows/src/authoring/typebox-defaults.ts +0 -180
  292. package/dist/builtin/workflows/src/authoring/workflow.ts +0 -206
  293. package/dist/builtin/workflows/src/durable/backend.ts +0 -598
  294. package/dist/builtin/workflows/src/durable/boundary-lifecycle.ts +0 -172
  295. package/dist/builtin/workflows/src/durable/boundary-topology.ts +0 -475
  296. package/dist/builtin/workflows/src/durable/child-invocation.ts +0 -14
  297. package/dist/builtin/workflows/src/durable/child-primitive.ts +0 -124
  298. package/dist/builtin/workflows/src/durable/completed-catalog-stage-groups.ts +0 -385
  299. package/dist/builtin/workflows/src/durable/completed-catalog.ts +0 -685
  300. package/dist/builtin/workflows/src/durable/completed-inspection.ts +0 -157
  301. package/dist/builtin/workflows/src/durable/completed-subtree.ts +0 -50
  302. package/dist/builtin/workflows/src/durable/dbos-backend.ts +0 -580
  303. package/dist/builtin/workflows/src/durable/dbos-embedded-postgres-root.ts +0 -681
  304. package/dist/builtin/workflows/src/durable/dbos-embedded-postgres.ts +0 -717
  305. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +0 -516
  306. package/dist/builtin/workflows/src/durable/dbos-lifecycle.ts +0 -208
  307. package/dist/builtin/workflows/src/durable/dbos-local-postgres.ts +0 -166
  308. package/dist/builtin/workflows/src/durable/dbos-metadata.ts +0 -196
  309. package/dist/builtin/workflows/src/durable/dbos-process-owner.ts +0 -87
  310. package/dist/builtin/workflows/src/durable/dbos-prompt-reservations.ts +0 -377
  311. package/dist/builtin/workflows/src/durable/dbos-registration-diagnostics.ts +0 -113
  312. package/dist/builtin/workflows/src/durable/dbos-sdk-handle.ts +0 -182
  313. package/dist/builtin/workflows/src/durable/dbos-status-transition.ts +0 -67
  314. package/dist/builtin/workflows/src/durable/dbos-tombstone.ts +0 -27
  315. package/dist/builtin/workflows/src/durable/durable-hash.ts +0 -18
  316. package/dist/builtin/workflows/src/durable/factory.ts +0 -93
  317. package/dist/builtin/workflows/src/durable/format-version.ts +0 -6
  318. package/dist/builtin/workflows/src/durable/index.ts +0 -82
  319. package/dist/builtin/workflows/src/durable/local-command.ts +0 -135
  320. package/dist/builtin/workflows/src/durable/prompt-reservation-state.ts +0 -184
  321. package/dist/builtin/workflows/src/durable/prompt-reservations.ts +0 -36
  322. package/dist/builtin/workflows/src/durable/resume-catalog.ts +0 -20
  323. package/dist/builtin/workflows/src/durable/resume-eligibility.ts +0 -106
  324. package/dist/builtin/workflows/src/durable/resume-runtime.ts +0 -344
  325. package/dist/builtin/workflows/src/durable/retention-policy.ts +0 -43
  326. package/dist/builtin/workflows/src/durable/run-timing.ts +0 -151
  327. package/dist/builtin/workflows/src/durable/scoped-backend.ts +0 -308
  328. package/dist/builtin/workflows/src/durable/stage-primitive.ts +0 -553
  329. package/dist/builtin/workflows/src/durable/stage-topology-validation.ts +0 -247
  330. package/dist/builtin/workflows/src/durable/stage-topology.ts +0 -53
  331. package/dist/builtin/workflows/src/durable/targeted-inspection.ts +0 -110
  332. package/dist/builtin/workflows/src/durable/tool-failure-checkpoint.ts +0 -54
  333. package/dist/builtin/workflows/src/durable/tool-outcome.ts +0 -130
  334. package/dist/builtin/workflows/src/durable/tool-primitive.ts +0 -861
  335. package/dist/builtin/workflows/src/durable/types.ts +0 -343
  336. package/dist/builtin/workflows/src/durable/ui-primitive.ts +0 -263
  337. package/dist/builtin/workflows/src/durable/workflow-child-result.ts +0 -63
  338. package/dist/builtin/workflows/src/durable/workflow-heartbeat-anchor.ts +0 -153
  339. package/dist/builtin/workflows/src/durable/workflow-status-transition.ts +0 -31
  340. package/dist/builtin/workflows/src/engine/graph-inference.ts +0 -100
  341. package/dist/builtin/workflows/src/engine/options.ts +0 -44
  342. package/dist/builtin/workflows/src/engine/primitives/chain.ts +0 -34
  343. package/dist/builtin/workflows/src/engine/primitives/exit.ts +0 -2
  344. package/dist/builtin/workflows/src/engine/primitives/parallel.ts +0 -74
  345. package/dist/builtin/workflows/src/engine/primitives/task.ts +0 -127
  346. package/dist/builtin/workflows/src/engine/primitives/ui.ts +0 -54
  347. package/dist/builtin/workflows/src/engine/primitives/workflow.ts +0 -219
  348. package/dist/builtin/workflows/src/engine/replay.ts +0 -8
  349. package/dist/builtin/workflows/src/engine/run-budget.ts +0 -308
  350. package/dist/builtin/workflows/src/engine/run-durable-admission.ts +0 -50
  351. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +0 -97
  352. package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +0 -65
  353. package/dist/builtin/workflows/src/engine/run-durable-topology.ts +0 -295
  354. package/dist/builtin/workflows/src/engine/run-returned-status.ts +0 -86
  355. package/dist/builtin/workflows/src/engine/run-terminal-event.ts +0 -39
  356. package/dist/builtin/workflows/src/engine/run-terminal-failure.ts +0 -53
  357. package/dist/builtin/workflows/src/engine/run-tool-admission-boundary.ts +0 -99
  358. package/dist/builtin/workflows/src/engine/run-tool-control-registry.ts +0 -187
  359. package/dist/builtin/workflows/src/engine/run-tool-execution-tracker.ts +0 -164
  360. package/dist/builtin/workflows/src/engine/run-tool-node-lifecycle.ts +0 -158
  361. package/dist/builtin/workflows/src/engine/run.ts +0 -841
  362. package/dist/builtin/workflows/src/engine/runtime.ts +0 -220
  363. package/dist/builtin/workflows/src/engine/workflow-activity.ts +0 -13
  364. package/dist/builtin/workflows/src/engine/workflow-tool-abort.ts +0 -92
  365. package/dist/builtin/workflows/src/extension/adopt-session-run-state.ts +0 -20
  366. package/dist/builtin/workflows/src/extension/atomic-stage-session.ts +0 -168
  367. package/dist/builtin/workflows/src/extension/background-ui-adapter.ts +0 -154
  368. package/dist/builtin/workflows/src/extension/companions.ts +0 -210
  369. package/dist/builtin/workflows/src/extension/completed-stage-intercom-ask.ts +0 -167
  370. package/dist/builtin/workflows/src/extension/config-file-loader.ts +0 -185
  371. package/dist/builtin/workflows/src/extension/config-loader.ts +0 -439
  372. package/dist/builtin/workflows/src/extension/discovery-loaders.ts +0 -112
  373. package/dist/builtin/workflows/src/extension/discovery.ts +0 -424
  374. package/dist/builtin/workflows/src/extension/dispatcher.ts +0 -273
  375. package/dist/builtin/workflows/src/extension/extension-factory.ts +0 -133
  376. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +0 -174
  377. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +0 -596
  378. package/dist/builtin/workflows/src/extension/hil-answer-notifications.ts +0 -367
  379. package/dist/builtin/workflows/src/extension/index.ts +0 -42
  380. package/dist/builtin/workflows/src/extension/lifecycle-notification-delivery.ts +0 -83
  381. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +0 -849
  382. package/dist/builtin/workflows/src/extension/mcp.ts +0 -121
  383. package/dist/builtin/workflows/src/extension/postmortem-deps.ts +0 -70
  384. package/dist/builtin/workflows/src/extension/public-types.ts +0 -234
  385. package/dist/builtin/workflows/src/extension/render-call.ts +0 -115
  386. package/dist/builtin/workflows/src/extension/render-component.ts +0 -12
  387. package/dist/builtin/workflows/src/extension/render-result.ts +0 -558
  388. package/dist/builtin/workflows/src/extension/renderers.ts +0 -89
  389. package/dist/builtin/workflows/src/extension/runtime-active-block-claim.ts +0 -78
  390. package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +0 -174
  391. package/dist/builtin/workflows/src/extension/runtime.ts +0 -439
  392. package/dist/builtin/workflows/src/extension/status-writer.ts +0 -182
  393. package/dist/builtin/workflows/src/extension/ui-surface.ts +0 -387
  394. package/dist/builtin/workflows/src/extension/wiring.ts +0 -490
  395. package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +0 -129
  396. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +0 -296
  397. package/dist/builtin/workflows/src/extension/workflow-command-surfaces.ts +0 -114
  398. package/dist/builtin/workflows/src/extension/workflow-command-utils.ts +0 -175
  399. package/dist/builtin/workflows/src/extension/workflow-durable-resume-command.ts +0 -270
  400. package/dist/builtin/workflows/src/extension/workflow-heartbeat-delivery.ts +0 -241
  401. package/dist/builtin/workflows/src/extension/workflow-heartbeat-notice.ts +0 -115
  402. package/dist/builtin/workflows/src/extension/workflow-heartbeat-scheduler.ts +0 -962
  403. package/dist/builtin/workflows/src/extension/workflow-model-catalog.ts +0 -24
  404. package/dist/builtin/workflows/src/extension/workflow-module-loader.ts +0 -162
  405. package/dist/builtin/workflows/src/extension/workflow-policy.ts +0 -13
  406. package/dist/builtin/workflows/src/extension/workflow-ports.ts +0 -45
  407. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +0 -73
  408. package/dist/builtin/workflows/src/extension/workflow-reload-coordinator.ts +0 -66
  409. package/dist/builtin/workflows/src/extension/workflow-reload-report.ts +0 -42
  410. package/dist/builtin/workflows/src/extension/workflow-request-abort.ts +0 -15
  411. package/dist/builtin/workflows/src/extension/workflow-resume-picker-rows.ts +0 -96
  412. package/dist/builtin/workflows/src/extension/workflow-resume-shadow.ts +0 -53
  413. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +0 -562
  414. package/dist/builtin/workflows/src/extension/workflow-schema.ts +0 -192
  415. package/dist/builtin/workflows/src/extension/workflow-stage-results.ts +0 -252
  416. package/dist/builtin/workflows/src/extension/workflow-status-summary.ts +0 -276
  417. package/dist/builtin/workflows/src/extension/workflow-targets.ts +0 -210
  418. package/dist/builtin/workflows/src/extension/workflow-tool-content.ts +0 -265
  419. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +0 -547
  420. package/dist/builtin/workflows/src/extension/workflow-tool-inspection.ts +0 -153
  421. package/dist/builtin/workflows/src/extension/workflow-tool-registration.ts +0 -145
  422. package/dist/builtin/workflows/src/extension/workflow-tool-send.ts +0 -488
  423. package/dist/builtin/workflows/src/extension/workflow-tool.ts +0 -188
  424. package/dist/builtin/workflows/src/index.ts +0 -8
  425. package/dist/builtin/workflows/src/intercom/intercom-bridge.ts +0 -90
  426. package/dist/builtin/workflows/src/intercom/intercom-routing.ts +0 -131
  427. package/dist/builtin/workflows/src/intercom/result-intercom.ts +0 -271
  428. package/dist/builtin/workflows/src/runs/background/cancellation-registry.ts +0 -135
  429. package/dist/builtin/workflows/src/runs/background/durable-resume-transition.ts +0 -63
  430. package/dist/builtin/workflows/src/runs/background/job-tracker.ts +0 -125
  431. package/dist/builtin/workflows/src/runs/background/quit-tool-node.ts +0 -71
  432. package/dist/builtin/workflows/src/runs/background/quit.ts +0 -417
  433. package/dist/builtin/workflows/src/runs/background/resume-acknowledgements.ts +0 -99
  434. package/dist/builtin/workflows/src/runs/background/run-inspect.ts +0 -126
  435. package/dist/builtin/workflows/src/runs/background/runner.ts +0 -185
  436. package/dist/builtin/workflows/src/runs/background/startup-admission.ts +0 -73
  437. package/dist/builtin/workflows/src/runs/background/status.ts +0 -511
  438. package/dist/builtin/workflows/src/runs/background/workflow-lifecycle-aggregate.ts +0 -43
  439. package/dist/builtin/workflows/src/runs/foreground/executor-abort.ts +0 -441
  440. package/dist/builtin/workflows/src/runs/foreground/executor-child-boundary.ts +0 -263
  441. package/dist/builtin/workflows/src/runs/foreground/executor-child-helpers.ts +0 -79
  442. package/dist/builtin/workflows/src/runs/foreground/executor-child-workflow.ts +0 -1
  443. package/dist/builtin/workflows/src/runs/foreground/executor-continuation.ts +0 -207
  444. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +0 -321
  445. package/dist/builtin/workflows/src/runs/foreground/executor-exit-manager.ts +0 -224
  446. package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +0 -403
  447. package/dist/builtin/workflows/src/runs/foreground/executor-inputs.ts +0 -86
  448. package/dist/builtin/workflows/src/runs/foreground/executor-lifecycle.ts +0 -491
  449. package/dist/builtin/workflows/src/runs/foreground/executor-outputs.ts +0 -156
  450. package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +0 -379
  451. package/dist/builtin/workflows/src/runs/foreground/executor-queued-user-message.ts +0 -75
  452. package/dist/builtin/workflows/src/runs/foreground/executor-run-finalizers.ts +0 -144
  453. package/dist/builtin/workflows/src/runs/foreground/executor-run.ts +0 -1
  454. package/dist/builtin/workflows/src/runs/foreground/executor-scheduler.ts +0 -206
  455. package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +0 -434
  456. package/dist/builtin/workflows/src/runs/foreground/executor-stage-context.ts +0 -153
  457. package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +0 -225
  458. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +0 -473
  459. package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +0 -156
  460. package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +0 -72
  461. package/dist/builtin/workflows/src/runs/foreground/executor-task-context.ts +0 -2
  462. package/dist/builtin/workflows/src/runs/foreground/executor-task-prompts.ts +0 -226
  463. package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +0 -186
  464. package/dist/builtin/workflows/src/runs/foreground/executor.ts +0 -25
  465. package/dist/builtin/workflows/src/runs/foreground/postmortem-stage-chat.ts +0 -245
  466. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +0 -466
  467. package/dist/builtin/workflows/src/runs/foreground/stage-delivery-activity.ts +0 -86
  468. package/dist/builtin/workflows/src/runs/foreground/stage-queued-user-messages.ts +0 -95
  469. package/dist/builtin/workflows/src/runs/foreground/stage-runner-candidate.ts +0 -21
  470. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +0 -330
  471. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +0 -1472
  472. package/dist/builtin/workflows/src/runs/foreground/stage-runner-message-admission.ts +0 -196
  473. package/dist/builtin/workflows/src/runs/foreground/stage-runner-messages.ts +0 -177
  474. package/dist/builtin/workflows/src/runs/foreground/stage-runner-options.ts +0 -97
  475. package/dist/builtin/workflows/src/runs/foreground/stage-runner-output.ts +0 -278
  476. package/dist/builtin/workflows/src/runs/foreground/stage-runner-pause.ts +0 -206
  477. package/dist/builtin/workflows/src/runs/foreground/stage-runner-replacement.ts +0 -41
  478. package/dist/builtin/workflows/src/runs/foreground/stage-runner-send-user-message.ts +0 -134
  479. package/dist/builtin/workflows/src/runs/foreground/stage-runner-session-options.ts +0 -38
  480. package/dist/builtin/workflows/src/runs/foreground/stage-runner-session.ts +0 -66
  481. package/dist/builtin/workflows/src/runs/foreground/stage-runner-structured-output.ts +0 -120
  482. package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +0 -211
  483. package/dist/builtin/workflows/src/runs/foreground/stage-runner-unresolved-overflow.ts +0 -42
  484. package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +0 -22
  485. package/dist/builtin/workflows/src/runs/foreground/stage-session-heartbeat.ts +0 -88
  486. package/dist/builtin/workflows/src/runs/foreground/stage-tool-execution-buffer.ts +0 -49
  487. package/dist/builtin/workflows/src/runs/shared/concurrency.ts +0 -76
  488. package/dist/builtin/workflows/src/runs/shared/graph-inference.ts +0 -2
  489. package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +0 -325
  490. package/dist/builtin/workflows/src/runs/shared/model-fallback-failures.ts +0 -19
  491. package/dist/builtin/workflows/src/runs/shared/model-fallback.ts +0 -2
  492. package/dist/builtin/workflows/src/runs/shared/prompt-callsite.ts +0 -96
  493. package/dist/builtin/workflows/src/runs/shared/retry.ts +0 -44
  494. package/dist/builtin/workflows/src/runs/shared/validate-inputs.ts +0 -111
  495. package/dist/builtin/workflows/src/runs/shared/worktree-cache-lifecycle.ts +0 -23
  496. package/dist/builtin/workflows/src/runs/shared/worktree-cwd.ts +0 -116
  497. package/dist/builtin/workflows/src/runs/shared/worktree-diff.ts +0 -172
  498. package/dist/builtin/workflows/src/runs/shared/worktree-generation.ts +0 -57
  499. package/dist/builtin/workflows/src/runs/shared/worktree-git-runner.ts +0 -107
  500. package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +0 -407
  501. package/dist/builtin/workflows/src/runs/shared/worktree-post-create.ts +0 -137
  502. package/dist/builtin/workflows/src/runs/shared/worktree-root.ts +0 -84
  503. package/dist/builtin/workflows/src/runs/shared/worktree-setup.ts +0 -372
  504. package/dist/builtin/workflows/src/runs/shared/worktree-types.ts +0 -102
  505. package/dist/builtin/workflows/src/runs/shared/worktree.ts +0 -21
  506. package/dist/builtin/workflows/src/sdk-surface.ts +0 -70
  507. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +0 -403
  508. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +0 -489
  509. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +0 -327
  510. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +0 -437
  511. package/dist/builtin/workflows/src/shared/budget-meter.ts +0 -34
  512. package/dist/builtin/workflows/src/shared/budget.d.ts +0 -67
  513. package/dist/builtin/workflows/src/shared/budget.ts +0 -127
  514. package/dist/builtin/workflows/src/shared/expanded-workflow-graph.ts +0 -434
  515. package/dist/builtin/workflows/src/shared/flat-string.ts +0 -33
  516. package/dist/builtin/workflows/src/shared/graph-store-snapshot.ts +0 -188
  517. package/dist/builtin/workflows/src/shared/intercom-group.ts +0 -58
  518. package/dist/builtin/workflows/src/shared/persistence-compaction-policy.ts +0 -72
  519. package/dist/builtin/workflows/src/shared/persistence-restore-helpers.ts +0 -613
  520. package/dist/builtin/workflows/src/shared/persistence-restore.ts +0 -306
  521. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +0 -303
  522. package/dist/builtin/workflows/src/shared/prompt-answer.ts +0 -130
  523. package/dist/builtin/workflows/src/shared/prompt-callsite-context.ts +0 -13
  524. package/dist/builtin/workflows/src/shared/render-inputs-schema.ts +0 -161
  525. package/dist/builtin/workflows/src/shared/resume-continuation.ts +0 -2
  526. package/dist/builtin/workflows/src/shared/returned-run-status.ts +0 -164
  527. package/dist/builtin/workflows/src/shared/run-id.ts +0 -36
  528. package/dist/builtin/workflows/src/shared/run-indicator-status.ts +0 -75
  529. package/dist/builtin/workflows/src/shared/run-visibility.ts +0 -9
  530. package/dist/builtin/workflows/src/shared/schema-introspection.ts +0 -111
  531. package/dist/builtin/workflows/src/shared/serializable.ts +0 -118
  532. package/dist/builtin/workflows/src/shared/session-scoped-singleton.ts +0 -98
  533. package/dist/builtin/workflows/src/shared/session-transcript.ts +0 -79
  534. package/dist/builtin/workflows/src/shared/stage-prompt.ts +0 -338
  535. package/dist/builtin/workflows/src/shared/stage-ui-broker.ts +0 -340
  536. package/dist/builtin/workflows/src/shared/store-factory.ts +0 -26
  537. package/dist/builtin/workflows/src/shared/store-internal.ts +0 -252
  538. package/dist/builtin/workflows/src/shared/store-observation.ts +0 -10
  539. package/dist/builtin/workflows/src/shared/store-prompt-methods.ts +0 -215
  540. package/dist/builtin/workflows/src/shared/store-public-types.ts +0 -282
  541. package/dist/builtin/workflows/src/shared/store-run-methods.ts +0 -305
  542. package/dist/builtin/workflows/src/shared/store-stage-methods.ts +0 -331
  543. package/dist/builtin/workflows/src/shared/store-tool-node-methods.ts +0 -60
  544. package/dist/builtin/workflows/src/shared/store-types.ts +0 -439
  545. package/dist/builtin/workflows/src/shared/store.ts +0 -15
  546. package/dist/builtin/workflows/src/shared/timing.ts +0 -71
  547. package/dist/builtin/workflows/src/shared/tool-payload-bounds.ts +0 -576
  548. package/dist/builtin/workflows/src/shared/types.ts +0 -523
  549. package/dist/builtin/workflows/src/shared/workflow-artifact-env.ts +0 -21
  550. package/dist/builtin/workflows/src/shared/workflow-artifacts.ts +0 -259
  551. package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +0 -60
  552. package/dist/builtin/workflows/src/shared/workflow-authoring-types.ts +0 -111
  553. package/dist/builtin/workflows/src/shared/workflow-failures-classifier.ts +0 -292
  554. package/dist/builtin/workflows/src/shared/workflow-failures-contract.ts +0 -74
  555. package/dist/builtin/workflows/src/shared/workflow-failures-decisions.ts +0 -458
  556. package/dist/builtin/workflows/src/shared/workflow-failures-signals.ts +0 -303
  557. package/dist/builtin/workflows/src/shared/workflow-failures.ts +0 -13
  558. package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.d.ts +0 -21
  559. package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.ts +0 -25
  560. package/dist/builtin/workflows/src/shared/workflow-run-ownership.ts +0 -49
  561. package/dist/builtin/workflows/src/tui/chat-surface-message.ts +0 -319
  562. package/dist/builtin/workflows/src/tui/chat-surface.ts +0 -477
  563. package/dist/builtin/workflows/src/tui/color-utils.ts +0 -55
  564. package/dist/builtin/workflows/src/tui/connectors.ts +0 -84
  565. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +0 -334
  566. package/dist/builtin/workflows/src/tui/edge.ts +0 -25
  567. package/dist/builtin/workflows/src/tui/graph-canvas.ts +0 -185
  568. package/dist/builtin/workflows/src/tui/graph-theme.ts +0 -292
  569. package/dist/builtin/workflows/src/tui/graph-view-constants.ts +0 -49
  570. package/dist/builtin/workflows/src/tui/graph-view-graph-render.ts +0 -157
  571. package/dist/builtin/workflows/src/tui/graph-view-input.ts +0 -427
  572. package/dist/builtin/workflows/src/tui/graph-view-layout.ts +0 -297
  573. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +0 -294
  574. package/dist/builtin/workflows/src/tui/graph-view-render.ts +0 -361
  575. package/dist/builtin/workflows/src/tui/graph-view-state.ts +0 -547
  576. package/dist/builtin/workflows/src/tui/graph-view-types.ts +0 -79
  577. package/dist/builtin/workflows/src/tui/graph-view.ts +0 -25
  578. package/dist/builtin/workflows/src/tui/header.ts +0 -210
  579. package/dist/builtin/workflows/src/tui/host-input-form.ts +0 -64
  580. package/dist/builtin/workflows/src/tui/inline-form-card.ts +0 -438
  581. package/dist/builtin/workflows/src/tui/inline-form-editor-text.ts +0 -120
  582. package/dist/builtin/workflows/src/tui/inline-form-editor.ts +0 -496
  583. package/dist/builtin/workflows/src/tui/inline-form-overlay.ts +0 -317
  584. package/dist/builtin/workflows/src/tui/inline-form-store.ts +0 -90
  585. package/dist/builtin/workflows/src/tui/inputs-overlay.ts +0 -185
  586. package/dist/builtin/workflows/src/tui/inputs-picker-editing.ts +0 -147
  587. package/dist/builtin/workflows/src/tui/inputs-picker-input.ts +0 -357
  588. package/dist/builtin/workflows/src/tui/inputs-picker-render.ts +0 -312
  589. package/dist/builtin/workflows/src/tui/inputs-picker-types.ts +0 -161
  590. package/dist/builtin/workflows/src/tui/inputs-picker.ts +0 -20
  591. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +0 -167
  592. package/dist/builtin/workflows/src/tui/layout.ts +0 -150
  593. package/dist/builtin/workflows/src/tui/mouse-input.ts +0 -61
  594. package/dist/builtin/workflows/src/tui/node-card.ts +0 -357
  595. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +0 -449
  596. package/dist/builtin/workflows/src/tui/overlay-terminal-modes.ts +0 -39
  597. package/dist/builtin/workflows/src/tui/prompt-card-input.ts +0 -215
  598. package/dist/builtin/workflows/src/tui/prompt-card-render.ts +0 -584
  599. package/dist/builtin/workflows/src/tui/prompt-card-select.ts +0 -94
  600. package/dist/builtin/workflows/src/tui/prompt-card-state.ts +0 -61
  601. package/dist/builtin/workflows/src/tui/prompt-card-text.ts +0 -122
  602. package/dist/builtin/workflows/src/tui/prompt-card.ts +0 -12
  603. package/dist/builtin/workflows/src/tui/renderers.ts +0 -14
  604. package/dist/builtin/workflows/src/tui/run-detail.ts +0 -438
  605. package/dist/builtin/workflows/src/tui/run-identity-rows.ts +0 -97
  606. package/dist/builtin/workflows/src/tui/session-list.ts +0 -38
  607. package/dist/builtin/workflows/src/tui/session-overlays.ts +0 -161
  608. package/dist/builtin/workflows/src/tui/session-picker.ts +0 -482
  609. package/dist/builtin/workflows/src/tui/stage-chat-composer-drafts.ts +0 -19
  610. package/dist/builtin/workflows/src/tui/stage-chat-layout.ts +0 -81
  611. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +0 -462
  612. package/dist/builtin/workflows/src/tui/stage-chat-view-custom-ui.ts +0 -115
  613. package/dist/builtin/workflows/src/tui/stage-chat-view-delivery-activity.ts +0 -113
  614. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +0 -219
  615. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +0 -216
  616. package/dist/builtin/workflows/src/tui/stage-chat-view-live-events.ts +0 -65
  617. package/dist/builtin/workflows/src/tui/stage-chat-view-pending-tools.ts +0 -7
  618. package/dist/builtin/workflows/src/tui/stage-chat-view-render-helpers.ts +0 -149
  619. package/dist/builtin/workflows/src/tui/stage-chat-view-render-settings.ts +0 -49
  620. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +0 -575
  621. package/dist/builtin/workflows/src/tui/stage-chat-view-status.ts +0 -35
  622. package/dist/builtin/workflows/src/tui/stage-chat-view-transcript.ts +0 -226
  623. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +0 -156
  624. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +0 -309
  625. package/dist/builtin/workflows/src/tui/status-helpers.ts +0 -85
  626. package/dist/builtin/workflows/src/tui/status-list.ts +0 -447
  627. package/dist/builtin/workflows/src/tui/store-widget-installer.ts +0 -338
  628. package/dist/builtin/workflows/src/tui/submit-pane.ts +0 -148
  629. package/dist/builtin/workflows/src/tui/switcher.ts +0 -172
  630. package/dist/builtin/workflows/src/tui/text-helpers.ts +0 -208
  631. package/dist/builtin/workflows/src/tui/tool-detail.ts +0 -367
  632. package/dist/builtin/workflows/src/tui/widget.ts +0 -427
  633. package/dist/builtin/workflows/src/tui/workflow-attach-pane-handle.ts +0 -21
  634. package/dist/builtin/workflows/src/tui/workflow-attach-pane-types.ts +0 -77
  635. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +0 -477
  636. package/dist/builtin/workflows/src/tui/workflow-list.ts +0 -189
  637. package/dist/builtin/workflows/src/tui/workflow-notice-card.ts +0 -167
  638. package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +0 -334
  639. package/dist/builtin/workflows/src/tui/workflow-status.ts +0 -12
  640. package/dist/builtin/workflows/src/workflows/identity.ts +0 -39
  641. package/dist/builtin/workflows/src/workflows/registry.ts +0 -115
@@ -1,962 +0,0 @@
1
- import type { SessionEntry } from "../shared/persistence-restore.js";
2
- import { effectiveRunStatus } from "../shared/returned-run-status.js";
3
- import { isTopLevelWorkflowRun } from "../shared/run-visibility.js";
4
- import type { Store } from "../shared/store.js";
5
- import { isTerminalRunStatus } from "../shared/store-internal.js";
6
- import { readGraphStoreSnapshot, subscribeStoreInvalidation } from "../shared/store-observation.js";
7
- import type { RunSnapshot, StoreSnapshot } from "../shared/store-types.js";
8
- import {
9
- WORKFLOW_HEARTBEAT_CUSTOM_TYPE,
10
- type WorkflowHeartbeatEventDetails,
11
- type WorkflowHeartbeatIdentity,
12
- } from "../shared/workflow-heartbeat-contract.js";
13
- import type { ExtensionAPI } from "./index.js";
14
- import {
15
- createWorkflowHeartbeatDelivery,
16
- defaultWorkflowHeartbeatTimerApi,
17
- type WorkflowHeartbeatTimerApi,
18
- type WorkflowHeartbeatTimerHandle,
19
- } from "./workflow-heartbeat-delivery.js";
20
- import { formatWorkflowHeartbeatNoticeText } from "./workflow-heartbeat-notice.js";
21
-
22
- /**
23
- * Longest delay a host timer accepts before it overflows to a 1 ms fire. A
24
- * boundary further out than this is armed in one clamped hop; the wake-up finds
25
- * nothing due and re-arms for the remainder.
26
- */
27
- const MAX_TIMER_DELAY_MS = 2_147_483_647;
28
-
29
- const MS_PER_MINUTE = 60_000;
30
-
31
- /** Minimal run shape the schedule door reads. */
32
- export type WorkflowHeartbeatRun = Pick<RunSnapshot, "id" | "name" | "startedAt" | "status">;
33
-
34
- export interface WorkflowHeartbeatScheduleDisabled {
35
- readonly kind: "disabled";
36
- }
37
-
38
- export interface WorkflowHeartbeatScheduleScheduled {
39
- readonly kind: "scheduled";
40
- readonly scheduledAt: number;
41
- }
42
-
43
- export type WorkflowHeartbeatScheduleResult = WorkflowHeartbeatScheduleDisabled | WorkflowHeartbeatScheduleScheduled;
44
-
45
- export type WorkflowHeartbeatSuppressionReason = "missing" | "terminal" | "paused" | "duplicate" | "unavailable";
46
-
47
- export interface WorkflowHeartbeatEnqueued {
48
- readonly kind: "enqueued";
49
- readonly identity: WorkflowHeartbeatIdentity;
50
- }
51
-
52
- export interface WorkflowHeartbeatSuppressed {
53
- readonly kind: "suppressed";
54
- readonly reason: WorkflowHeartbeatSuppressionReason;
55
- }
56
-
57
- export type WorkflowHeartbeatEnqueueResult = WorkflowHeartbeatEnqueued | WorkflowHeartbeatSuppressed;
58
-
59
- export interface WorkflowHeartbeatCleared {
60
- readonly kind: "cleared";
61
- }
62
-
63
- export interface WorkflowHeartbeatAlreadyClear {
64
- readonly kind: "already-clear";
65
- }
66
-
67
- export type WorkflowHeartbeatClearResult = WorkflowHeartbeatCleared | WorkflowHeartbeatAlreadyClear;
68
-
69
- /**
70
- * Scheduler state.
71
- *
72
- * The cadence is derived, never stored twice: a boundary is a pure function of
73
- * the run's original start time and the `heartbeatIntervalMinutes` frozen at the
74
- * authoring door. Session restore already preserves the start time verbatim
75
- * (`shared/persistence-restore.ts`).
76
- *
77
- * One durable record exists, and only because one input is genuinely not
78
- * derivable: a durable resume re-dispatches under the original workflow id but
79
- * mints a fresh `RunSnapshot.startedAt`, so the original start survives nowhere
80
- * else. `durable/workflow-heartbeat-anchor.ts` carries it, write-once, and is
81
- * read as `min(run.startedAt, anchorAt)` — it can only restore the original
82
- * anchor, never advance it.
83
- *
84
- * `pending` is deliberately never persisted: after a process exit the host
85
- * session and its queue are gone, so re-delivering that identity would backfill
86
- * a missed boundary, which the spec forbids.
87
- */
88
- export interface WorkflowHeartbeatSchedulerState {
89
- /** Next due boundary per enabled active run. At most one entry per run. */
90
- readonly scheduled: Map<string, WorkflowHeartbeatEventDetails>;
91
- /** Outstanding heartbeat per run — in flight, or admitted and awaiting pickup. */
92
- readonly pending: Map<string, WorkflowHeartbeatIdentity>;
93
- /** Exact identity of each admitted heartbeat the parent has not consumed yet, by run. */
94
- readonly awaitingParentPickup: Map<string, WorkflowHeartbeatIdentity>;
95
- /** Most recently enqueued boundary per run, so a boundary is never re-raised. */
96
- readonly lastEnqueuedAt: Map<string, number>;
97
- /** Resolved cadence anchor per run, memoized after its first durable read. */
98
- readonly anchorAt: Map<string, number>;
99
- /** Runs whose launch record is durably acknowledged, so the write stops retrying. */
100
- readonly anchorPersisted: Set<string>;
101
- /** Runs with a launch-record write in flight, so at most one is outstanding. */
102
- readonly anchorWritesPending: Set<string>;
103
- /**
104
- * Cadence each run launched with, captured the first time it resolved.
105
- *
106
- * An in-flight run keeps the interval its own definition was authored with.
107
- * Re-reading the live registry every pass would let a mid-run `/workflow
108
- * reload`, rename, edit, or delete change or stop an already-enabled run —
109
- * and nothing else in the system lets a reload reach a run in flight, because
110
- * the executor closes over its own definition for the life of the run.
111
- */
112
- readonly intervalMinutes: Map<string, number>;
113
- }
114
-
115
- export function createWorkflowHeartbeatSchedulerState(): WorkflowHeartbeatSchedulerState {
116
- return {
117
- scheduled: new Map<string, WorkflowHeartbeatEventDetails>(),
118
- pending: new Map<string, WorkflowHeartbeatIdentity>(),
119
- awaitingParentPickup: new Map<string, WorkflowHeartbeatIdentity>(),
120
- lastEnqueuedAt: new Map<string, number>(),
121
- anchorAt: new Map<string, number>(),
122
- anchorPersisted: new Set<string>(),
123
- anchorWritesPending: new Set<string>(),
124
- intervalMinutes: new Map<string, number>(),
125
- };
126
- }
127
-
128
- export function resetWorkflowHeartbeatSchedulerState(state: WorkflowHeartbeatSchedulerState): void {
129
- state.scheduled.clear();
130
- state.pending.clear();
131
- state.awaitingParentPickup.clear();
132
- state.lastEnqueuedAt.clear();
133
- state.anchorAt.clear();
134
- state.anchorPersisted.clear();
135
- state.anchorWritesPending.clear();
136
- state.intervalMinutes.clear();
137
- }
138
-
139
- export interface WorkflowHeartbeatSchedulerOptions {
140
- readonly store: Store;
141
- readonly sendMessage?: ExtensionAPI["sendMessage"];
142
- /**
143
- * Resolved cadence for a workflow name, read from the compiled definition.
144
- * `undefined` means the definition is not available, which schedules nothing.
145
- */
146
- readonly resolveIntervalMinutes: (workflowName: string) => number | undefined;
147
- /**
148
- * Whether the host reports heartbeat consumption, by routing its `message_end`
149
- * event to `notifyHeartbeatConsumed()`.
150
- *
151
- * The host resolves `sendMessage` when the card is admitted into the parent's
152
- * queue, not when the parent reads it. When consumption is reported, an
153
- * admitted heartbeat holds its slot until the card is actually injected into
154
- * the conversation, with no deadline — that is what "retain exactly one
155
- * pending event" requires, and a deadline of any length would breach it. When
156
- * it is not reported nothing could ever release the slot, so an admitted
157
- * heartbeat releases it at once rather than silencing the run.
158
- */
159
- readonly parentAvailabilityReported?: boolean;
160
- /** Persisted cadence anchor, best-effort. Omitted disables the durable record. */
161
- readonly anchorStore?: WorkflowHeartbeatAnchorStore;
162
- readonly state?: WorkflowHeartbeatSchedulerState;
163
- readonly now?: () => number;
164
- readonly timers?: WorkflowHeartbeatTimerApi;
165
- }
166
-
167
- /** What a run launched with, recovered across a process boundary. */
168
- export interface WorkflowHeartbeatLaunchRecord {
169
- /** The run's original start time. */
170
- readonly anchorAt: number;
171
- /** The cadence its own definition declared. Absent on pre-existing records. */
172
- readonly intervalMinutes?: number;
173
- }
174
-
175
- /**
176
- * Durable launch-record seam. Both sides are best-effort: a backend that is not
177
- * ready must degrade to the run's own `startedAt` and the live definition rather
178
- * than fail a background pass.
179
- */
180
- export interface WorkflowHeartbeatAnchorStore {
181
- /** What the run launched with, when a record was written. */
182
- readAnchorAt(runId: string): WorkflowHeartbeatLaunchRecord | undefined;
183
- /**
184
- * Persist what the run launched with. Write-once; later calls are no-ops.
185
- * Returns whether the record is durably readable afterwards, so the caller can
186
- * stop retrying. Never called for a non-positive cadence.
187
- */
188
- recordAnchorAt(runId: string, record: WorkflowHeartbeatLaunchRecord): Promise<boolean>;
189
- }
190
-
191
- export interface WorkflowHeartbeatScheduler {
192
- /** Maintain at most one next-due heartbeat schedule for one enabled active run. */
193
- scheduleWorkflowHeartbeats(run: WorkflowHeartbeatRun, intervalMinutes: number): WorkflowHeartbeatScheduleResult;
194
- /** Queue one due heartbeat for the parent chat without interrupting it. */
195
- enqueueWorkflowHeartbeat(payload: WorkflowHeartbeatEventDetails): WorkflowHeartbeatEnqueueResult;
196
- /**
197
- * Terminal cleanup (issue #1975): leave no deliverable heartbeat schedule,
198
- * timer, launch memo, or queued heartbeat for one run.
199
- *
200
- * Idempotent by construction — every step is an unconditional delete on a map,
201
- * a set, or the delivery queue, none of which throws for an absent key and
202
- * none of which writes anything back. A repeat call therefore reports
203
- * `already-clear` and cannot resurrect a schedule.
204
- *
205
- * What it cannot do is withdraw a card the host has already admitted into the
206
- * parent's queue: no extension-facing seam exposes that. That one is caught at
207
- * the other end instead — {@link workflowHeartbeatContextInvalidation} runs
208
- * when the parent reads the card and keeps a finished run's heartbeat out of
209
- * the model's context. Locally, the run's slot is released and a later
210
- * consumption signal for it releases and re-arms nothing.
211
- */
212
- clearWorkflowHeartbeats(runId: string): WorkflowHeartbeatClearResult;
213
- /**
214
- * The parent chat consumed this exact heartbeat identity: the host injected
215
- * its typed reconciliation into the conversation. Releases only that run's
216
- * matching held slot and re-arms it at its first future boundary — never at a
217
- * missed one.
218
- *
219
- * Consumption, not turn completion, is the release condition. The host emits
220
- * its turn-settled event even when a paused queue held the card back, so
221
- * releasing on that would let a second card stack behind a parked first one.
222
- */
223
- notifyHeartbeatConsumed(identity: WorkflowHeartbeatIdentity): void;
224
- readonly state: WorkflowHeartbeatSchedulerState;
225
- dispose(): void;
226
- }
227
-
228
- /** Largest cadence in minutes whose millisecond conversion is still representable. */
229
- export const MAX_REPRESENTABLE_WORKFLOW_HEARTBEAT_INTERVAL_MINUTES = Number.MAX_VALUE / MS_PER_MINUTE;
230
-
231
- /**
232
- * First cadence boundary strictly after `after`, on the `startedAt + n × I`
233
- * series. Never derived from a previous delivery, so a retry, a pause, or a
234
- * process restart cannot shift the cadence.
235
- *
236
- * The arithmetic `n` is tried first, then `n + 1` for the ordinary rounding
237
- * case. Neither suffices for a cadence far finer than one ULP at the anchor:
238
- * at a real epoch anchor near `1.7e12` one ULP is about `0.000244 ms`, so a
239
- * `1e-9`-minute cadence (`0.00006 ms`) first lands a representable step at
240
- * `n = 3`. Those two probes would call an authoring-valid interval
241
- * unschedulable, so a bounded bracket-and-narrow finds the smallest such `n`
242
- * while keeping the boundary exactly on the anchored series.
243
- *
244
- * Below one ULP the naming `n` itself stops being representable — at
245
- * `Number.MIN_VALUE` minutes the first `n` that moves the sum is about
246
- * `4.1e314`, past `Number.MAX_VALUE`. The series member still exists and still
247
- * rounds to exactly one ULP past the anchor, so that is what is returned. This
248
- * is not an invented boundary: every value this function produces is the
249
- * correctly-rounded `startedAt + n × I`, and this case only applies the same
250
- * rounding when no `n` can be written down.
251
- *
252
- * Returns `undefined` only when no representable boundary exists at all: a
253
- * non-positive or non-finite interval, or a cadence above
254
- * {@link MAX_REPRESENTABLE_WORKFLOW_HEARTBEAT_INTERVAL_MINUTES}
255
- * (~`3e303` minutes), where `intervalMs` is already `Infinity` and every
256
- * `startedAt + n × I` is `Infinity` too. Authoring accepts those values, so no
257
- * schedulable boundary is the narrow, non-throwing answer — but it is warned
258
- * about under `ATOMIC_WORKFLOW_DEBUG` rather than being silent.
259
- */
260
- export function nextWorkflowHeartbeatBoundary(
261
- startedAt: number,
262
- intervalMinutes: number,
263
- after: number,
264
- ): number | undefined {
265
- if (!Number.isFinite(intervalMinutes) || intervalMinutes <= 0) return undefined;
266
- if (!Number.isFinite(startedAt) || !Number.isFinite(after)) return undefined;
267
- const intervalMs = intervalMinutes * MS_PER_MINUTE;
268
- if (!Number.isFinite(intervalMs) || intervalMs <= 0) {
269
- warnWorkflowHeartbeatUnschedulableInterval(intervalMinutes);
270
- return undefined;
271
- }
272
- const boundaryAt = (n: number): number => startedAt + n * intervalMs;
273
- const elapsed = after - startedAt;
274
- const estimate = elapsed < 0 ? 1 : Math.floor(elapsed / intervalMs) + 1;
275
- if (!Number.isFinite(estimate)) return undefined;
276
- if (boundaryAt(estimate) > after) return finiteBoundaryAfter(boundaryAt(estimate), after);
277
- // Floating-point rounding can land the computed boundary exactly on or a hair
278
- // before `after`; step one whole interval rather than shaving the anchor.
279
- if (boundaryAt(estimate + 1) > after) return finiteBoundaryAfter(boundaryAt(estimate + 1), after);
280
- // Sub-ULP cadence. Double until the anchored multiple is representably past
281
- // `after`, then narrow back to the smallest one, so the boundary raised is
282
- // still the first on the series rather than an arbitrary later multiple.
283
- let low = estimate + 1;
284
- let high = low;
285
- while (boundaryAt(high) <= after) {
286
- low = high;
287
- high *= 2;
288
- // `n` itself is no longer representable, but the series member it would
289
- // name is: it rounds to the next representable instant after `after`.
290
- if (!Number.isFinite(high)) return nextRepresentableAfter(after);
291
- }
292
- while (high - low > 1) {
293
- const mid = Math.floor(low / 2 + high / 2);
294
- // No integer strictly between them is representable at this magnitude.
295
- if (mid <= low || mid >= high) break;
296
- if (boundaryAt(mid) > after) high = mid;
297
- else low = mid;
298
- }
299
- return finiteBoundaryAfter(boundaryAt(high), after);
300
- }
301
-
302
- function finiteBoundaryAfter(scheduledAt: number, after: number): number | undefined {
303
- return Number.isFinite(scheduledAt) && scheduledAt > after ? scheduledAt : undefined;
304
- }
305
-
306
- /**
307
- * The next representable instant after `at`, one unit in the last place away.
308
- *
309
- * JavaScript has no `Math.nextafter`, so the double is stepped at the bit level.
310
- * Used only for a cadence finer than one ULP, where the anchored series member
311
- * exists but no representable `n` names it.
312
- */
313
- function nextRepresentableAfter(at: number): number | undefined {
314
- if (!Number.isFinite(at)) return undefined;
315
- const view = new DataView(new ArrayBuffer(8));
316
- view.setFloat64(0, at);
317
- // Stepping the bit pattern upward walks away from zero for a positive double
318
- // and toward zero for a negative one, which is what "next larger" means on
319
- // each side. A run's timestamps are positive, so the negative branch is a
320
- // completeness guard rather than a live path.
321
- const bits = view.getBigUint64(0);
322
- view.setBigUint64(0, at >= 0 ? bits + 1n : bits - 1n);
323
- const next = view.getFloat64(0);
324
- return Number.isFinite(next) && next > at ? next : undefined;
325
- }
326
-
327
- /**
328
- * Whether a run may hold a heartbeat schedule right now. An effectively
329
- * blocked run is not progressing, so it receives no new heartbeat even though
330
- * its stored `running` status still makes it resumable.
331
- */
332
- export function isWorkflowHeartbeatEligibleRun(run: RunSnapshot): boolean {
333
- if (!isTopLevelWorkflowRun(run)) return false;
334
- if (run.status !== "running") return false;
335
- if (run.pausedAt !== undefined) return false;
336
- return !isTerminalRunStatus(effectiveRunStatus(run));
337
- }
338
-
339
- /**
340
- * Whether a run is genuinely over and no longer owns heartbeat state.
341
- * `recordRunBlocked` keeps a recoverable block at stored status `running`, so
342
- * cleanup must use the store's terminal status rather than its effective
343
- * lifecycle-notice status.
344
- */
345
- export function isWorkflowHeartbeatTerminalRun(run: RunSnapshot): boolean {
346
- return isTerminalRunStatus(run.status);
347
- }
348
-
349
- export function installWorkflowHeartbeatScheduler(
350
- options: WorkflowHeartbeatSchedulerOptions,
351
- ): WorkflowHeartbeatScheduler {
352
- const state = options.state ?? createWorkflowHeartbeatSchedulerState();
353
- const now = options.now ?? Date.now;
354
- const timers = options.timers ?? defaultWorkflowHeartbeatTimerApi;
355
- const send = options.sendMessage;
356
- const parentAvailabilityReported = options.parentAvailabilityReported === true;
357
- const anchorStore = options.anchorStore;
358
- let active = true;
359
- let timerHandle: WorkflowHeartbeatTimerHandle | undefined;
360
-
361
- const emit = (details: WorkflowHeartbeatEventDetails): boolean | Promise<boolean> => {
362
- if (typeof send !== "function") return false;
363
- try {
364
- const result = send(
365
- {
366
- customType: WORKFLOW_HEARTBEAT_CUSTOM_TYPE,
367
- content: formatWorkflowHeartbeatNoticeText(details),
368
- display: true,
369
- details,
370
- },
371
- // Identical to the lifecycle notice options: the parent's active
372
- // response is never aborted; the steer waits for the next
373
- // protocol-safe boundary and is persisted meanwhile.
374
- { triggerTurn: true, deliverAs: "steer", persistWhenStreaming: true },
375
- );
376
- if (result === undefined) return true;
377
- return Promise.resolve(result).then(
378
- () => true,
379
- (error: unknown) => {
380
- warnWorkflowHeartbeatSendFailure(error);
381
- return false;
382
- },
383
- );
384
- } catch (error) {
385
- warnWorkflowHeartbeatSendFailure(error);
386
- return false;
387
- }
388
- };
389
-
390
- /**
391
- * Live re-check taken before every attempt, retries included. The two
392
- * objective-named guards are the pre-process batch read and the pre-enqueue
393
- * read; this one keeps the second guard true across the retry window, where
394
- * the run could otherwise reach a terminal state between attempt 1 and
395
- * attempt 5 and still be sent. A card the host has already admitted into its
396
- * queue is past this guard: terminal cleanup (issue #1975) discards the
397
- * identities still waiting here, and no host seam withdraws an admitted one,
398
- * so that one is caught later instead — see
399
- * {@link workflowHeartbeatContextInvalidation}, which runs when the parent
400
- * reads the card.
401
- */
402
- const canDeliverWorkflowHeartbeat = (details: WorkflowHeartbeatEventDetails): boolean => {
403
- const run = findRun(readGraphStoreSnapshot(options.store), details.runId);
404
- return run !== undefined && isWorkflowHeartbeatEligibleRun(run);
405
- };
406
-
407
- const delivery = createWorkflowHeartbeatDelivery({
408
- emit,
409
- timers,
410
- canDeliver: canDeliverWorkflowHeartbeat,
411
- onSettled: (details, delivered) => {
412
- const identity = state.pending.get(details.runId);
413
- if (identity?.scheduledAt !== details.scheduledAt) return;
414
- if (!delivered) {
415
- // Nothing reached the parent's queue, so the slot is free at once.
416
- state.pending.delete(details.runId);
417
- state.awaitingParentPickup.delete(details.runId);
418
- refresh();
419
- return;
420
- }
421
- if (!parentAvailabilityReported) {
422
- // This host reports no consumption signal, so nothing could ever
423
- // release a held slot. Releasing on admission is the only choice that
424
- // keeps the run heartbeating at all.
425
- state.pending.delete(details.runId);
426
- refresh();
427
- return;
428
- }
429
- // The host resolves `sendMessage` once the card is admitted into the
430
- // parent's queue, not once the parent reads it — and its turn-settled
431
- // event fires even when a paused queue held the card back. Releasing on
432
- // either would let the next boundary stack a second card behind the
433
- // first, so the slot is held — with no deadline — until the card is
434
- // actually consumed into the conversation. The cadence pauses rather
435
- // than stacking.
436
- //
437
- // The exact scheduled identity is retained until the host injects the
438
- // typed hidden reconciliation. Rendered text is display-only and never
439
- // decides slot ownership or release.
440
- state.awaitingParentPickup.set(details.runId, identity);
441
- refresh();
442
- },
443
- });
444
-
445
- /**
446
- * Drop everything one run owns, in one place.
447
- *
448
- * Every per-run map and set is listed deliberately rather than filtered: a
449
- * field left out here is a leak that survives the run that owns it, which is
450
- * precisely what slice 3 exists to close. `Map.delete`/`Set.delete` report
451
- * whether a key was there and never throw, so the union of those answers is
452
- * the `Cleared`/`AlreadyClear` result with no extra bookkeeping — and no
453
- * tombstone to grow without bound for the life of the process.
454
- *
455
- * Late callbacks cannot re-create what this removed. `onSettled` returns
456
- * early once `pending` no longer holds the identity, and the launch-record
457
- * write only marks a run persisted when its own in-flight marker was still
458
- * there to remove.
459
- *
460
- * Does not arm: the public cleanup door re-arms after this helper removes
461
- * every per-run field and queued identity.
462
- */
463
- const clearRunHeartbeatState = (runId: string): boolean => {
464
- let cleared = state.scheduled.delete(runId);
465
- cleared = state.pending.delete(runId) || cleared;
466
- cleared = state.awaitingParentPickup.delete(runId) || cleared;
467
- cleared = state.lastEnqueuedAt.delete(runId) || cleared;
468
- cleared = state.anchorAt.delete(runId) || cleared;
469
- cleared = state.anchorPersisted.delete(runId) || cleared;
470
- cleared = state.anchorWritesPending.delete(runId) || cleared;
471
- cleared = state.intervalMinutes.delete(runId) || cleared;
472
- return delivery.discard(runId) || cleared;
473
- };
474
-
475
- const clearWorkflowHeartbeats = (runId: string): WorkflowHeartbeatClearResult => {
476
- if (!clearRunHeartbeatState(runId)) return { kind: "already-clear" };
477
- // The global wake-up may have been this run's; re-derive it from what is
478
- // left rather than leaving a timer for a boundary nobody owns.
479
- arm();
480
- return { kind: "cleared" };
481
- };
482
-
483
- const notifyHeartbeatConsumed = (identity: WorkflowHeartbeatIdentity): void => {
484
- if (!active) return;
485
- const held = state.awaitingParentPickup.get(identity.runId);
486
- const pending = state.pending.get(identity.runId);
487
- if (held?.scheduledAt !== identity.scheduledAt || pending?.scheduledAt !== identity.scheduledAt) return;
488
- state.awaitingParentPickup.delete(identity.runId);
489
- state.pending.delete(identity.runId);
490
- // `refresh()` re-arms from `max(now, lastEnqueuedAt)`, so the cadence
491
- // resumes at the first future boundary and never at a missed one.
492
- refresh();
493
- };
494
-
495
- const scheduleWorkflowHeartbeats = (
496
- run: WorkflowHeartbeatRun,
497
- intervalMinutes: number,
498
- ): WorkflowHeartbeatScheduleResult => {
499
- state.scheduled.delete(run.id);
500
- // A resolved interval of 0 creates no timer and no schedule record at all.
501
- if (intervalMinutes <= 0) return { kind: "disabled" };
502
- if (run.status !== "running") return { kind: "disabled" };
503
- // Recovery and resume both land here: the floor is `now`, so missed
504
- // boundaries are skipped rather than replayed.
505
- const floor = Math.max(now(), state.lastEnqueuedAt.get(run.id) ?? Number.NEGATIVE_INFINITY);
506
- const anchorAt = resolveAnchorAt(run);
507
- const scheduledAt = nextWorkflowHeartbeatBoundary(anchorAt, intervalMinutes, floor);
508
- if (scheduledAt === undefined) return { kind: "disabled" };
509
- // Persist the cadence anchor here rather than at the first delivery. A run
510
- // that gains durable progress and then pauses, quits, or crashes before its
511
- // first boundary would otherwise have no record, and a durable resume —
512
- // which reclaims the original run id but remints `startedAt` — would put it
513
- // on a fresh series. The write is a no-op until the run has durable progress
514
- // of its own. Active progress is retried on later store refreshes; the forced
515
- // pause/quit checkpoint covers its already-paused edge at the recorder that
516
- // creates that progress (`engine/run-durable-stage-session.ts`).
517
- persistLaunchRecordOnce(run.id, anchorAt, intervalMinutes);
518
- state.scheduled.set(run.id, {
519
- runId: run.id,
520
- scheduledAt,
521
- workflowName: run.name,
522
- // The anchor, not the snapshot's own `startedAt`: after a durable
523
- // resume those differ, and the payload must stay consistent with the
524
- // series the boundary came from.
525
- startedAt: anchorAt,
526
- intervalMinutes,
527
- });
528
- return { kind: "scheduled", scheduledAt };
529
- };
530
-
531
- const enqueueWorkflowHeartbeat = (payload: WorkflowHeartbeatEventDetails): WorkflowHeartbeatEnqueueResult => {
532
- if (!active || typeof send !== "function") return { kind: "suppressed", reason: "unavailable" };
533
- // Pre-enqueue guard: an independent read of live status, so a run that
534
- // finished between the processing batch and this call is suppressed.
535
- const run = findRun(readGraphStoreSnapshot(options.store), payload.runId);
536
- if (run === undefined) return { kind: "suppressed", reason: "missing" };
537
- if (isTerminalRunStatus(effectiveRunStatus(run))) return { kind: "suppressed", reason: "terminal" };
538
- if (!isWorkflowHeartbeatEligibleRun(run)) return { kind: "suppressed", reason: "paused" };
539
- // One pending event per run, and the oldest one wins: a newer boundary is
540
- // not enqueued while an identity is still in flight.
541
- if (state.pending.has(payload.runId)) return { kind: "suppressed", reason: "duplicate" };
542
- if ((state.lastEnqueuedAt.get(payload.runId) ?? Number.NEGATIVE_INFINITY) >= payload.scheduledAt) {
543
- return { kind: "suppressed", reason: "duplicate" };
544
- }
545
- const identity: WorkflowHeartbeatIdentity = { runId: payload.runId, scheduledAt: payload.scheduledAt };
546
- state.pending.set(payload.runId, identity);
547
- state.lastEnqueuedAt.set(payload.runId, payload.scheduledAt);
548
- delivery.deliver(payload);
549
- return { kind: "enqueued", identity };
550
- };
551
-
552
- const arm = (): void => {
553
- if (timerHandle !== undefined) {
554
- timers.clearTimeout(timerHandle);
555
- timerHandle = undefined;
556
- }
557
- if (!active) return;
558
- // One globally-next-due wake-up, not one recurring timer per run.
559
- const next = earliestScheduled(state);
560
- if (next === undefined) return;
561
- const nextAt = next.scheduledAt;
562
- // A held slot has no deadline, so it contributes no wake-up of its own.
563
- const delay = Math.min(Math.max(1, Math.ceil(nextAt - now())), MAX_TIMER_DELAY_MS);
564
- const handle = timers.setTimeout(() => {
565
- timerHandle = undefined;
566
- processDue();
567
- }, delay);
568
- handle.unref?.();
569
- timerHandle = handle;
570
- };
571
-
572
- const refresh = (): void => {
573
- if (!active || typeof send !== "function") return;
574
- const snapshot = readGraphStoreSnapshot(options.store);
575
- const observed = new Set<string>();
576
- for (const run of snapshot.runs) {
577
- if (!isTopLevelWorkflowRun(run)) continue;
578
- // Terminal cleanup and restart recovery (issue #1975). The trigger is
579
- // observed state, not a transition event, because several paths reach a
580
- // terminal snapshot without ever calling `recordRunEnd` — durable replay,
581
- // completed-catalog reconstruction, and a restore that inserts an
582
- // already-failed run. This pass also runs once at install, so it is the
583
- // boot sweep: a stale durable anchor or a leftover pending record for a
584
- // run that is already terminal is discarded rather than replayed, and the
585
- // anchor is neither read nor written for such a run.
586
- if (isWorkflowHeartbeatTerminalRun(run)) {
587
- clearWorkflowHeartbeats(run.id);
588
- continue;
589
- }
590
- observed.add(run.id);
591
- if (state.pending.has(run.id) || !isWorkflowHeartbeatEligibleRun(run)) {
592
- state.scheduled.delete(run.id);
593
- continue;
594
- }
595
- // An entry that already came due is owed and is kept as it is. Re-deriving
596
- // it here would floor at `now` and silently advance it to the following
597
- // boundary, so any ordinary store mutation landing between a boundary and
598
- // its armed callback would drop that heartbeat. A sticky entry carries the
599
- // `intervalMinutes` captured when it was derived, so a workflow reload in
600
- // that window does not retro-fit a new cadence onto an owed boundary.
601
- const owed = state.scheduled.get(run.id);
602
- if (owed !== undefined && owed.scheduledAt <= now()) continue;
603
- const launched = readLaunchRecord(run.id);
604
- const intervalMinutes = resolveRunIntervalMinutes(
605
- state,
606
- options.resolveIntervalMinutes,
607
- run,
608
- launched?.intervalMinutes,
609
- );
610
- if (intervalMinutes === undefined) {
611
- state.scheduled.delete(run.id);
612
- continue;
613
- }
614
- scheduleWorkflowHeartbeats(run, intervalMinutes);
615
- }
616
- // A run that vanished from the store — cleared session state, a discarded
617
- // graph — owns nothing either. The sweep covers every per-run field, not
618
- // just the schedule, so no timer, slot, or queued identity outlives its run.
619
- for (const runId of trackedRunIds(state)) {
620
- if (!observed.has(runId)) clearWorkflowHeartbeats(runId);
621
- }
622
- arm();
623
- };
624
-
625
- /** The run's durable launch record, read at most once per run per process. */
626
- function readLaunchRecord(runId: string): WorkflowHeartbeatLaunchRecord | undefined {
627
- try {
628
- return anchorStore?.readAnchorAt(runId);
629
- } catch {
630
- // A durable backend that is not ready falls back to live values.
631
- return undefined;
632
- }
633
- }
634
-
635
- /**
636
- * The run's cadence anchor: its original start time. A durable resume mints a
637
- * fresh `RunSnapshot.startedAt` under the original workflow id, so the
638
- * persisted anchor is what keeps the resumed run on its original series.
639
- * Taking the minimum means the record can only restore the original anchor,
640
- * never advance it.
641
- *
642
- * A failed-run continuation legitimately starts a new series: it carries a
643
- * fresh run id, and the slice-1 identity is `runId + scheduledAt`, so it is a
644
- * different run and reads no record of its own.
645
- */
646
- function resolveAnchorAt(run: WorkflowHeartbeatRun): number {
647
- const cached = state.anchorAt.get(run.id);
648
- if (cached !== undefined) return Math.min(cached, run.startedAt);
649
- const stored = readLaunchRecord(run.id)?.anchorAt;
650
- const anchorAt = stored === undefined ? run.startedAt : Math.min(stored, run.startedAt);
651
- state.anchorAt.set(run.id, anchorAt);
652
- return anchorAt;
653
- }
654
-
655
- /**
656
- * Write what the run launched with, at most once per process, best-effort.
657
- *
658
- * The write is asynchronous and its result is only trusted once the durable
659
- * backend acknowledges it. The DBOS backend updates its in-memory mirror
660
- * before the real write is queued, so a synchronous read-back would mark a
661
- * rejected storage write as persisted and never retry it.
662
- *
663
- * `recordAnchorAt` is itself a no-op until the run has durable progress of its
664
- * own, so this is called on every schedule pass until it is acknowledged and
665
- * then never again. Bounding it matters because a schedule pass runs on every
666
- * store invalidation for every running run; `anchorWritesPending` keeps at
667
- * most one write in flight per run while a pass is waiting.
668
- *
669
- * A failure clears only the pending marker and leaves the retry to the next
670
- * natural schedule pass. It deliberately does not call `refresh()`, which
671
- * would turn a persistently failing backend into a retry loop.
672
- *
673
- * The in-flight marker is also what makes a late acknowledgement safe after
674
- * terminal cleanup (issue #1975): cleanup removes the marker, so a write that
675
- * resolves afterwards finds nothing to remove and records nothing, rather
676
- * than re-creating an `anchorPersisted` entry for a run that is finished.
677
- *
678
- * Only reached for a positive cadence, because `scheduleWorkflowHeartbeats`
679
- * returns `disabled` above this point — so a run launched with heartbeats off
680
- * leaves no durable artifact of any kind, which is what the acceptance
681
- * criterion "disabled (0) creates no timer or record" requires.
682
- */
683
- function persistLaunchRecordOnce(runId: string, anchorAt: number, intervalMinutes: number): void {
684
- if (anchorStore === undefined) return;
685
- if (state.anchorPersisted.has(runId) || state.anchorWritesPending.has(runId)) return;
686
- state.anchorWritesPending.add(runId);
687
- let write: Promise<boolean>;
688
- try {
689
- write = Promise.resolve(anchorStore.recordAnchorAt(runId, { anchorAt, intervalMinutes }));
690
- } catch {
691
- // A backend that throws synchronously must not stop a heartbeat.
692
- state.anchorWritesPending.delete(runId);
693
- return;
694
- }
695
- void write.then(
696
- (acknowledged) => {
697
- // `Set.delete` reports whether this run was still tracked. Cleanup
698
- // removes the marker, so a resolution arriving after it adds nothing.
699
- const tracked = state.anchorWritesPending.delete(runId);
700
- if (acknowledged && tracked) state.anchorPersisted.add(runId);
701
- },
702
- () => {
703
- state.anchorWritesPending.delete(runId);
704
- },
705
- );
706
- }
707
-
708
- const processDue = (): void => {
709
- if (!active) return;
710
- const at = now();
711
- const due = [...state.scheduled.values()]
712
- .filter((details) => details.scheduledAt <= at)
713
- .sort(compareWorkflowHeartbeatOrder);
714
- // Pre-process guard: live status read taken immediately before the batch,
715
- // separate from the per-enqueue read below.
716
- const snapshot = readGraphStoreSnapshot(options.store);
717
- for (const details of due) {
718
- state.scheduled.delete(details.runId);
719
- const run = findRun(snapshot, details.runId);
720
- if (run === undefined || !isWorkflowHeartbeatEligibleRun(run)) continue;
721
- enqueueWorkflowHeartbeat(details);
722
- }
723
- refresh();
724
- };
725
-
726
- const unsubscribe = subscribeStoreInvalidation(options.store, refresh);
727
- refresh();
728
-
729
- return {
730
- scheduleWorkflowHeartbeats,
731
- enqueueWorkflowHeartbeat,
732
- clearWorkflowHeartbeats,
733
- notifyHeartbeatConsumed,
734
- state,
735
- dispose() {
736
- active = false;
737
- unsubscribe();
738
- if (timerHandle !== undefined) {
739
- timers.clearTimeout(timerHandle);
740
- timerHandle = undefined;
741
- }
742
- state.scheduled.clear();
743
- delivery.dispose();
744
- },
745
- };
746
- }
747
-
748
- /** Due heartbeats process in `scheduledAt` order, with `runId` as the stable tie-break. */
749
- export function compareWorkflowHeartbeatOrder(a: WorkflowHeartbeatIdentity, b: WorkflowHeartbeatIdentity): number {
750
- if (a.scheduledAt !== b.scheduledAt) return a.scheduledAt - b.scheduledAt;
751
- if (a.runId === b.runId) return 0;
752
- return a.runId < b.runId ? -1 : 1;
753
- }
754
-
755
- function earliestScheduled(state: WorkflowHeartbeatSchedulerState): WorkflowHeartbeatEventDetails | undefined {
756
- let earliest: WorkflowHeartbeatEventDetails | undefined;
757
- for (const details of state.scheduled.values()) {
758
- if (earliest === undefined || compareWorkflowHeartbeatOrder(details, earliest) < 0) earliest = details;
759
- }
760
- return earliest;
761
- }
762
-
763
- /**
764
- * Every run this state still holds anything for, as a snapshot safe to mutate
765
- * under. Listing all eight fields is deliberate: the sweep that uses it exists
766
- * to prove nothing outlives its run, and a field omitted here would be the one
767
- * thing that did.
768
- */
769
- function trackedRunIds(state: WorkflowHeartbeatSchedulerState): string[] {
770
- const ids = new Set<string>([
771
- ...state.scheduled.keys(),
772
- ...state.pending.keys(),
773
- ...state.awaitingParentPickup.keys(),
774
- ...state.lastEnqueuedAt.keys(),
775
- ...state.anchorAt.keys(),
776
- ...state.anchorPersisted,
777
- ...state.anchorWritesPending,
778
- ...state.intervalMinutes.keys(),
779
- ]);
780
- return [...ids];
781
- }
782
-
783
- /**
784
- * The cadence for a run: the one it launched with, resolved from its definition
785
- * the first time and memoized thereafter.
786
- *
787
- * Only a successful resolution memoizes, so a run observed during startup
788
- * warmup — before discovery has finished — picks its cadence up on a later pass
789
- * rather than being frozen as unresolvable. Once resolved, a `/workflow reload`,
790
- * rename, edit, or delete cannot change or stop that run.
791
- */
792
- function resolveRunIntervalMinutes(
793
- state: WorkflowHeartbeatSchedulerState,
794
- resolve: (workflowName: string) => number | undefined,
795
- run: WorkflowHeartbeatRun,
796
- persistedIntervalMinutes?: number,
797
- ): number | undefined {
798
- const memoized = state.intervalMinutes.get(run.id);
799
- // A memoized `0` means the run launched disabled, and stays disabled for its
800
- // whole life however the definition is later edited.
801
- if (memoized !== undefined) return memoized > 0 ? memoized : undefined;
802
- // A persisted launch cadence outranks the live registry: it is what this run
803
- // launched with, recovered across a process boundary. Absent on records
804
- // written by earlier builds, which fall back to the registry.
805
- const resolved = persistedIntervalMinutes ?? resolve(run.name);
806
- // Not resolvable yet — startup discovery may still be warming up, so nothing
807
- // is memoized and the next pass tries again.
808
- if (resolved === undefined || !Number.isFinite(resolved)) return undefined;
809
- // Memoize before the positivity test, so a run that launched disabled is
810
- // remembered as such. Editing that workflow to a positive cadence mid-session
811
- // must not start heartbeating a run that launched with heartbeats off, just as
812
- // editing to `0` must not silence one that launched enabled.
813
- state.intervalMinutes.set(run.id, resolved);
814
- return resolved > 0 ? resolved : undefined;
815
- }
816
-
817
- function findRun(snapshot: StoreSnapshot, runId: string): RunSnapshot | undefined {
818
- return snapshot.runs.find((run) => run.id === runId);
819
- }
820
-
821
- function warnWorkflowHeartbeatSendFailure(error: unknown): void {
822
- if (process.env.ATOMIC_WORKFLOW_DEBUG !== "1") return;
823
- const message = error instanceof Error ? error.message : String(error);
824
- console.warn("[workflows] workflow heartbeat send failed", message);
825
- }
826
-
827
- /**
828
- * A cadence so large that its first boundary is not a representable time.
829
- * Authoring accepts every positive finite value, so this cannot be rejected at
830
- * the door — but it must not be silent either, because the run simply never
831
- * heartbeats.
832
- */
833
- function warnWorkflowHeartbeatUnschedulableInterval(intervalMinutes: number): void {
834
- if (process.env.ATOMIC_WORKFLOW_DEBUG !== "1") return;
835
- console.warn(
836
- `[workflows] heartbeatIntervalMinutes ${intervalMinutes} exceeds the largest representable cadence ` +
837
- `(${MAX_REPRESENTABLE_WORKFLOW_HEARTBEAT_INTERVAL_MINUTES} minutes); no boundary can be scheduled for it`,
838
- );
839
- }
840
-
841
- /**
842
- * A host message as far as heartbeat consumption is concerned.
843
- *
844
- * `details` stays a record because its contents differ per custom type and are
845
- * validated by the reader that knows which type it asked for.
846
- */
847
- interface HostCustomMessage {
848
- readonly role: string;
849
- readonly customType?: string;
850
- readonly details?: Record<string, unknown>;
851
- /** The message exactly as the host produced it, for key-preserving replacement. */
852
- readonly raw: Record<string, unknown>;
853
- }
854
-
855
- /** The `message_end` payload the workflows-side handler receives. */
856
- interface HostMessageEndEvent {
857
- readonly message: HostCustomMessage;
858
- }
859
-
860
- function isRecord(value: unknown): value is Record<string, unknown> {
861
- return typeof value === "object" && value !== null;
862
- }
863
-
864
- /**
865
- * Narrow an untyped `message_end` payload to the declared host shape.
866
- *
867
- * The handler signature is `(event?: unknown, ctx?) => unknown`, so `unknown` is
868
- * the honest type of what arrives; it is validated once here and every consumer
869
- * downstream reads a declared type instead of re-casting at each field. A
870
- * payload that does not match is rejected exactly as before rather than trusted
871
- * because a type claims a shape.
872
- */
873
- function asHostMessageEndEvent(event: unknown): HostMessageEndEvent | undefined {
874
- if (!isRecord(event)) return undefined;
875
- const message = event.message;
876
- if (!isRecord(message)) return undefined;
877
- const { role, customType, details } = message;
878
- if (typeof role !== "string") return undefined;
879
- return {
880
- message: {
881
- role,
882
- ...(typeof customType === "string" ? { customType } : {}),
883
- ...(isRecord(details) ? { details } : {}),
884
- raw: message,
885
- },
886
- };
887
- }
888
-
889
- /**
890
- * Host custom type of the hidden twin queued alongside a protected card.
891
- *
892
- * Declared locally rather than imported: `packages/workflows` never imports
893
- * `packages/coding-agent` source, the same reason `"message_end"` and
894
- * `deliverAs: "steer"` are string literals here.
895
- *
896
- * cross-ref: packages/coding-agent/src/core/agent-session-persistent-custom-messages.ts
897
- */
898
- const PROTECTED_RECONCILIATION_CUSTOM_TYPE = "atomic:protected-streaming-reconciliation";
899
-
900
- /**
901
- * The exact heartbeat identity this consumed message belongs to, or
902
- * `undefined` when it is not a heartbeat reconciliation.
903
- *
904
- * The parent's queue holds a hidden reconciliation whose
905
- * `details.protectedReconciliationOf` points to the visible intent entry.
906
- * Identity comes only from a typed `workflows:workflow-heartbeat` intent, never
907
- * from rendered text or from another extension's custom message.
908
- */
909
- export function workflowHeartbeatConsumedIdentity(
910
- event: unknown,
911
- entries: readonly SessionEntry[] | undefined,
912
- ): WorkflowHeartbeatIdentity | undefined {
913
- if (entries === undefined) return undefined;
914
- const parsed = asHostMessageEndEvent(event);
915
- if (parsed === undefined) return undefined;
916
- const { role, customType, details } = parsed.message;
917
- if (role !== "custom" || customType !== PROTECTED_RECONCILIATION_CUSTOM_TYPE) return undefined;
918
- if (details === undefined) return undefined;
919
- const intentEntryId = details.protectedReconciliationOf;
920
- if (typeof intentEntryId !== "string") return undefined;
921
- const intent = entries.find((entry) => entry.id === intentEntryId);
922
- if (intent?.customType !== WORKFLOW_HEARTBEAT_CUSTOM_TYPE) return undefined;
923
- if (!isRecord(intent.details)) return undefined;
924
- const { runId, scheduledAt } = intent.details;
925
- if (typeof runId !== "string" || typeof scheduledAt !== "number") return undefined;
926
- return { runId, scheduledAt };
927
- }
928
-
929
- /**
930
- * The `message_end` replacement that invalidates a heartbeat whose run no longer
931
- * owns it, or `undefined` to leave the message exactly as the host produced it.
932
- *
933
- * Terminal cleanup reaches everything the scheduler owns, but the parent's queue
934
- * is the host's: once `sendMessage` resolves, the visible card is committed to
935
- * the transcript and a hidden reconciliation is queued behind it, and no host
936
- * seam withdraws either. Consumption is the last moment before that steer joins
937
- * the model's context, and a `message_end` handler may return a replacement of
938
- * the same role — so this is where a heartbeat whose exact identity is no longer
939
- * owned is invalidated (issue #1975).
940
- *
941
- * `excludeFromContext` rather than rewritten text: the host includes a custom
942
- * message in the provider request only when that flag is not `true`, so setting
943
- * it removes the steer from the model's view outright instead of putting
944
- * different words in the parent's context. The visible card is deliberately
945
- * untouched — it is already in the user's scrollback, already excluded from
946
- * context itself, and rewriting a transcript after the fact would be worse than
947
- * leaving a true record of what was raised.
948
- *
949
- * Every key of the original message is carried over: the host replaces by
950
- * deleting each key of the target before assigning, so an omitted one is lost.
951
- */
952
- export function workflowHeartbeatContextInvalidation(
953
- event: unknown,
954
- entries: readonly SessionEntry[] | undefined,
955
- isIdentityOwned: (identity: WorkflowHeartbeatIdentity) => boolean,
956
- ): { readonly message: Record<string, unknown> } | undefined {
957
- const identity = workflowHeartbeatConsumedIdentity(event, entries);
958
- if (identity === undefined || isIdentityOwned(identity)) return undefined;
959
- const parsed = asHostMessageEndEvent(event);
960
- if (parsed === undefined) return undefined;
961
- return { message: { ...parsed.message.raw, excludeFromContext: true } };
962
- }