@bastani/atomic 0.9.13 → 0.9.14-alpha.2

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 (762) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +3 -3
  3. package/dist/builtin/intercom/package.json +2 -2
  4. package/dist/builtin/mcp/package.json +3 -3
  5. package/dist/builtin/subagents/CHANGELOG.md +14 -0
  6. package/dist/builtin/subagents/README.md +6 -4
  7. package/dist/builtin/subagents/agents/code-simplifier.md +1 -1
  8. package/dist/builtin/subagents/agents/codebase-analyzer.md +1 -1
  9. package/dist/builtin/subagents/agents/codebase-locator.md +1 -1
  10. package/dist/builtin/subagents/agents/codebase-online-researcher.md +1 -1
  11. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +1 -1
  12. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +1 -1
  13. package/dist/builtin/subagents/agents/codebase-research-locator.md +1 -1
  14. package/dist/builtin/subagents/agents/debugger.md +1 -1
  15. package/dist/builtin/subagents/agents/worker.md +1 -1
  16. package/dist/builtin/subagents/package.json +6 -5
  17. package/dist/builtin/subagents/src/agents/agent-discovery.ts +17 -11
  18. package/dist/builtin/subagents/src/agents/agent-loaders.ts +115 -43
  19. package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +10 -8
  20. package/dist/builtin/subagents/src/agents/agent-management.ts +8 -7
  21. package/dist/builtin/subagents/src/agents/agent-overrides.ts +2 -2
  22. package/dist/builtin/subagents/src/agents/agent-scope.ts +1 -1
  23. package/dist/builtin/subagents/src/agents/agent-selection.ts +1 -1
  24. package/dist/builtin/subagents/src/agents/agent-serializer.ts +24 -3
  25. package/dist/builtin/subagents/src/agents/agent-types.ts +3 -1
  26. package/dist/builtin/subagents/src/agents/agents.ts +7 -5
  27. package/dist/builtin/subagents/src/agents/frontmatter.ts +67 -22
  28. package/dist/builtin/subagents/src/agents/identity.ts +1 -1
  29. package/dist/builtin/subagents/src/agents/skills-paths.ts +1 -1
  30. package/dist/builtin/subagents/src/agents/skills.ts +64 -6
  31. package/dist/builtin/subagents/src/extension/config.ts +1 -1
  32. package/dist/builtin/subagents/src/extension/control-notices.ts +2 -2
  33. package/dist/builtin/subagents/src/extension/doctor.ts +15 -5
  34. package/dist/builtin/subagents/src/extension/fanout-child.ts +12 -12
  35. package/dist/builtin/subagents/src/extension/index.ts +23 -23
  36. package/dist/builtin/subagents/src/extension/notification-content.ts +1 -1
  37. package/dist/builtin/subagents/src/extension/schemas.ts +1 -1
  38. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +3 -3
  39. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +3 -3
  40. package/dist/builtin/subagents/src/intercom/result-intercom.ts +1 -1
  41. package/dist/builtin/subagents/src/intercom/supervisor-authorization.ts +1 -1
  42. package/dist/builtin/subagents/src/runs/foreground/completion-notification.ts +2 -2
  43. package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +1 -1
  44. package/dist/builtin/subagents/src/runs/foreground/execution-intercom-detach.ts +3 -3
  45. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +1 -1
  46. package/dist/builtin/subagents/src/runs/foreground/execution-updates.ts +2 -2
  47. package/dist/builtin/subagents/src/runs/foreground/execution-utils.ts +1 -1
  48. package/dist/builtin/subagents/src/runs/foreground/execution.ts +2 -2
  49. package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +27 -11
  50. package/dist/builtin/subagents/src/runs/foreground/notify.ts +3 -3
  51. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +11 -11
  52. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +3 -3
  53. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +15 -14
  54. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +19 -19
  55. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-runtime.ts +2 -2
  56. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +14 -13
  57. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +9 -9
  58. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +7 -7
  59. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-worktree.ts +6 -6
  60. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +24 -23
  61. package/dist/builtin/subagents/src/runs/inprocess/control-registry.ts +1 -1
  62. package/dist/builtin/subagents/src/runs/inprocess/control-status.ts +3 -3
  63. package/dist/builtin/subagents/src/runs/inprocess/index.ts +3 -3
  64. package/dist/builtin/subagents/src/runs/inprocess/prompt-behavior.ts +17 -8
  65. package/dist/builtin/subagents/src/runs/inprocess/runner.ts +60 -12
  66. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-api.ts +8 -8
  67. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-control.ts +3 -3
  68. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-core.ts +4 -4
  69. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-projection.ts +4 -4
  70. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-registry.ts +5 -5
  71. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-rendering.ts +3 -3
  72. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-sanitize.ts +3 -3
  73. package/dist/builtin/subagents/src/runs/inprocess.ts +1 -1
  74. package/dist/builtin/subagents/src/runs/shared/long-running-guard.ts +1 -1
  75. package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +1 -1
  76. package/dist/builtin/subagents/src/runs/shared/model-candidate-filter.ts +3 -3
  77. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +2 -2
  78. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +1 -1
  79. package/dist/builtin/subagents/src/runs/shared/single-output.ts +1 -1
  80. package/dist/builtin/subagents/src/runs/shared/subagent-control.ts +1 -1
  81. package/dist/builtin/subagents/src/shared/artifacts.ts +2 -2
  82. package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +1 -1
  83. package/dist/builtin/subagents/src/shared/fast-mode.ts +1 -1
  84. package/dist/builtin/subagents/src/shared/formatters.ts +2 -2
  85. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -1
  86. package/dist/builtin/subagents/src/shared/model-resolution.ts +1 -1
  87. package/dist/builtin/subagents/src/shared/session-tokens.ts +1 -1
  88. package/dist/builtin/subagents/src/shared/settings.ts +4 -4
  89. package/dist/builtin/subagents/src/shared/status-format.ts +1 -1
  90. package/dist/builtin/subagents/src/shared/types-config.ts +16 -4
  91. package/dist/builtin/subagents/src/shared/types-depth.ts +1 -1
  92. package/dist/builtin/subagents/src/shared/types-nested.ts +1 -1
  93. package/dist/builtin/subagents/src/shared/types-output.ts +1 -1
  94. package/dist/builtin/subagents/src/shared/types-results.ts +1 -1
  95. package/dist/builtin/subagents/src/shared/types-runtime.ts +1 -1
  96. package/dist/builtin/subagents/src/shared/types.ts +6 -6
  97. package/dist/builtin/subagents/src/shared/utils.ts +3 -3
  98. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +1 -1
  99. package/dist/builtin/subagents/src/slash/slash-bridge.ts +3 -3
  100. package/dist/builtin/subagents/src/slash/slash-commands.ts +6 -6
  101. package/dist/builtin/subagents/src/slash/slash-live-state.ts +3 -3
  102. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -2
  103. package/dist/builtin/subagents/src/tui/render-layout.ts +1 -1
  104. package/dist/builtin/subagents/src/tui/render-progress.ts +2 -2
  105. package/dist/builtin/subagents/src/tui/render-result-compact.ts +7 -7
  106. package/dist/builtin/subagents/src/tui/render-result.ts +10 -10
  107. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -1
  108. package/dist/builtin/subagents/src/tui/render-status-progress.ts +5 -5
  109. package/dist/builtin/subagents/src/tui/render.ts +4 -4
  110. package/dist/builtin/web-access/package.json +2 -2
  111. package/dist/builtin/workflows/CHANGELOG.md +57 -0
  112. package/dist/builtin/workflows/README.md +39 -8
  113. package/dist/builtin/workflows/builtin/adversarial-verification-runner.ts +16 -5
  114. package/dist/builtin/workflows/builtin/adversarial-verification.ts +4 -0
  115. package/dist/builtin/workflows/builtin/classify-and-act.ts +4 -0
  116. package/dist/builtin/workflows/builtin/fan-out-and-synthesize.ts +4 -0
  117. package/dist/builtin/workflows/builtin/generate-and-filter-runner.ts +12 -4
  118. package/dist/builtin/workflows/builtin/generate-and-filter.ts +4 -0
  119. package/dist/builtin/workflows/builtin/goal-models.ts +8 -10
  120. package/dist/builtin/workflows/builtin/goal.ts +4 -0
  121. package/dist/builtin/workflows/builtin/index.d.ts +0 -4
  122. package/dist/builtin/workflows/builtin/loop-until-done-runner.ts +4 -2
  123. package/dist/builtin/workflows/builtin/loop-until-done.ts +4 -0
  124. package/dist/builtin/workflows/builtin/open-claude-design-live-protocol.ts +305 -0
  125. package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +115 -171
  126. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +9 -25
  127. package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +19 -86
  128. package/dist/builtin/workflows/builtin/open-claude-design-utils.ts +0 -6
  129. package/dist/builtin/workflows/builtin/open-claude-design.d.ts +0 -5
  130. package/dist/builtin/workflows/builtin/open-claude-design.ts +11 -15
  131. package/dist/builtin/workflows/builtin/ralph-models.ts +24 -29
  132. package/dist/builtin/workflows/builtin/ralph.ts +4 -0
  133. package/dist/builtin/workflows/builtin/tournament-runner.ts +6 -3
  134. package/dist/builtin/workflows/builtin/tournament.ts +4 -0
  135. package/dist/builtin/workflows/package.json +2 -2
  136. package/dist/builtin/workflows/skills/impeccable/SKILL.md +3 -3
  137. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_asset_producer.toml +25 -31
  138. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_documenter.toml +1 -0
  139. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_finish_reviewer.toml +16 -10
  140. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_manual_edit_applier.toml +2 -2
  141. package/dist/builtin/workflows/skills/impeccable/reference/android.md +6 -0
  142. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +3 -0
  143. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +3 -1
  144. package/dist/builtin/workflows/skills/impeccable/reference/craft-floor.md +6 -1
  145. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +18 -2
  146. package/dist/builtin/workflows/skills/impeccable/reference/degraded/asset-producer.md +24 -30
  147. package/dist/builtin/workflows/skills/impeccable/reference/degraded/documenter.md +1 -0
  148. package/dist/builtin/workflows/skills/impeccable/reference/degraded/finish-reviewer.md +16 -10
  149. package/dist/builtin/workflows/skills/impeccable/reference/degraded/manual-edit-applier.md +2 -2
  150. package/dist/builtin/workflows/skills/impeccable/reference/distill.md +1 -1
  151. package/dist/builtin/workflows/skills/impeccable/reference/doctor.md +1 -0
  152. package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
  153. package/dist/builtin/workflows/skills/impeccable/reference/extract.md +1 -1
  154. package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +12 -6
  155. package/dist/builtin/workflows/skills/impeccable/reference/init.md +12 -3
  156. package/dist/builtin/workflows/skills/impeccable/reference/ios.md +6 -0
  157. package/dist/builtin/workflows/skills/impeccable/reference/live-setup.md +102 -0
  158. package/dist/builtin/workflows/skills/impeccable/reference/live.md +113 -521
  159. package/dist/builtin/workflows/skills/impeccable/reference/new-work.md +39 -26
  160. package/dist/builtin/workflows/skills/impeccable/reference/overdrive.md +1 -1
  161. package/dist/builtin/workflows/skills/impeccable/reference/polish.md +3 -3
  162. package/dist/builtin/workflows/skills/impeccable/reference/quieter.md +1 -1
  163. package/dist/builtin/workflows/skills/impeccable/reference/visualize.md +25 -11
  164. package/dist/builtin/workflows/skills/impeccable/scripts/concept-seed.mjs +332 -221
  165. package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +10 -19
  166. package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +91 -38
  167. package/dist/builtin/workflows/skills/impeccable/scripts/critique-storage.mjs +19 -10
  168. package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +56 -6
  169. package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +10 -16
  170. package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +140 -2
  171. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +1174 -694
  172. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns.mjs +1 -0
  173. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +5 -1
  174. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +431 -45
  175. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +10 -1
  176. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +47 -6
  177. package/dist/builtin/workflows/skills/impeccable/scripts/detector/node/file-system.mjs +23 -22
  178. package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +0 -10
  179. package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +384 -384
  180. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/color.mjs +466 -2
  181. package/dist/builtin/workflows/skills/impeccable/scripts/doctor.mjs +2 -0
  182. package/dist/builtin/workflows/skills/impeccable/scripts/embed-prompt.mjs +270 -0
  183. package/dist/builtin/workflows/skills/impeccable/scripts/generate-image.mjs +51 -6
  184. package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +70 -10
  185. package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +336 -90
  186. package/dist/builtin/workflows/skills/impeccable/scripts/lib/composition-catalog.mjs +38 -3
  187. package/dist/builtin/workflows/skills/impeccable/scripts/lib/concept-catalog.mjs +77 -11
  188. package/dist/builtin/workflows/skills/impeccable/scripts/lib/design-parser.mjs +102 -19
  189. package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +44 -59
  190. package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +3 -0
  191. package/dist/builtin/workflows/skills/impeccable/scripts/lib/open-system-browser.mjs +57 -0
  192. package/dist/builtin/workflows/skills/impeccable/scripts/lib/roll-selection.mjs +369 -0
  193. package/dist/builtin/workflows/skills/impeccable/scripts/lib/staleness-deep.mjs +31 -3
  194. package/dist/builtin/workflows/skills/impeccable/scripts/lib/staleness.mjs +73 -2
  195. package/dist/builtin/workflows/skills/impeccable/scripts/live/accept-css.mjs +617 -0
  196. package/dist/builtin/workflows/skills/impeccable/scripts/live/accept-verify.mjs +71 -0
  197. package/dist/builtin/workflows/skills/impeccable/scripts/live/browser-script-parts.mjs +29 -2
  198. package/dist/builtin/workflows/skills/impeccable/scripts/live/event-validation.mjs +54 -7
  199. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/astro.mjs +47 -0
  200. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/detect-utils.mjs +157 -0
  201. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/index.mjs +143 -0
  202. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/journal.mjs +205 -0
  203. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/nextjs.mjs +49 -0
  204. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/nuxt.mjs +170 -0
  205. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/script-src.mjs +26 -0
  206. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/static-html.mjs +26 -0
  207. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/sveltekit.mjs +71 -0
  208. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/tag-strategy.mjs +247 -0
  209. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/tanstack-start.mjs +70 -0
  210. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/vite-generic.mjs +42 -0
  211. package/dist/builtin/workflows/skills/impeccable/scripts/live/instructions.mjs +169 -0
  212. package/dist/builtin/workflows/skills/impeccable/scripts/live/roots.mjs +670 -0
  213. package/dist/builtin/workflows/skills/impeccable/scripts/live/session-store.mjs +232 -35
  214. package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-ast.mjs +969 -0
  215. package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +621 -74
  216. package/dist/builtin/workflows/skills/impeccable/scripts/live/sveltekit-adapter.mjs +66 -28
  217. package/dist/builtin/workflows/skills/impeccable/scripts/live/tanstack-adapter.mjs +12 -12
  218. package/dist/builtin/workflows/skills/impeccable/scripts/live/ui-surfaces.mjs +75 -0
  219. package/dist/builtin/workflows/skills/impeccable/scripts/live/vocabulary.mjs +135 -0
  220. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +23 -37
  221. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +945 -115
  222. package/dist/builtin/workflows/skills/impeccable/scripts/live-complete.mjs +33 -1
  223. package/dist/builtin/workflows/skills/impeccable/scripts/live-copy-edit-agent.mjs +132 -15
  224. package/dist/builtin/workflows/skills/impeccable/scripts/live-inject.mjs +173 -425
  225. package/dist/builtin/workflows/skills/impeccable/scripts/live-insert.mjs +2 -0
  226. package/dist/builtin/workflows/skills/impeccable/scripts/live-poll.mjs +16 -3
  227. package/dist/builtin/workflows/skills/impeccable/scripts/live-resume.mjs +39 -10
  228. package/dist/builtin/workflows/skills/impeccable/scripts/live-server.mjs +194 -27
  229. package/dist/builtin/workflows/skills/impeccable/scripts/live-status.mjs +10 -4
  230. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +50 -31
  231. package/dist/builtin/workflows/skills/impeccable/scripts/live.mjs +91 -28
  232. package/dist/builtin/workflows/skills/impeccable/scripts/pin.mjs +8 -5
  233. package/dist/builtin/workflows/skills/impeccable/scripts/serve-question.mjs +759 -109
  234. package/dist/builtin/workflows/src/authoring/workflow.ts +9 -0
  235. package/dist/builtin/workflows/src/authoring.d.ts +3 -0
  236. package/dist/builtin/workflows/src/durable/completed-catalog.ts +23 -2
  237. package/dist/builtin/workflows/src/durable/dbos-backend.ts +30 -17
  238. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +14 -0
  239. package/dist/builtin/workflows/src/durable/dbos-lifecycle.ts +60 -57
  240. package/dist/builtin/workflows/src/durable/dbos-process-owner.ts +87 -0
  241. package/dist/builtin/workflows/src/durable/dbos-registration-diagnostics.ts +113 -0
  242. package/dist/builtin/workflows/src/durable/factory.ts +11 -8
  243. package/dist/builtin/workflows/src/durable/tool-failure-checkpoint.ts +5 -0
  244. package/dist/builtin/workflows/src/durable/tool-primitive.ts +186 -20
  245. package/dist/builtin/workflows/src/durable/types.ts +4 -0
  246. package/dist/builtin/workflows/src/durable/workflow-heartbeat-anchor.ts +153 -0
  247. package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +28 -0
  248. package/dist/builtin/workflows/src/engine/run-tool-control-registry.ts +9 -1
  249. package/dist/builtin/workflows/src/engine/run.ts +1 -0
  250. package/dist/builtin/workflows/src/extension/adopt-session-run-state.ts +20 -0
  251. package/dist/builtin/workflows/src/extension/background-ui-adapter.ts +9 -30
  252. package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
  253. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +28 -10
  254. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +138 -0
  255. package/dist/builtin/workflows/src/extension/index.bundle.mjs +3365 -1341
  256. package/dist/builtin/workflows/src/extension/workflow-heartbeat-delivery.ts +197 -0
  257. package/dist/builtin/workflows/src/extension/workflow-heartbeat-notice.ts +115 -0
  258. package/dist/builtin/workflows/src/extension/workflow-heartbeat-scheduler.ts +962 -0
  259. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +4 -1
  260. package/dist/builtin/workflows/src/extension/workflow-schema.ts +29 -5
  261. package/dist/builtin/workflows/src/extension/workflow-tool-send.ts +32 -1
  262. package/dist/builtin/workflows/src/runs/background/cancellation-registry.ts +10 -1
  263. package/dist/builtin/workflows/src/runs/background/job-tracker.ts +10 -1
  264. package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +16 -11
  265. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +31 -1
  266. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +41 -10
  267. package/dist/builtin/workflows/src/runs/foreground/stage-runner-messages.ts +48 -0
  268. package/dist/builtin/workflows/src/runs/foreground/stage-runner-output.ts +4 -1
  269. package/dist/builtin/workflows/src/runs/foreground/stage-runner-structured-output.ts +45 -12
  270. package/dist/builtin/workflows/src/sdk-surface.ts +9 -0
  271. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +10 -0
  272. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +10 -0
  273. package/dist/builtin/workflows/src/shared/graph-store-snapshot.ts +14 -2
  274. package/dist/builtin/workflows/src/shared/persistence-restore.ts +12 -0
  275. package/dist/builtin/workflows/src/shared/prompt-answer.ts +130 -0
  276. package/dist/builtin/workflows/src/shared/session-scoped-singleton.ts +98 -0
  277. package/dist/builtin/workflows/src/shared/stage-ui-broker.ts +9 -1
  278. package/dist/builtin/workflows/src/shared/store-factory.ts +9 -1
  279. package/dist/builtin/workflows/src/shared/store-public-types.ts +2 -1
  280. package/dist/builtin/workflows/src/shared/store-tool-node-methods.ts +7 -0
  281. package/dist/builtin/workflows/src/shared/store-types.ts +18 -1
  282. package/dist/builtin/workflows/src/shared/tool-payload-bounds.ts +576 -0
  283. package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +1 -0
  284. package/dist/builtin/workflows/src/shared/workflow-authoring-types.ts +1 -0
  285. package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.d.ts +21 -0
  286. package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.ts +25 -0
  287. package/dist/builtin/workflows/src/tui/graph-theme.ts +8 -1
  288. package/dist/builtin/workflows/src/tui/graph-view-constants.ts +11 -0
  289. package/dist/builtin/workflows/src/tui/graph-view-input.ts +100 -5
  290. package/dist/builtin/workflows/src/tui/graph-view-layout.ts +42 -11
  291. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +55 -6
  292. package/dist/builtin/workflows/src/tui/graph-view-render.ts +71 -6
  293. package/dist/builtin/workflows/src/tui/graph-view-state.ts +43 -0
  294. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +2 -0
  295. package/dist/builtin/workflows/src/tui/node-card.ts +5 -1
  296. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +11 -2
  297. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +36 -10
  298. package/dist/builtin/workflows/src/tui/switcher.ts +11 -4
  299. package/dist/builtin/workflows/src/tui/tool-detail.ts +348 -0
  300. package/dist/builtin/workflows/src/tui/workflow-status.ts +5 -2
  301. package/dist/cli/args.d.ts +1 -0
  302. package/dist/cli/args.d.ts.map +1 -1
  303. package/dist/cli/args.js +11 -0
  304. package/dist/cli/args.js.map +1 -1
  305. package/dist/cli/auth-check.d.ts +1 -1
  306. package/dist/cli/auth-check.js.map +1 -1
  307. package/dist/cli/credential-print.d.ts +1 -1
  308. package/dist/cli/credential-print.js.map +1 -1
  309. package/dist/cli/list-models.d.ts +1 -1
  310. package/dist/cli/list-models.js.map +1 -1
  311. package/dist/cli/startup-ui.d.ts +9 -0
  312. package/dist/cli/startup-ui.d.ts.map +1 -1
  313. package/dist/cli/startup-ui.js +7 -1
  314. package/dist/cli/startup-ui.js.map +1 -1
  315. package/dist/core/agent-session-custom-message-commit.js +2 -2
  316. package/dist/core/agent-session-custom-message-commit.js.map +1 -1
  317. package/dist/core/agent-session-export.d.ts +6 -1
  318. package/dist/core/agent-session-export.d.ts.map +1 -1
  319. package/dist/core/agent-session-export.js +6 -3
  320. package/dist/core/agent-session-export.js.map +1 -1
  321. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  322. package/dist/core/agent-session-extension-bindings.js +6 -4
  323. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  324. package/dist/core/agent-session-methods.d.ts +5 -2
  325. package/dist/core/agent-session-methods.d.ts.map +1 -1
  326. package/dist/core/agent-session-methods.js.map +1 -1
  327. package/dist/core/agent-session-prompt.d.ts +12 -1
  328. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  329. package/dist/core/agent-session-prompt.js +31 -10
  330. package/dist/core/agent-session-prompt.js.map +1 -1
  331. package/dist/core/agent-session-runtime-auth.js.map +1 -1
  332. package/dist/core/agent-session-services.d.ts +1 -1
  333. package/dist/core/agent-session-services.js.map +1 -1
  334. package/dist/core/agent-session-skill-block.d.ts +1 -0
  335. package/dist/core/agent-session-skill-block.d.ts.map +1 -1
  336. package/dist/core/agent-session-skill-block.js +18 -2
  337. package/dist/core/agent-session-skill-block.js.map +1 -1
  338. package/dist/core/agent-session-state.d.ts.map +1 -1
  339. package/dist/core/agent-session-state.js +2 -1
  340. package/dist/core/agent-session-state.js.map +1 -1
  341. package/dist/core/agent-session-types.d.ts +2 -1
  342. package/dist/core/agent-session-types.d.ts.map +1 -1
  343. package/dist/core/agent-session-types.js.map +1 -1
  344. package/dist/core/agent-session.d.ts +1 -1
  345. package/dist/core/agent-session.js.map +1 -1
  346. package/dist/core/atomic-guide-command.js +2 -2
  347. package/dist/core/atomic-guide-command.js.map +1 -1
  348. package/dist/core/builtin-packages.d.ts.map +1 -1
  349. package/dist/core/builtin-packages.js +0 -6
  350. package/dist/core/builtin-packages.js.map +1 -1
  351. package/dist/core/cloudflare-gateway-binding.d.ts +11 -0
  352. package/dist/core/cloudflare-gateway-binding.d.ts.map +1 -0
  353. package/dist/core/cloudflare-gateway-binding.js +11 -0
  354. package/dist/core/cloudflare-gateway-binding.js.map +1 -0
  355. package/dist/core/codex-fast-mode-transport.d.ts +12 -0
  356. package/dist/core/codex-fast-mode-transport.d.ts.map +1 -0
  357. package/dist/core/codex-fast-mode-transport.js +130 -0
  358. package/dist/core/codex-fast-mode-transport.js.map +1 -0
  359. package/dist/core/codex-fast-mode.d.ts +20 -6
  360. package/dist/core/codex-fast-mode.d.ts.map +1 -1
  361. package/dist/core/codex-fast-mode.js +111 -3
  362. package/dist/core/codex-fast-mode.js.map +1 -1
  363. package/dist/core/diagnostics.d.ts +4 -0
  364. package/dist/core/diagnostics.d.ts.map +1 -1
  365. package/dist/core/diagnostics.js.map +1 -1
  366. package/dist/core/event-bus.d.ts +12 -0
  367. package/dist/core/event-bus.d.ts.map +1 -1
  368. package/dist/core/event-bus.js +22 -0
  369. package/dist/core/event-bus.js.map +1 -1
  370. package/dist/core/experimental.d.ts +25 -0
  371. package/dist/core/experimental.d.ts.map +1 -1
  372. package/dist/core/experimental.js +24 -0
  373. package/dist/core/experimental.js.map +1 -1
  374. package/dist/core/export-html/template-js/tree-filter-render.js +4 -3
  375. package/dist/core/export-html/template.js +4 -3
  376. package/dist/core/extension-session-state.d.ts +28 -0
  377. package/dist/core/extension-session-state.d.ts.map +1 -0
  378. package/dist/core/extension-session-state.js +55 -0
  379. package/dist/core/extension-session-state.js.map +1 -0
  380. package/dist/core/extensions/api-types.d.ts +6 -0
  381. package/dist/core/extensions/api-types.d.ts.map +1 -1
  382. package/dist/core/extensions/api-types.js.map +1 -1
  383. package/dist/core/extensions/context-types.d.ts +4 -0
  384. package/dist/core/extensions/context-types.d.ts.map +1 -1
  385. package/dist/core/extensions/context-types.js.map +1 -1
  386. package/dist/core/extensions/index.d.ts +1 -0
  387. package/dist/core/extensions/index.d.ts.map +1 -1
  388. package/dist/core/extensions/index.js +1 -0
  389. package/dist/core/extensions/index.js.map +1 -1
  390. package/dist/core/extensions/loader-api.d.ts +1 -1
  391. package/dist/core/extensions/loader-api.d.ts.map +1 -1
  392. package/dist/core/extensions/loader-api.js +16 -10
  393. package/dist/core/extensions/loader-api.js.map +1 -1
  394. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  395. package/dist/core/extensions/loader-virtual-modules.js +12 -1
  396. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  397. package/dist/core/extensions/runner-context.d.ts +2 -0
  398. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  399. package/dist/core/extensions/runner-context.js +8 -0
  400. package/dist/core/extensions/runner-context.js.map +1 -1
  401. package/dist/core/extensions/runner.d.ts +1 -0
  402. package/dist/core/extensions/runner.d.ts.map +1 -1
  403. package/dist/core/extensions/runner.js +3 -0
  404. package/dist/core/extensions/runner.js.map +1 -1
  405. package/dist/core/extensions/runtime-types.d.ts +3 -0
  406. package/dist/core/extensions/runtime-types.d.ts.map +1 -1
  407. package/dist/core/extensions/runtime-types.js.map +1 -1
  408. package/dist/core/extensions/ui-types.d.ts +26 -0
  409. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  410. package/dist/core/extensions/ui-types.js +17 -1
  411. package/dist/core/extensions/ui-types.js.map +1 -1
  412. package/dist/core/http-dispatcher.d.ts.map +1 -1
  413. package/dist/core/http-dispatcher.js +5 -0
  414. package/dist/core/http-dispatcher.js.map +1 -1
  415. package/dist/core/keybindings.d.ts +24 -0
  416. package/dist/core/keybindings.d.ts.map +1 -1
  417. package/dist/core/keybindings.js +6 -0
  418. package/dist/core/keybindings.js.map +1 -1
  419. package/dist/core/model-config.d.ts +5 -0
  420. package/dist/core/model-config.d.ts.map +1 -1
  421. package/dist/core/model-config.js +1 -0
  422. package/dist/core/model-config.js.map +1 -1
  423. package/dist/core/model-registry.d.ts +1 -1
  424. package/dist/core/model-registry.js.map +1 -1
  425. package/dist/core/model-resolver-cli.d.ts +1 -1
  426. package/dist/core/model-resolver-cli.js.map +1 -1
  427. package/dist/core/model-resolver-defaults.js +3 -3
  428. package/dist/core/model-resolver-defaults.js.map +1 -1
  429. package/dist/core/model-resolver-initial.d.ts +1 -1
  430. package/dist/core/model-resolver-initial.js.map +1 -1
  431. package/dist/core/model-resolver-scope.d.ts +1 -1
  432. package/dist/core/model-resolver-scope.js.map +1 -1
  433. package/dist/core/model-runtime.d.ts +54 -0
  434. package/dist/core/model-runtime.d.ts.map +1 -1
  435. package/dist/core/model-runtime.js +96 -13
  436. package/dist/core/model-runtime.js.map +1 -1
  437. package/dist/core/oauth-login.js.map +1 -1
  438. package/dist/core/project-trust.d.ts +10 -0
  439. package/dist/core/project-trust.d.ts.map +1 -1
  440. package/dist/core/project-trust.js +12 -0
  441. package/dist/core/project-trust.js.map +1 -1
  442. package/dist/core/resource-loader-assets.d.ts.map +1 -1
  443. package/dist/core/resource-loader-assets.js +14 -5
  444. package/dist/core/resource-loader-assets.js.map +1 -1
  445. package/dist/core/resource-loader-core.d.ts +3 -0
  446. package/dist/core/resource-loader-core.d.ts.map +1 -1
  447. package/dist/core/resource-loader-core.js +5 -0
  448. package/dist/core/resource-loader-core.js.map +1 -1
  449. package/dist/core/resource-loader-internals.d.ts +2 -0
  450. package/dist/core/resource-loader-internals.d.ts.map +1 -1
  451. package/dist/core/resource-loader-internals.js.map +1 -1
  452. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  453. package/dist/core/resource-loader-reload.js +2 -0
  454. package/dist/core/resource-loader-reload.js.map +1 -1
  455. package/dist/core/resource-loader-types.d.ts +2 -0
  456. package/dist/core/resource-loader-types.d.ts.map +1 -1
  457. package/dist/core/resource-loader-types.js.map +1 -1
  458. package/dist/core/resource-loader.d.ts +2 -0
  459. package/dist/core/resource-loader.d.ts.map +1 -1
  460. package/dist/core/resource-loader.js +1 -0
  461. package/dist/core/resource-loader.js.map +1 -1
  462. package/dist/core/sdk-types.d.ts +7 -6
  463. package/dist/core/sdk-types.d.ts.map +1 -1
  464. package/dist/core/sdk-types.js.map +1 -1
  465. package/dist/core/sdk.d.ts.map +1 -1
  466. package/dist/core/sdk.js +17 -6
  467. package/dist/core/sdk.js.map +1 -1
  468. package/dist/core/session-manager-core.d.ts +7 -1
  469. package/dist/core/session-manager-core.d.ts.map +1 -1
  470. package/dist/core/session-manager-core.js +11 -2
  471. package/dist/core/session-manager-core.js.map +1 -1
  472. package/dist/core/session-manager-entries.d.ts +2 -2
  473. package/dist/core/session-manager-entries.d.ts.map +1 -1
  474. package/dist/core/session-manager-entries.js +6 -4
  475. package/dist/core/session-manager-entries.js.map +1 -1
  476. package/dist/core/session-manager-list.d.ts.map +1 -1
  477. package/dist/core/session-manager-list.js +5 -1
  478. package/dist/core/session-manager-list.js.map +1 -1
  479. package/dist/core/session-manager-types.d.ts +25 -2
  480. package/dist/core/session-manager-types.d.ts.map +1 -1
  481. package/dist/core/session-manager-types.js.map +1 -1
  482. package/dist/core/session-manager.d.ts +1 -1
  483. package/dist/core/session-manager.d.ts.map +1 -1
  484. package/dist/core/session-manager.js.map +1 -1
  485. package/dist/core/settings-manager-basic-accessors.d.ts +1 -0
  486. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  487. package/dist/core/settings-manager-basic-accessors.js +8 -0
  488. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  489. package/dist/core/settings-manager-ui-accessors.d.ts +3 -1
  490. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  491. package/dist/core/settings-manager-ui-accessors.js +9 -0
  492. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  493. package/dist/core/settings-manager.d.ts +1 -1
  494. package/dist/core/settings-manager.d.ts.map +1 -1
  495. package/dist/core/settings-manager.js.map +1 -1
  496. package/dist/core/settings-types.d.ts +4 -0
  497. package/dist/core/settings-types.d.ts.map +1 -1
  498. package/dist/core/settings-types.js.map +1 -1
  499. package/dist/core/skill-catalog.d.ts +35 -0
  500. package/dist/core/skill-catalog.d.ts.map +1 -0
  501. package/dist/core/skill-catalog.js +264 -0
  502. package/dist/core/skill-catalog.js.map +1 -0
  503. package/dist/core/skills-async.d.ts.map +1 -1
  504. package/dist/core/skills-async.js +12 -6
  505. package/dist/core/skills-async.js.map +1 -1
  506. package/dist/core/skills.d.ts +2 -0
  507. package/dist/core/skills.d.ts.map +1 -1
  508. package/dist/core/skills.js +8 -5
  509. package/dist/core/skills.js.map +1 -1
  510. package/dist/core/slash-commands.d.ts.map +1 -1
  511. package/dist/core/slash-commands.js +1 -5
  512. package/dist/core/slash-commands.js.map +1 -1
  513. package/dist/core/system-prompt.js +2 -2
  514. package/dist/core/system-prompt.js.map +1 -1
  515. package/dist/core/tools/ask-user-question/ask-user-question.d.ts +25 -2
  516. package/dist/core/tools/ask-user-question/ask-user-question.d.ts.map +1 -1
  517. package/dist/core/tools/ask-user-question/ask-user-question.js +47 -18
  518. package/dist/core/tools/ask-user-question/ask-user-question.js.map +1 -1
  519. package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts.map +1 -1
  520. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js +5 -2
  521. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js.map +1 -1
  522. package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts.map +1 -1
  523. package/dist/core/tools/ask-user-question/view/components/submit-picker.js +3 -1
  524. package/dist/core/tools/ask-user-question/view/components/submit-picker.js.map +1 -1
  525. package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts.map +1 -1
  526. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js +8 -1
  527. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js.map +1 -1
  528. package/dist/core/tools/bash.d.ts.map +1 -1
  529. package/dist/core/tools/bash.js +2 -0
  530. package/dist/core/tools/bash.js.map +1 -1
  531. package/dist/core/tools/edit.d.ts.map +1 -1
  532. package/dist/core/tools/edit.js +2 -0
  533. package/dist/core/tools/edit.js.map +1 -1
  534. package/dist/core/tools/find.d.ts.map +1 -1
  535. package/dist/core/tools/find.js +3 -1
  536. package/dist/core/tools/find.js.map +1 -1
  537. package/dist/core/tools/grep.js +1 -1
  538. package/dist/core/tools/grep.js.map +1 -1
  539. package/dist/core/tools/hashline-engine/format.d.ts +2 -0
  540. package/dist/core/tools/hashline-engine/format.d.ts.map +1 -1
  541. package/dist/core/tools/hashline-engine/format.js +4 -2
  542. package/dist/core/tools/hashline-engine/format.js.map +1 -1
  543. package/dist/core/tools/hashline-engine/messages.d.ts +2 -0
  544. package/dist/core/tools/hashline-engine/messages.d.ts.map +1 -1
  545. package/dist/core/tools/hashline-engine/messages.js +4 -2
  546. package/dist/core/tools/hashline-engine/messages.js.map +1 -1
  547. package/dist/core/tools/hashline-engine/parser.d.ts.map +1 -1
  548. package/dist/core/tools/hashline-engine/parser.js +16 -4
  549. package/dist/core/tools/hashline-engine/parser.js.map +1 -1
  550. package/dist/core/tools/hashline-engine/tokenizer.d.ts.map +1 -1
  551. package/dist/core/tools/hashline-engine/tokenizer.js +37 -27
  552. package/dist/core/tools/hashline-engine/tokenizer.js.map +1 -1
  553. package/dist/core/tools/hashline.d.ts.map +1 -1
  554. package/dist/core/tools/hashline.js +8 -2
  555. package/dist/core/tools/hashline.js.map +1 -1
  556. package/dist/core/tools/ls.d.ts.map +1 -1
  557. package/dist/core/tools/ls.js +2 -0
  558. package/dist/core/tools/ls.js.map +1 -1
  559. package/dist/core/tools/read.d.ts.map +1 -1
  560. package/dist/core/tools/read.js +8 -1
  561. package/dist/core/tools/read.js.map +1 -1
  562. package/dist/core/tools/search.d.ts.map +1 -1
  563. package/dist/core/tools/search.js +2 -0
  564. package/dist/core/tools/search.js.map +1 -1
  565. package/dist/core/tools/todos.d.ts +3 -12
  566. package/dist/core/tools/todos.d.ts.map +1 -1
  567. package/dist/core/tools/todos.js +19 -4
  568. package/dist/core/tools/todos.js.map +1 -1
  569. package/dist/core/tools/write.d.ts.map +1 -1
  570. package/dist/core/tools/write.js +2 -0
  571. package/dist/core/tools/write.js.map +1 -1
  572. package/dist/index-extensions.d.ts +1 -1
  573. package/dist/index-extensions.d.ts.map +1 -1
  574. package/dist/index-extensions.js +1 -1
  575. package/dist/index-extensions.js.map +1 -1
  576. package/dist/index.d.ts +8 -5
  577. package/dist/index.d.ts.map +1 -1
  578. package/dist/index.js +6 -2
  579. package/dist/index.js.map +1 -1
  580. package/dist/main-runtime-api-key.d.ts +1 -1
  581. package/dist/main-runtime-api-key.js.map +1 -1
  582. package/dist/main-session-options.d.ts +1 -1
  583. package/dist/main-session-options.js.map +1 -1
  584. package/dist/main.d.ts.map +1 -1
  585. package/dist/main.js +10 -2
  586. package/dist/main.js.map +1 -1
  587. package/dist/modes/interactive/components/chat-session-host-rendering.js +1 -1
  588. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  589. package/dist/modes/interactive/components/chat-session-host-state.d.ts +8 -0
  590. package/dist/modes/interactive/components/chat-session-host-state.d.ts.map +1 -1
  591. package/dist/modes/interactive/components/chat-session-host-state.js +8 -0
  592. package/dist/modes/interactive/components/chat-session-host-state.js.map +1 -1
  593. package/dist/modes/interactive/components/chat-session-host.d.ts +26 -0
  594. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  595. package/dist/modes/interactive/components/chat-session-host.js +38 -0
  596. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  597. package/dist/modes/interactive/components/chat-transcript.d.ts +37 -0
  598. package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
  599. package/dist/modes/interactive/components/chat-transcript.js +54 -1
  600. package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
  601. package/dist/modes/interactive/components/fast-mode-selector.js +1 -1
  602. package/dist/modes/interactive/components/fast-mode-selector.js.map +1 -1
  603. package/dist/modes/interactive/components/model-selector.d.ts +1 -1
  604. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  605. package/dist/modes/interactive/components/model-selector.js +2 -1
  606. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  607. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
  608. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  609. package/dist/modes/interactive/components/reserved-bottom-overlay.d.ts +95 -0
  610. package/dist/modes/interactive/components/reserved-bottom-overlay.d.ts.map +1 -0
  611. package/dist/modes/interactive/components/reserved-bottom-overlay.js +234 -0
  612. package/dist/modes/interactive/components/reserved-bottom-overlay.js.map +1 -0
  613. package/dist/modes/interactive/components/session-selector-search.d.ts +4 -0
  614. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  615. package/dist/modes/interactive/components/session-selector-search.js +4 -0
  616. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  617. package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
  618. package/dist/modes/interactive/components/settings-selector-handlers.js +3 -0
  619. package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
  620. package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
  621. package/dist/modes/interactive/components/settings-selector-items.js +7 -0
  622. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  623. package/dist/modes/interactive/components/settings-selector-types.d.ts +3 -1
  624. package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
  625. package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
  626. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  627. package/dist/modes/interactive/components/tool-execution.js +12 -1
  628. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  629. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  630. package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
  631. package/dist/modes/interactive/interactive-autocomplete.js +5 -4
  632. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  633. package/dist/modes/interactive/interactive-bash-compact.d.ts.map +1 -1
  634. package/dist/modes/interactive/interactive-bash-compact.js +2 -2
  635. package/dist/modes/interactive/interactive-bash-compact.js.map +1 -1
  636. package/dist/modes/interactive/interactive-extension-custom-ui.js +94 -6
  637. package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
  638. package/dist/modes/interactive/interactive-mode-base.d.ts +41 -3
  639. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  640. package/dist/modes/interactive/interactive-mode-base.js +80 -11
  641. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  642. package/dist/modes/interactive/interactive-mode-surface.d.ts +9 -1
  643. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  644. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  645. package/dist/modes/interactive/interactive-mode-types.d.ts +2 -0
  646. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  647. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  648. package/dist/modes/interactive/interactive-model-catalog-startup.d.ts +8 -1
  649. package/dist/modes/interactive/interactive-model-catalog-startup.d.ts.map +1 -1
  650. package/dist/modes/interactive/interactive-model-catalog-startup.js +13 -3
  651. package/dist/modes/interactive/interactive-model-catalog-startup.js.map +1 -1
  652. package/dist/modes/interactive/interactive-model-routing.js +3 -4
  653. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  654. package/dist/modes/interactive/interactive-render-chat.js +6 -0
  655. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  656. package/dist/modes/interactive/interactive-resource-disclosure.js +2 -2
  657. package/dist/modes/interactive/interactive-resource-disclosure.js.map +1 -1
  658. package/dist/modes/interactive/interactive-selectors.js +7 -3
  659. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  660. package/dist/modes/interactive/interactive-session-runtime.js +7 -1
  661. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  662. package/dist/modes/interactive/interactive-slash-commands.js +2 -2
  663. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  664. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  665. package/dist/modes/interactive/interactive-startup.js +34 -9
  666. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  667. package/dist/modes/interactive/interactive-tui.d.ts +21 -1
  668. package/dist/modes/interactive/interactive-tui.d.ts.map +1 -1
  669. package/dist/modes/interactive/interactive-tui.js +140 -38
  670. package/dist/modes/interactive/interactive-tui.js.map +1 -1
  671. package/dist/modes/interactive/model-catalog-refresh.d.ts +17 -0
  672. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  673. package/dist/modes/interactive/model-catalog-refresh.js +84 -0
  674. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  675. package/dist/modes/interactive/theme/dark.json +2 -0
  676. package/dist/modes/interactive/theme/light.json +2 -0
  677. package/dist/modes/interactive/theme/theme-class.d.ts +12 -3
  678. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  679. package/dist/modes/interactive/theme/theme-class.js +6 -1
  680. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  681. package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
  682. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  683. package/dist/modes/interactive/theme/theme-controller.js +23 -10
  684. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  685. package/dist/modes/interactive/theme/theme-loading.d.ts.map +1 -1
  686. package/dist/modes/interactive/theme/theme-loading.js +1 -0
  687. package/dist/modes/interactive/theme/theme-loading.js.map +1 -1
  688. package/dist/modes/interactive/theme/theme-schema.d.ts +8 -0
  689. package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  690. package/dist/modes/interactive/theme/theme-schema.js +3 -1
  691. package/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  692. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  693. package/dist/modes/interactive-engine/engine-custom-ui.d.ts +2 -0
  694. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
  695. package/dist/modes/interactive-engine/engine-custom-ui.js +1 -0
  696. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
  697. package/dist/modes/interactive-engine/protocol.d.ts +1 -0
  698. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  699. package/dist/modes/interactive-engine/protocol.js +1 -0
  700. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  701. package/dist/modes/interactive-engine/remote-component.d.ts +3 -1
  702. package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
  703. package/dist/modes/interactive-engine/remote-component.js +3 -2
  704. package/dist/modes/interactive-engine/remote-component.js.map +1 -1
  705. package/dist/modes/json-event.d.ts +6 -1
  706. package/dist/modes/json-event.d.ts.map +1 -1
  707. package/dist/modes/json-event.js +17 -2
  708. package/dist/modes/json-event.js.map +1 -1
  709. package/dist/modes/rpc/rpc-client.js.map +1 -1
  710. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  711. package/dist/modes/rpc/rpc-command-handler.js +5 -4
  712. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  713. package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
  714. package/dist/modes/rpc/rpc-responses.js.map +1 -1
  715. package/dist/modes/rpc/rpc-types.d.ts +1 -1
  716. package/dist/modes/rpc/rpc-types.js.map +1 -1
  717. package/dist/package-manager-cli.js.map +1 -1
  718. package/dist/server/create-harness.d.ts.map +1 -1
  719. package/dist/server/create-harness.js +11 -0
  720. package/dist/server/create-harness.js.map +1 -1
  721. package/dist/utils/abort.d.ts +9 -0
  722. package/dist/utils/abort.d.ts.map +1 -0
  723. package/dist/utils/abort.js +19 -0
  724. package/dist/utils/abort.js.map +1 -0
  725. package/dist/utils/tools-manager.d.ts +16 -1
  726. package/dist/utils/tools-manager.d.ts.map +1 -1
  727. package/dist/utils/tools-manager.js +19 -19
  728. package/dist/utils/tools-manager.js.map +1 -1
  729. package/docs/custom-provider.md +9 -8
  730. package/docs/development.md +0 -1
  731. package/docs/docs.json +0 -1
  732. package/docs/environment-variables.md +3 -0
  733. package/docs/extensions.md +100 -2
  734. package/docs/json.md +3 -1
  735. package/docs/keybindings.md +8 -3
  736. package/docs/models/artificial-analysis-index.md +2 -2
  737. package/docs/models/model-selection.md +32 -23
  738. package/docs/models/pareto-efficiency.md +25 -24
  739. package/docs/providers.md +95 -2
  740. package/docs/quickstart.md +4 -2
  741. package/docs/rpc.md +21 -7
  742. package/docs/sdk.md +26 -1
  743. package/docs/session-format.md +5 -2
  744. package/docs/settings.md +34 -3
  745. package/docs/skills.md +16 -1
  746. package/docs/terminal-setup.md +15 -2
  747. package/docs/themes.md +22 -4
  748. package/docs/tools.md +3 -1
  749. package/docs/tui.md +2 -0
  750. package/docs/usage.md +5 -4
  751. package/docs/workflows.md +96 -19
  752. package/npm-shrinkwrap.json +211 -232
  753. package/package.json +8 -8
  754. package/dist/builtin/i-have-adhd/CHANGELOG.md +0 -30
  755. package/dist/builtin/i-have-adhd/LICENSE +0 -21
  756. package/dist/builtin/i-have-adhd/README.md +0 -18
  757. package/dist/builtin/i-have-adhd/index.ts +0 -238
  758. package/dist/builtin/i-have-adhd/package.json +0 -56
  759. package/dist/builtin/i-have-adhd/skills/i-have-adhd/SKILL.md +0 -140
  760. package/dist/builtin/workflows/builtin/open-claude-design-feedback.ts +0 -359
  761. package/dist/builtin/workflows/skills/impeccable/scripts/live/ui-core.mjs +0 -180
  762. package/docs/i-have-adhd.md +0 -36
@@ -4,7 +4,7 @@ import {
4
4
  readBridgeRequestSettlement,
5
5
  registerBridgeRequestSettlement,
6
6
  rejectStoppedBridgeRequest,
7
- } from "./bridge-settlement.ts";
7
+ } from "./bridge-settlement.js";
8
8
  export const PROMPT_TEMPLATE_SUBAGENT_REQUEST_EVENT = "prompt-template:subagent:request";
9
9
  export const PROMPT_TEMPLATE_SUBAGENT_STARTED_EVENT = "prompt-template:subagent:started";
10
10
  export const PROMPT_TEMPLATE_SUBAGENT_RESPONSE_EVENT = "prompt-template:subagent:response";
@@ -1,6 +1,6 @@
1
1
  import type { ExtensionContext } from "@bastani/atomic";
2
2
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
3
- import type { SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
3
+ import type { SubagentParamsLike } from "../runs/foreground/subagent-executor.js";
4
4
  import {
5
5
  type Details,
6
6
  SLASH_SUBAGENT_CANCEL_EVENT,
@@ -8,13 +8,13 @@ import {
8
8
  SLASH_SUBAGENT_RESPONSE_EVENT,
9
9
  SLASH_SUBAGENT_STARTED_EVENT,
10
10
  SLASH_SUBAGENT_UPDATE_EVENT,
11
- } from "../shared/types.ts";
11
+ } from "../shared/types.js";
12
12
  import {
13
13
  type BridgeRequestSettlement,
14
14
  emitBridgeEvent,
15
15
  readBridgeRequestSettlement,
16
16
  rejectStoppedBridgeRequest,
17
- } from "./bridge-settlement.ts";
17
+ } from "./bridge-settlement.js";
18
18
 
19
19
  interface SlashSubagentRequest {
20
20
  requestId: string;
@@ -8,8 +8,8 @@ import {
8
8
  keyHintIfBound,
9
9
  } from "@bastani/atomic";
10
10
  import { Key, matchesKey } from "@earendil-works/pi-tui";
11
- import { discoverAgents } from "../agents/agents.ts";
12
- import type { SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
11
+ import { discoverAgents } from "../agents/agents.js";
12
+ import type { SubagentParamsLike } from "../runs/foreground/subagent-executor.js";
13
13
  import {
14
14
  type SingleResult,
15
15
  SLASH_RESULT_TYPE,
@@ -19,10 +19,10 @@ import {
19
19
  SLASH_SUBAGENT_STARTED_EVENT,
20
20
  SLASH_SUBAGENT_UPDATE_EVENT,
21
21
  type SubagentState,
22
- } from "../shared/types.ts";
23
- import { registerBridgeRequestSettlement } from "./bridge-settlement.ts";
24
- import type { SlashSubagentResponse, SlashSubagentUpdate } from "./slash-bridge.ts";
25
- import { applySlashUpdate, buildSlashInitialResult, failSlashResult, finalizeSlashResult } from "./slash-live-state.ts";
22
+ } from "../shared/types.js";
23
+ import { registerBridgeRequestSettlement } from "./bridge-settlement.js";
24
+ import type { SlashSubagentResponse, SlashSubagentUpdate } from "./slash-bridge.js";
25
+ import { applySlashUpdate, buildSlashInitialResult, failSlashResult, finalizeSlashResult } from "./slash-live-state.js";
26
26
 
27
27
  interface InlineConfig {
28
28
  output?: string | false;
@@ -1,8 +1,8 @@
1
1
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
2
2
  import type { Message } from "@earendil-works/pi-ai/compat";
3
- import type { SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
4
- import { type Details, type SingleResult, SLASH_RESULT_TYPE, type Usage } from "../shared/types.ts";
5
- import type { SlashSubagentResponse, SlashSubagentUpdate } from "./slash-bridge.ts";
3
+ import type { SubagentParamsLike } from "../runs/foreground/subagent-executor.js";
4
+ import { type Details, type SingleResult, SLASH_RESULT_TYPE, type Usage } from "../shared/types.js";
5
+ import type { SlashSubagentResponse, SlashSubagentUpdate } from "./slash-bridge.js";
6
6
 
7
7
  export interface SlashMessageDetails {
8
8
  requestId: string;
@@ -1,5 +1,5 @@
1
- import { formatModelThinking } from "../shared/formatters.ts";
2
- import type { Theme } from "./render-layout.ts";
1
+ import { formatModelThinking } from "../shared/formatters.js";
2
+ import type { Theme } from "./render-layout.js";
3
3
 
4
4
  export function modelThinkingBadge(theme: Theme, model?: string, thinking?: string, fastMode?: boolean): string {
5
5
  const label = formatModelThinking(model, thinking, fastMode);
@@ -1,6 +1,6 @@
1
1
  import type { ExtensionContext } from "@bastani/atomic";
2
2
  import { visibleWidth } from "@earendil-works/pi-tui";
3
- import type { AgentProgress } from "../shared/types.ts";
3
+ import type { AgentProgress } from "../shared/types.js";
4
4
 
5
5
  export type Theme = ExtensionContext["ui"]["theme"];
6
6
 
@@ -1,5 +1,5 @@
1
- import { formatAgentRunningLabel } from "../shared/status-format.ts";
2
- import type { Details } from "../shared/types.ts";
1
+ import { formatAgentRunningLabel } from "../shared/status-format.js";
2
+ import type { Details } from "../shared/types.js";
3
3
 
4
4
  export function isDoneResult(result: Details["results"][number]): boolean {
5
5
  const status = result.progress?.status;
@@ -1,11 +1,11 @@
1
1
  import { keyHintIfBound } from "@bastani/atomic";
2
2
  import { type Component, Container, Text } from "@earendil-works/pi-tui";
3
- import { shortenPath } from "../shared/formatters.ts";
4
- import type { AgentProgress, Details } from "../shared/types.ts";
5
- import { getSingleResultOutput } from "../shared/utils.ts";
6
- import { modelThinkingBadge } from "./render-event-formatting.ts";
7
- import { getTermWidth, pulseGlyph, type Theme, truncLine } from "./render-layout.ts";
8
- import { buildMultiProgressLabel, resultRowLabel } from "./render-progress.ts";
3
+ import { shortenPath } from "../shared/formatters.js";
4
+ import type { AgentProgress, Details } from "../shared/types.js";
5
+ import { getSingleResultOutput } from "../shared/utils.js";
6
+ import { modelThinkingBadge } from "./render-event-formatting.js";
7
+ import { getTermWidth, pulseGlyph, type Theme, truncLine } from "./render-layout.js";
8
+ import { buildMultiProgressLabel, resultRowLabel } from "./render-progress.js";
9
9
  import {
10
10
  buildLiveStatusLine,
11
11
  compactCurrentActivity,
@@ -18,7 +18,7 @@ import {
18
18
  snapshotNowForProgress,
19
19
  statJoin,
20
20
  themeBold,
21
- } from "./render-status-progress.ts";
21
+ } from "./render-status-progress.js";
22
22
 
23
23
  export function renderSingleCompact(
24
24
  d: Details,
@@ -1,19 +1,19 @@
1
1
  import { getMarkdownTheme, keyHintIfBound } from "@bastani/atomic";
2
2
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
3
3
  import { type Component, Container, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
4
- import { formatDuration, formatTokens, formatUsage, shortenPath } from "../shared/formatters.ts";
5
- import type { AgentProgress, Details } from "../shared/types.ts";
6
- import { getSingleResultOutput } from "../shared/utils.ts";
7
- import { modelThinkingBadge } from "./render-event-formatting.ts";
8
- import { getTermWidth, type Theme, truncLine } from "./render-layout.ts";
9
- import { buildMultiProgressLabel, resultRowLabel } from "./render-progress.ts";
4
+ import { formatDuration, formatTokens, formatUsage, shortenPath } from "../shared/formatters.js";
5
+ import type { AgentProgress, Details } from "../shared/types.js";
6
+ import { getSingleResultOutput } from "../shared/utils.js";
7
+ import { modelThinkingBadge } from "./render-event-formatting.js";
8
+ import { getTermWidth, type Theme, truncLine } from "./render-layout.js";
9
+ import { buildMultiProgressLabel, resultRowLabel } from "./render-progress.js";
10
10
  import {
11
11
  advanceResultPulseFrame,
12
12
  clearResultAnimationTimer,
13
13
  type ResultAnimationContext,
14
- } from "./render-result-animation.ts";
15
- import { renderMultiCompact, renderSingleCompact } from "./render-result-compact.ts";
16
- import { subagentResultRenderKey } from "./render-stable-output.ts";
14
+ } from "./render-result-animation.js";
15
+ import { renderMultiCompact, renderSingleCompact } from "./render-result-compact.js";
16
+ import { subagentResultRenderKey } from "./render-stable-output.js";
17
17
  import {
18
18
  buildLiveStatusLine,
19
19
  displayProgressDurationMs,
@@ -22,7 +22,7 @@ import {
22
22
  getToolCallLines,
23
23
  hasEmptyTextOutputWithoutOutputTarget,
24
24
  snapshotNowForProgress,
25
- } from "./render-status-progress.ts";
25
+ } from "./render-status-progress.js";
26
26
 
27
27
  export function renderLiveSubagentResult(
28
28
  result: AgentToolResult<Details>,
@@ -1,5 +1,5 @@
1
1
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
2
- import type { AgentProgress, Details } from "../shared/types.ts";
2
+ import type { AgentProgress, Details } from "../shared/types.js";
3
3
 
4
4
  export function progressRenderKey(progress: Partial<AgentProgress> | undefined): string {
5
5
  if (!progress) return "";
@@ -1,8 +1,8 @@
1
- import { formatDuration, formatTokens, formatToolCall } from "../shared/formatters.ts";
2
- import { formatActivityLabel } from "../shared/status-format.ts";
3
- import type { AgentProgress, Details } from "../shared/types.ts";
4
- import { getDisplayItems } from "../shared/utils.ts";
5
- import { getTermWidth, pulseGlyph, type Theme } from "./render-layout.ts";
1
+ import { formatDuration, formatTokens, formatToolCall } from "../shared/formatters.js";
2
+ import { formatActivityLabel } from "../shared/status-format.js";
3
+ import type { AgentProgress, Details } from "../shared/types.js";
4
+ import { getDisplayItems } from "../shared/utils.js";
5
+ import { getTermWidth, pulseGlyph, type Theme } from "./render-layout.js";
6
6
 
7
7
  export function extractOutputTarget(task: string): string | undefined {
8
8
  const writeToMatch = task.match(/\[Write to:\s*([^\]\n]+)\]/i);
@@ -12,12 +12,12 @@ export {
12
12
  RUNNING_ANIMATION_MS,
13
13
  RUNNING_FRAMES,
14
14
  runningPulseGlyph,
15
- } from "./render-layout.ts";
16
- export { renderLiveSubagentResult, renderSubagentResult } from "./render-result.ts";
17
- export type { SubagentResultRenderState } from "./render-result-animation.ts";
15
+ } from "./render-layout.js";
16
+ export { renderLiveSubagentResult, renderSubagentResult } from "./render-result.js";
17
+ export type { SubagentResultRenderState } from "./render-result-animation.js";
18
18
  export {
19
19
  advanceResultPulseFrame,
20
20
  clearLegacyResultAnimationTimer,
21
21
  clearResultAnimationTimer,
22
22
  stopResultAnimations,
23
- } from "./render-result-animation.ts";
23
+ } from "./render-result-animation.js";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/web-access",
3
- "version": "0.9.13",
3
+ "version": "0.9.14-alpha.2",
4
4
  "private": true,
5
5
  "description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
6
6
  "contributors": [
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "peerDependencies": {
33
33
  "@bastani/atomic": "*",
34
- "@earendil-works/pi-tui": "^0.84.1"
34
+ "@earendil-works/pi-tui": "^0.84.2"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@bastani/atomic": {
@@ -6,6 +6,63 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.9.14-alpha.2] - 2026-08-17
10
+
11
+ ### Breaking Changes
12
+
13
+ - `open-claude-design` removes the `max_refinements` input, the `approved_for_export` and `refinements_completed` outputs, and the `<artifact_dir>/feedback/` feedback artifact. A run now performs one `generate-1`, an optional live review, and export; callers must stop supplying, reading, or expecting those fields and artifacts ([#2401](https://github.com/bastani-inc/atomic/issues/2401)).
14
+
15
+ ### Added
16
+
17
+ - Added optional per-attempt `timeoutMs` deadlines to `ctx.tool`. Expiry aborts the attempt signal, records a timeout-specific diagnostic, participates in retries, and follows the existing throwing or typed `failureMode: "return"` behavior; each retry gets a fresh signal and deadline, while omitted timeouts preserve existing behavior ([#2424](https://github.com/bastani-inc/atomic/issues/2424)).
18
+ - Stage control registries expose `has(runId)` so a pruned registration map is distinguishable from an empty one after `clearDetached()` ([#2462](https://github.com/bastani-inc/atomic/issues/2462)).
19
+ - Refined `ctx.tool` graph inspection into one read-only agent-chat-style tool message block. Enter, click, or switcher selection opens it collapsed by default with the tool call and a compact bounded result/error preview; the configured `app.tools.expand` action (`ctrl+o` by default) toggles full bounded args, result/error, callback source, timing, and cached/replayed markers. The block preserves keyboard and mouse scrolling, narrow-terminal layout, status styling, Escape/return navigation, `attachable: false`, and no attach, steer, interrupt, resume, or editable transcript affordances. Hostile payloads now cross precise typed boundaries with one own-key discovery call and bounded descriptor/value work for both retention and display, explicit cycle/accessor/conversion placeholders, and collision-safe truncation markers; the runtime's own key-list materialization remains outside the module's control, while durable checkpoints still keep exact output and raw-args `argsHash` identity ([#2427](https://github.com/bastani-inc/atomic/issues/2427)).
20
+
21
+ ### Removed
22
+
23
+ - Removed find-in-stage-chat. `Ctrl+Shift+F` in an attached workflow stage chat no longer opens a search box over that chat.
24
+
25
+ ### Changed
26
+
27
+ - Redesigned the `ctx.tool` inspection surface as a shaded host-style operator card: a `$` call header, a tail preview taken from the fully bounded result/error body with an exact earlier-lines expand hint, `Took`/`Elapsed` timing, status-tinted tool backgrounds that cover every cell of the card, callback source only in the expanded view, and a graph statusline that advertises the configured expand key as `expand`/`collapse` alongside return-to-graph and scroll controls. Plain rendering remains ANSI-free at narrow widths, and capped payload wrapping now scans once without changing its visual output. The forensic ARGS/RESULT/SOURCE/TIMING/MARKERS field table is gone from the operator surface.
28
+ - Synchronized the complete bundled `impeccable` skill tree from upstream `skill-v4.0.3` (`68b1129634a1cdd9a0ba50b27376c71b4b083ae8`) to `skill-v4.1.1` (`5a149f3fdb1b5793f10567233b1dcab98fc305fd`), adding persisted Live roots, framework-aware injection, prompt embedding, CSS acceptance checks, Svelte AST support, mount verification, UI-surface contracts, and the latest detector and design guidance. The sync removes obsolete `scripts/live/ui-core.mjs`, keeps the Cursor-only `scripts/hook-before-edit.mjs` omitted, and retains Atomic's package-path and security adaptations ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
29
+ - Impeccable concept rolls now include platform, grain, register, and card-kind fields and use a bounded `impeccable.style` fallback when no local catalog exists. The OpenAI image fallback supports reference-image edits and generated images only when `OPENAI_API_KEY` is present, warns about account spend, and embeds each prompt in the image or a sidecar ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
30
+ - Removed upstream Impeccable's outbound telemetry and update check from the bundled skill. Upstream 4.1.1 posts an anonymous attended-choice ping to `impeccable.style` unless `IMPECCABLE_NO_TELEMETRY` or `DO_NOT_TRACK` is set, and polls `/api/version` once a day to suggest `npx impeccable update`. Atomic ships neither: the ping is removed outright rather than defaulted off, and the update check is dropped because a vendored skill cannot self-update and its version ships with Atomic releases. The only request the concept roll can still make is the catalog `GET /api/roll`, which carries scope, mode, an eight-hex seed key, and a re-roll counter, and no project files, prompts, code, or conversation context ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
31
+ - The `open-claude-design` run-level review gate and the session-start stage now state how a review ends — exit in the Impeccable overlay, closing the browser tab, or `exit live` — that the session waits indefinitely until then, and that ending it exports the design as it stands with no further round ([#2401](https://github.com/bastani-inc/atomic/issues/2401)).
32
+ - The live review session is the final review boundary: the workflow-owned poll loop dispatches `generate`, `steer`, `manual_edit_apply`, and failed variant mounts to model stages, keeps successful mounts journal-only, ends on the helper's `exit` event, and exports the preview as it stands without a summary, second opinion, decision, or later review session ([#2401](https://github.com/bastani-inc/atomic/issues/2401), [#2382](https://github.com/bastani-inc/atomic/issues/2382)).
33
+ - The run-level gate retains `Start live review` and `Skip remaining review rounds and export as-is`; the skip choice exports immediately without opening the session ([#2401](https://github.com/bastani-inc/atomic/issues/2401)).
34
+ - Added model-visible workflow source-layout guidance: keep compact workflows in one entry file, and extract only cohesive prompt, schema/type, model-policy, deterministic-helper, or child-workflow concerns at meaningful boundaries while keeping graph control flow visible in the entry file ([#2451](https://github.com/bastani-inc/atomic/issues/2451)).
35
+ - Migrated the built-in Goal, Ralph, and open-claude-design model chains from active GLM-5.2 entries to direct Z.AI `zai/glm-5.3:high` and `zai-coding-cn/glm-5.3:high` fallbacks. OpenRouter's unavailable GLM-5.3 model is intentionally omitted rather than shipped as a placeholder ([#2459](https://github.com/bastani-inc/atomic/issues/2459)).
36
+
37
+ ### Fixed
38
+
39
+ - Hardened the synced Impeccable executables against shell-based browser launch, remote browser URLs, project-root and symlink escapes, unsafe persisted roots and injection journals, non-atomic generated writes, untrusted live instructions, read failures reported as clean, and unbounded or malformed live protocol values. The `open-claude-design` loop now handles 4.1.1 mount failures, preserves the full event payload, replies with the required event id and status, and fails on helper process errors ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
40
+ - Operator-card wrapping no longer drops a `/` or punctuation that could not fit on a truncated row.
41
+ - An unbound `app.tools.expand` no longer leaves a keyless `expand`/`collapse` label on the `ctx.tool` operator-card statusline. The card body already dropped the key from `... (N earlier lines)`; the statusline now matches.
42
+ - Workflow run-scoped singletons now survive `/reload`'s module re-evaluation. The replacement extension instance re-binds its store, stage-control registry, cancellation registry, tool-control registry, job tracker, and stage UI broker to the host session-scoped state, so an in-flight run stays visible and controllable instead of vanishing behind empty replacements. Adopting a previously unseen host session creates a fresh instance instead of handing that session the previous session's live object, so controls invoked from the new session cannot cancel or mutate the prior run ([#2462](https://github.com/bastani-inc/atomic/issues/2462) by [@makgunay](https://github.com/makgunay)).
43
+ - Process-preserving session boundaries (`/reload`, `/fork`, `/new`, `/resume`) no longer kill in-flight workflow runs or drop live executor stage handles; the run keeps executing. `/reload` reuses the host event bus, so the replacement session can still list a run, report its real state, and answer a stage awaiting input. `/new`, `/resume`, and `/fork` build a new event bus, so the successor session gets fresh registries and does not list the run. `startup` and unrecognised start reasons still clear, and a real `quit` still pauses, clears the registry, and shuts DBOS down exactly once ([#2462](https://github.com/bastani-inc/atomic/issues/2462), [#2247](https://github.com/bastani-inc/atomic/issues/2247) by [@makgunay](https://github.com/makgunay)).
44
+ - DBOS lifecycle state and the registered `atomicWorkflowHandle` / `atomicWorkflowCheckpoint` wrappers now live in a process-global `globalThis` slot keyed with `Symbol.for`, so a re-evaluated workflows bundle reuses the original registrations instead of colliding with the still-live SDK registry and silently falling back to an in-memory backend. A later `configureDbosDurableBackend` call after `DBOS.launch` recovers those wrappers and does not call `setConfig` again. A real quit still flushes and shuts DBOS down exactly once ([#2462](https://github.com/bastani-inc/atomic/issues/2462), [#2022](https://github.com/bastani-inc/atomic/issues/2022) by [@makgunay](https://github.com/makgunay)).
45
+ - A duplicate DBOS operation registration is no longer reported as a Postgres provisioning failure. The durability error and the non-durable fallback warning now name the registration conflict and no longer suggest changing `DBOS_SYSTEM_DATABASE_URL`. Classification uses the SDK `Error.DBOSConflictingRegistrationError` class and `dbosErrorCode`, not message wording. A wrapper whose `cause`, `name`, or `message` getter throws stays `other` and keeps the original failure in the diagnostic instead of replacing it with the inspection trap. Reading the failure detail for the wrapper itself also uses the guarded accessor, so a throwing `message` getter cannot escape as a raw exception ([#2462](https://github.com/bastani-inc/atomic/issues/2462), [#2022](https://github.com/bastani-inc/atomic/issues/2022) by [@makgunay](https://github.com/makgunay)).
46
+ - Fixed `workflow send` answers for primitive human-in-the-loop prompts. Confirm answers now preserve booleans and accept the documented yes/no labels, select answers resolve case-insensitive labels or 1-based indexes instead of silently choosing the first option, and unusable answers remain pending with a helpful no-op response ([#2417](https://github.com/bastani-inc/atomic/pull/2417) by [@makgunay](https://github.com/makgunay)).
47
+ - Separated schema-backed workflow result data from runner-owned output artifacts. When a stage configures both `schema` and `output`, the successful `structured_output` arguments now remain the typed machine-readable result while ordered ordinary text blocks from that exact tool-call message become the human-readable artifact. The runner snapshots both against the successful tool-call id so correction attempts and late admitted turns cannot replace either result; missing prose is written empty with an explicit warning instead of silently persisting JSON ([#2198](https://github.com/bastani-inc/atomic/issues/2198)).
48
+ - Separated schema-backed workflow result data from runner-owned output artifacts. When a stage configures both `schema` and `output`, the successful `structured_output` arguments now remain the typed machine-readable result while ordered ordinary text blocks from that exact tool-call message become the human-readable artifact. The runner snapshots both against the successful tool-call id so correction attempts and later admitted turns cannot replace either result, and never serializes the tool arguments into the artifact. When the successful message carries no ordinary text — including after a model-fallback session recreation that leaves the live session without that message — the artifact falls back to the most recent earlier assistant text that made no `structured_output` call, and only when no such text exists is it written empty with an explicit warning. Corrective prompts for schema-and-output stages keep the validation-failure guidance, schema-only stages keep their existing result-text behavior, and the builtin `adversarial-verification`, `generate-and-filter`, `tournament`, and `loop-until-done` workflows now persist their structured decisions themselves so their `*.json` inter-stage artifacts remain machine-readable ([#2198](https://github.com/bastani-inc/atomic/issues/2198)).
49
+
50
+ ### Removed
51
+
52
+ - Removed the live-review feedback module and all `<artifact_dir>/feedback/` artifacts, including the JSON record, `iteration-N.md` copy, and annotated-snapshot copies. No feedback directory is written during a run ([#2401](https://github.com/bastani-inc/atomic/issues/2401)).
53
+
54
+ ## [0.9.14-alpha.1] - 2026-08-14
55
+
56
+ ### Added
57
+
58
+ - Added `heartbeatIntervalMinutes` to the workflow authoring surface: an optional cadence in minutes that resolves to the `15`-minute default when omitted, treats `0` as an explicit disable, and rejects negative and non-finite values with a `TypeError` while the definition is authored, so a bad cadence fails at authoring rather than at schedule time. Every compiled definition carries the resolved value, and a distinct `workflows:workflow-heartbeat` event contract is declared alongside it — run id, workflow name, start time, scheduled time, and interval, with heartbeat identity keyed by run id plus scheduled time. The default interval constant, heartbeat custom type, and heartbeat event types are exported from the `@bastani/workflows` package root ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
59
+ - Added workflow heartbeat scheduling and queued parent delivery for `heartbeatIntervalMinutes`, so a positive cadence now produces real heartbeats. While a top-level run is active, one heartbeat is raised per `startedAt + n × interval` boundary computed from the run's persisted start time — never from the previous delivery — so a slow send, a retry, or a process restart cannot shift the cadence. A resolved interval of `0` creates no timer and no durable record at all. One globally-next-due wake-up serves every enabled run rather than one recurring timer per run. At most one heartbeat per run is outstanding at a time: an outstanding heartbeat holds its slot until its card is actually consumed into the conversation — not merely until the parent's turn ends, which can happen while the card is still queued or its queue is paused — so a boundary that falls before that is skipped rather than stacked behind it, and the cadence then resumes at the first future boundary. However long a turn runs, and however often the queue is paused, only one unread heartbeat per run is ever waiting on a host that reports message consumption, which Atomic's chat host does. Delivery reuses the lifecycle-notice parent path (`triggerTurn`, `deliverAs: "steer"`, `persistWhenStreaming`) under the distinct `workflows:workflow-heartbeat` custom type with the five-field payload, so a busy parent chat is queued and never interrupted. Paused runs emit nothing and receive no backfill; a resumed or restarted run takes the first future boundary. Simultaneously due heartbeats reach the parent in scheduled-time order with the run id as the stable tie-break — a heartbeat being retried holds its place rather than letting a later one overtake it — terminal state is re-checked immediately before enqueue, again immediately before processing, and again before every delivery attempt including retries, and nested child workflow runs never heartbeat the parent chat. A run keeps the cadence its own definition was authored with, so editing, renaming, deleting, or reloading a workflow mid-run changes what the next launch uses and leaves runs already in flight on their launch cadence; the anchor record carries that cadence too, so it survives a durable resume. A run that launched with heartbeats disabled writes no durable record at all, so if it is resumed in a new process it adopts whatever the workflow then declares. A cadence below a millisecond schedules at the finest representable instant, and the cadence range carries a documented representable upper limit: above roughly 3 × 10^303 minutes `startedAt + interval` exceeds the largest finite timestamp, so no first boundary exists, nothing is scheduled, no durable record is written, and `ATOMIC_WORKFLOW_DEBUG=1` says so — such a cadence stays a valid positive interval but delivers no heartbeat, and `0` remains the only value that declares heartbeats off. A durable resume re-dispatches under the original run id but records a fresh start time, so each run also writes one reserved durable cadence-anchor record as soon as it has durable progress of its own, before its first boundary comes due; the anchor is read only as the earlier of itself and the run's current start time, so it keeps a resumed run on its original cadence without being able to move a boundary or raise a missed one. The delivered card names the workflow, run id, cadence, and elapsed run time and hints `/workflow status <run-id>`, rendered through the existing workflow notice-card renderer ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
60
+ - Added terminal heartbeat cleanup and restart recovery, so a workflow's heartbeats stop when the run does. Reaching any terminal status — completed, failed, blocked, skipped, cancelled, or killed — drops everything that run's cadence held in one pass: its armed wake-up, its next scheduled boundary, its outstanding slot and the card text held for it, any heartbeat of its own still waiting in the delivery queue along with the retry timer that belonged to it, and its cadence and durable-anchor memos. No pending timer and no queued heartbeat outlives the run that owns it. The pass is idempotent: repeating it creates no state, resurrects no schedule, and does not throw, including for a run the scheduler never saw. Both completion races converge on suppression — a run that finishes before its due boundary is enqueued has that boundary dropped and is refused at enqueue, and one that finishes after enqueue but before processing has its queued identity discarded rather than sent. Cleanup keys on the run's observed state rather than on a transition event, so it also covers the paths that reach a terminal snapshot without a normal end transition — durable replay, completed-catalog reconstruction, and a restore that inserts an already-failed run — and the same pass runs at startup, making it the recovery pass: a stale durable anchor or leftover queued record belonging to an already-terminal run is discarded rather than replayed, its anchor is neither read nor rewritten, and a run the store no longer holds is dropped the same way. An active run is never affected by another run's cleanup, a paused run keeps the floor that stops it re-raising a boundary it already delivered, and recovery for an active run still selects the first future boundary rather than replaying a missed one. A late durable acknowledgement or a send that settles after cleanup re-creates nothing. A heartbeat the chat host had already accepted into the parent's queue is past that pass, because no queued message can be withdrawn, so it is invalidated at the moment the parent reads it instead: a heartbeat whose run has since reached a terminal state, or whose run this process no longer knows at all, is excluded from the model's context and never steers the parent about a run that is over. That closes both remaining stale paths — a card parked through a long turn while its run finished, and a card recovered from a previous process at startup, which would otherwise replay a boundary raised before the restart. The card already rendered in the transcript is deliberately left in place as a true record that the heartbeat was raised; only the model-facing steer is invalidated ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
61
+ A run that is only blocked on a recoverable provider or rate-limit failure remains stored as `running` and resumable: it raises no new heartbeat while blocked, but keeps its cadence state and any card already waiting with the parent. Cleanup runs only when the run's own status is terminal.
62
+ Parent pickup is keyed by the typed `workflows:workflow-heartbeat` entry and exact run id plus scheduled time rather than rendered card text, so a foreign custom message cannot release an unread heartbeat's slot and a durable resume that reuses the run id cannot revive an old admitted card after terminal cleanup ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
63
+ The cadence-anchor record is now written at the durability boundary itself, so it is durable before the checkpoint that made the run resumable is acknowledged. The scheduler's own write is guarded against runs with no durable progress and can therefore only be issued after resumability already exists; a process that exited inside that window left a resumable run carrying no record of what it launched with, and the next process then took both a freshly minted start time and whatever cadence the definition declared by then, shifting the phase and the cadence of a run already in flight ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
64
+ - Every bundled builtin workflow now states its heartbeat cadence rather than inheriting it. `adversarial-verification`, `classify-and-act`, `fan-out-and-synthesize`, `generate-and-filter`, `goal`, `loop-until-done`, `ralph`, and `tournament` declare the `15`-minute default explicitly, so these long autonomous runs report to the parent chat on a known cadence and a future change to the global default cannot silently re-cadence them. `open-claude-design` sets `0` and runs quiet: it is driven by the user reviewing generated HTML turn by turn, so the parent chat is already holding it to its goal and a periodic alignment steer would interrupt that review rather than inform it. Behaviour is unchanged for the eight that were already resolving to the default; only `open-claude-design` changes ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
65
+
9
66
  ## [0.9.13] - 2026-08-13
10
67
 
11
68
  Cumulative release of the `0.9.13-alpha.1` – `0.9.13-alpha.4` prereleases. The summary below covers the user-visible outcome of that work; the per-change detail remains in the prerelease sections below.
@@ -82,6 +82,23 @@ Sketch branches, loops, and nested boundaries before launch. Bounded loops must
82
82
 
83
83
  Execution, replay, and DBOS hydration are the authoritative topology-validation points. Runtime topology changes should add incremental edge checks and DBOS hydration validation; prompt guidance and TypeScript types cannot replace these checks.
84
84
 
85
+ ### Workflow source layout
86
+
87
+ Keep a small, readable workflow in one entry file. Do not split short one-use prompts, create one file per stage, add wrapper-only modules, hide the graph across files, or use line counts alone as a module boundary.
88
+
89
+ At a meaningful source boundary that improves clarity, reuse, ownership, or testability, keep the graph and control flow in the top-level workflow entry file and extract cohesive concerns: long or reused prompt builders; shared TypeBox schemas and workflow-specific types; model-policy constants shared by several stages; deterministic helpers with their own testable behavior; or reusable child workflow definitions.
90
+
91
+ Put support modules in a subdirectory below the top-level discovery directory — either one owned by a single workflow or a shared support directory for several workflows. Project and user discovery scans only top-level `.ts`/`.js`/`.mjs`/`.cjs` files in the workflow directory; the scan is non-recursive, so support modules in subdirectories are not scanned as extra top-level workflow candidates. Use `.js` import extensions from TypeScript source.
92
+
93
+ The existing `.atomic/workflows/release-docs.ts` keeps its graph in the entry file and imports deterministic helpers from `.atomic/workflows/lib/release-docs.ts`, a shared support directory that also holds the separate `publish-release` helper. For example:
94
+
95
+ ```text
96
+ .atomic/workflows/code-review.ts
97
+ .atomic/workflows/code-review/prompts.ts
98
+ .atomic/workflows/code-review/schemas.ts
99
+ .atomic/workflows/code-review/model-policy.ts
100
+ ```
101
+
85
102
  ### Workflow-owned side effects
86
103
 
87
104
  Prefer `ctx.tool(name, args, fn)` for workflow-owned TypeScript operations with side effects, including filesystem writes, network mutations, external API actions, and similar deterministic operations orchestrated directly by the workflow definition. Each invocation creates a non-chat, non-attachable durable graph node before `fn` runs; it may appear before, between, after, or without model stages. Atomic durably caches a completed call's serializable result, so resume returns that result without rerunning `fn` or repeating the side effect. Tool-only workflows are valid tracked execution, while a normal return with no stage, child, tool, or explicit exit remains invalid. Keep pure computation and side-effect-free transformations as ordinary TypeScript. Do not wrap agent-stage internals or every function call indiscriminately. The executor closes tool admission before publishing any terminal outcome; calling a retained `ctx.tool` function afterward returns a rejected native promise and creates no callback, retry, graph node, or checkpoint.
@@ -422,6 +439,8 @@ const decision = await ctx.stage("review-gate", { schema: Decision }).prompt(
422
439
 
423
440
  Atomic registers the canonical `structured_output` tool only for schema-enabled items and automatically adds it to explicit `tools` allowlists. The schema is used directly as the tool argument contract. A schema-backed `StageContext` supports one `prompt()` call because the final-answer tool is a single result contract; create another `ctx.stage(..., { schema })` for another structured prompt. If a turn completes without calling `structured_output`, or the tool call fails schema validation, Atomic sends up to three corrective follow-up prompts that include the exact contract/validation error before failing the item. `ctx.task`/`ctx.chain`/`ctx.parallel` results expose the captured value as `result.structured` and keep `result.text` as formatted JSON for handoffs.
424
441
 
442
+ When an item configures both `schema` and `output`, its successful `structured_output` turn has two separate channels: all ordinary assistant text blocks from that exact message, in order, form the human-readable artifact written to `output`, while the successful tool arguments remain the typed machine-readable workflow result. Atomic never serializes those arguments into the artifact. The runner snapshots the result together with the exact successful tool-call id, so corrective attempts, another call with the same tool name, and later admitted turns cannot replace either side of the pairing. When the successful message has no ordinary text — including after a model-fallback session recreation that leaves the live session without that message — Atomic falls back to the most recent earlier assistant text that made no `structured_output` call; only when no such text exists is the artifact written empty, with the standard empty-artifact warning in the receipt. Items with `schema` but no `output` keep their existing result-text behavior.
443
+
425
444
  `subagent` is available as a default workflow-stage tool with the same five-level nesting budget as main chat: a stage can launch recursively delegated subagents until the shared depth guard reaches five delegated levels, then deeper calls are blocked. `tools` allowlists apply to bundled extension tools as well as built-ins; if a stage sets `tools`, list every tool it should see. Workflow stages can explicitly list `subagent`, `web_search`, `fetch_content`, `intercom`, and other loaded extension tools, while `excludedTools` and `noTools: "all"` still win. Bundled `@bastani/subagents` agent definitions are available to the `subagent` tool in workflow stages, including workflows launched from a subagent child process.
426
445
 
427
446
  ### Model fallbacks
@@ -635,7 +654,7 @@ Tradeoff: `Type.Unsafe<T>()` does not deeply validate at runtime — it trusts t
635
654
 
636
655
  Input overrides are bare `key=value` tokens (no leading `--`). Values are JSON-parsed when possible, so numbers, booleans, and quoted strings work as expected (e.g. `count=3`, `flag=true`, `prompt="multi word value"`). A whole-object override can be passed as a single JSON token (e.g. `{"prompt":"...","count":3}`). Runtime validation is strict: unknown input keys, missing required values, type mismatches, and invalid `select` choices fail before a named workflow run starts.
637
656
 
638
- Named workflow launches always run as **background tasks** in interactive sessions. Run `/workflow connect <run>` to see agents working and chat with and steer each stage. Foreground launches are reserved for explicit user requests or technical requirements, with notice before launch. Press **F2** to open the same live graph viewer; HIL prompts (`ctx.ui.input/confirm/select/editor/custom`) appear as awaiting-input graph nodes. Press Enter on a focused node, or click a visible graph node directly, to open that stage and answer locally, never as a modal dialog over the chat. `ctrl+x` is the workflow hierarchy chord: attached stage chats show **ctrl+x return to graph**, while graph surfaces show **ctrl+x leave graph · return to main chat**. Workflow surfaces consume it before configurable editor/tool actions. Composer and prompt drafts survive leaving a stage, and pending custom questions remain pending for reattachment. `ctrl+d` and `q` are not workflow navigation controls; ordinary editor/prompt Ctrl+D behavior and printable prompt `q` remain available. Existing `esc`, `ctrl+c`, and graph `h` close/hide behavior is unchanged. While the graph pane is active, vertical wheel/trackpad gestures pan vertically and horizontal gestures pan wide graphs left and right when the terminal reports them, without falling through to the main chat or terminal scrollback. Focused graph and stage-chat overlays receive those gestures through the fullscreen application route. Fullscreen pi-tui owns application selection, so drag and multi-click selection also work over workflow overlays; copied text uses OSC 52, and terminals that refuse OSC 52 writes rely on the modifier-drag bypass (Shift/Option, as provided by the terminal). `ctrl+t` is not a workflow control: focused workflow overlays leave it to the host `app.thinking.toggle` action, while inline tree selectors keep `app.tree.filter.noTools`. Human input is detected when those runtime `ctx.ui.*` calls execute; workflows no longer have a declaration-time HIL flag.
657
+ Named workflow launches always run as **background tasks** in interactive sessions. Run `/workflow connect <run>` to see agents working and chat with and steer each stage. Foreground launches are reserved for explicit user requests or technical requirements, with notice before launch. Press **F2** to open the same live graph viewer; HIL prompts (`ctx.ui.input/confirm/select/editor/custom`) appear as awaiting-input graph nodes. Press Enter on a focused node, click a visible graph node, or choose one from the switcher to open a `ctx.tool` node's one read-only agent-chat-style tool message block, never a modal dialog or editable transcript. Tool nodes remain non-attachable: their graph card body is always the constant `durable tool`, and the message block is collapsed by default with the tool name/call and a compact bounded result or error preview. The configured `app.tools.expand` action (`ctrl+o` by default) toggles full bounded args, result or error, callback source, timing, and cached/replayed markers. `↑`/`↓`, `PageUp`/`PageDown`, `Home`/`End`, the wheel, and the scrollbar scroll the block; Escape or `ctrl+x` returns to the graph. It is read-only and offers no attach, steer, interrupt, or resume action. `ctrl+x` is the workflow hierarchy chord: attached stage chats show **ctrl+x return to graph**, while graph surfaces show **ctrl+x leave graph · return to main chat**. Workflow surfaces consume it before configurable editor/tool actions. Composer and prompt drafts survive leaving a stage, and pending custom questions remain pending for reattachment. `ctrl+d` and `q` are not workflow navigation controls; ordinary editor/prompt Ctrl+D behavior and printable prompt `q` remain available. `esc`, `ctrl+c`, and graph `h` close/hide behavior are unchanged. While the graph pane is active, vertical wheel/trackpad gestures pan vertically and horizontal gestures pan wide graphs left and right when the terminal reports them, without falling through to the main chat or terminal scrollback. Focused graph and stage-chat overlays receive those gestures through the fullscreen application route. Fullscreen pi-tui owns application selection, so drag and multi-click selection also work over workflow overlays; copied text uses OSC 52, and terminals that refuse OSC 52 writes rely on the modifier-drag bypass (Shift/Option, as provided by the terminal). `ctrl+t` is not a workflow control: focused workflow overlays leave it to the host `app.thinking.toggle` action, while inline tree selectors keep `app.tree.filter.noTools`. Human input is detected when those runtime `ctx.ui.*` calls execute; workflows no longer have a declaration-time HIL flag.
639
658
 
640
659
  Typing into an attached stage chat and pressing Enter steers: the message is consumed after the current assistant response finishes its tool batch and before the next model request, matching normal session steering. Ctrl+F queues a follow-up, consumed only when the agent would otherwise stop. Queued entries belong to the stage session rather than the pane, so leaving the stage and reattaching restores the pending `Steering:` / `Follow-up:` rows, and a detached stage node carries a `✉ N queued` badge in the graph.
641
660
 
@@ -658,7 +677,7 @@ Raw stage-chat prompt answer replay is live-memory only. `StageSnapshot.promptAn
658
677
  ```json
659
678
  {
660
679
  "name": "workflow",
661
- "description": "Run named builtin, project, user, or package workflows; custom definitions may import reusable project/package workflows or builtin definitions from @bastani/workflows/builtin and nest them with ctx.workflow(...), including deeper composition within the configured maxDepth; when workflow execution fits but another shape would better achieve the task, author a custom TypeScript workflow({...}) inline with normal coding tools, reload it, and run it; after successfully creating and reloading a newly authored custom workflow, report the folder containing its generated code as 'Custom workflow created. You can inspect its code at: <workflow-folder-path>'; do this only for newly created custom workflows, never builtin or pre-existing workflows; discover with list/get/inputs/models, list session runs with status (no runId; statusFilter narrows the list), inspect status/stages/stage details, send prompt answers or steering only while the root workflow is nonterminal, pause/resume/interrupt/quit runs, and reload workflow resources. For large stage handoffs, write context to files/artifacts, pass paths via reads, and prompt downstream agents to 'Read the file at <path>...' instead of injecting large previous text. Wrap critical parts of run inputs and steering messages in <keepContext>...</keepContext> so compaction preserves them verbatim in the stages that inherit them; tag role constraints, prohibitions, must-hold criteria, and identifiers, not background or bulk reference material. For transcripts, prefer status/stages/stage to get sessionFile/transcriptPath, quote the exact path without rewriting separators (Windows backslashes are valid), then search it with rg/grep and read small ranges; transcript is path-only by default when sessionFile/transcriptPath exists, explicit tail/limit returns bounded previews, and missing transcript paths fall back to a small preview. Use action 'models' to inspect models in the configured catalog; the result is a configured-auth snapshot showing what's present in the registry with configured authentication, not proof of credentials, entitlements, OAuth freshness, or live provider access. When authoring a workflow that should dynamically select a model, first call workflow({ action: 'models' }) to inspect the configured catalog, then select from the returned provider/id entries considering the isCurrent marker and available thinking levels.",
680
+ "description": "Run named builtin, project, user, or package workflows; custom definitions may import reusable project/package workflows or builtin definitions from @bastani/workflows/builtin and nest them with ctx.workflow(...), including deeper composition within the configured maxDepth; when workflow execution fits but another shape would better achieve the task, author a custom TypeScript workflow({...}) inline with normal coding tools, reload it, and run it; after successfully creating and reloading a newly authored custom workflow, report the folder containing its generated code as 'Custom workflow created. You can inspect its code at: <workflow-folder-path>'; do this only for newly created custom workflows, never builtin or pre-existing workflows; discover with list/get/inputs/models, list session runs with status (no runId; statusFilter narrows the list), inspect status/stages/stage details, send prompt answers or steering only while the root workflow is nonterminal, pause/resume/interrupt/quit runs, and reload workflow resources. For primitive prompt answers, use booleans or the documented confirm labels, exact case-insensitive select labels or 1-based indexes, and text strings for input/editor; an invalid answer remains pending and returns guidance instead of choosing a default. For large stage handoffs, write context to files/artifacts, pass paths via reads, and prompt downstream agents to 'Read the file at <path>...' instead of injecting large previous text. Wrap critical parts of run inputs and steering messages in <keepContext>...</keepContext> so compaction preserves them verbatim in the stages that inherit them; tag role constraints, prohibitions, must-hold criteria, and identifiers, not background or bulk reference material. For transcripts, prefer status/stages/stage to get sessionFile/transcriptPath, quote the exact path without rewriting separators (Windows backslashes are valid), then search it with rg/grep and read small ranges; transcript is path-only by default when sessionFile/transcriptPath exists, explicit tail/limit returns bounded previews, and missing transcript paths fall back to a small preview. Use action 'models' to inspect models in the configured catalog; the result is a configured-auth snapshot showing what's present in the registry with configured authentication, not proof of credentials, entitlements, OAuth freshness, or live provider access. When authoring a workflow that should dynamically select a model, first call workflow({ action: 'models' }) to inspect the configured catalog, then select from the returned provider/id entries considering the isCurrent marker and available thinking levels.",
662
681
  "parameters": {
663
682
  "workflow": "string (optional) — workflow ID or normalized name",
664
683
  "inputs": "object (optional) — key/value map of workflow inputs",
@@ -702,6 +721,14 @@ Because human input is runtime-only and workflows no longer carry a declaration-
702
721
 
703
722
  For library or package authoring, define reusable workflows with `workflow({...})` and export the returned definition. Hand-written objects with `__piWorkflow: true` are rejected by discovery and composition; `workflow({...})` is the public authoring surface. Standalone TypeScript workflow packages import `workflow` from `@bastani/workflows` and `Type` from `typebox` directly with no local `.d.ts` file or `declare module` shim. Migration from the removed builder API is mechanical: move `.description(...)` to `description`, `.input(key, schema)` calls into `inputs`, `.output(key, schema)` calls into `outputs`, `.worktreeFromInputs(...)` to `worktreeFromInputs`, and the `.run(fn)` callback to `run: fn`; delete `.compile()`. The former imperative `runWorkflow` object-form API is removed; use workflow definitions with the exported `run()` / registry helpers for programmatic execution.
704
723
 
724
+ Set `heartbeatIntervalMinutes` to declare the workflow's heartbeat cadence in minutes. Omitting it uses the `15`-minute default; `0` explicitly disables heartbeats. Negative and non-finite values are rejected when the workflow definition is authored. The scheduler consumes this validated setting directly: while a top-level run is active it raises one heartbeat per `startedAt + n × interval` boundary, computed from the run's persisted start time rather than the previous delivery, so retries and restarts cannot shift the cadence. The example below heartbeats every 30 minutes, so a run started at 09:00 raises boundaries at 09:30, 10:00, 10:30, and so on.
725
+
726
+ Each heartbeat reaches the parent chat as a `workflows:workflow-heartbeat` card through the same queued-steer delivery lifecycle notices use (`triggerTurn`, `deliverAs: "steer"`, `persistWhenStreaming`), so a busy parent is never interrupted — the steer lands at its next protocol-safe boundary. At most one heartbeat per run is outstanding at a time: it holds its slot until its card is actually consumed into the conversation, not merely until the parent's turn ends, so a boundary that falls before that is skipped rather than stacked behind it and the cadence then resumes at the first future boundary. Parent pickup follows the typed heartbeat entry and releases the slot only for the exact `runId + scheduledAt` identity; another custom message cannot release it by copying the rendered text. Paused runs emit nothing and are never backfilled, a resumed or restarted run takes the first future boundary rather than bursting missed ones, simultaneous heartbeats process in `scheduledAt` order with the run id as the tie-break, and a run that reaches a terminal state is suppressed before every delivery attempt.
727
+
728
+ When a run reaches any terminal status — completed, failed, blocked, skipped, cancelled, or killed — one idempotent cleanup pass drops its wake-up timer, its next boundary, its outstanding slot, any heartbeat of its own still queued inside the scheduler with the retry timer that belonged to it, and its cadence and durable-anchor memos. Repeating the pass creates nothing and resurrects nothing. Because it reads observed state rather than transition events, it is also the recovery pass: a later process discards a stale durable anchor or leftover queued record for an already-terminal run instead of replaying it, and never replays a missed boundary for an active one. A heartbeat the host already accepted into the parent's queue is past that pass, since nothing withdraws a queued message, so it is invalidated when the parent reads it instead: its exact `runId + scheduledAt` must still be pending for a current nonterminal run. A same-ID durable resume therefore cannot revive an old card, and a heartbeat whose run is terminal or absent from this process is excluded from the model's context. That covers a card parked through a long turn and a card recovered from a previous process alike. The rendered card stays in the transcript as a record of what was raised; only the model-facing steer is invalidated ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
729
+
730
+ A recoverable provider or rate-limit block is not the terminal `blocked` status: the run remains stored as `running` and resumable. It raises no new heartbeat while blocked, but keeps its cadence state and any card already waiting with the parent; cleanup runs only once the run's own status becomes terminal.
731
+
705
732
  ```ts
706
733
  import { workflow } from "@bastani/workflows";
707
734
  import { Type } from "typebox";
@@ -709,6 +736,7 @@ import { Type } from "typebox";
709
736
  export default workflow({
710
737
  name: "audit-auth",
711
738
  description: "Audit the authentication module.",
739
+ heartbeatIntervalMinutes: 30,
712
740
  inputs: {
713
741
  prompt: Type.String({ default: "Investigate the auth module" }),
714
742
  },
@@ -811,23 +839,26 @@ For either workflow, keep PR/MR creation out of the task text and pass the origi
811
839
 
812
840
  ### `open-claude-design`
813
841
 
814
- Combined discovery/init → design-system/reference research → curated reference discovery with user preference check → separate forked generate and user-feedback chains → export/handoff pipeline. The `discovery` stage asks for output type and references, then runs impeccable init in the same stage so PRODUCT.md/DESIGN.md are detected, created, or reconciled. `ds-*` stages handle user-provided URL/file reference extraction directly, then `reference-discovery` uses that context and asks which curated direction you prefer (or asks for a reference image/path/URL if none fit). Export is only `exporter` plus `final-display`.
842
+ Combined discovery/init → design-system/reference research → curated reference discovery with user preference check → one generation one live review session → export/handoff pipeline. The `discovery` stage asks for output type and references, then runs impeccable init in the same stage so PRODUCT.md/DESIGN.md are detected, created, or reconciled. `ds-*` stages handle user-provided URL/file reference extraction directly, then `reference-discovery` uses that context and asks which curated direction you prefer (or asks for a reference image/path/URL if none fit). Export is only `exporter` plus `final-display`.
843
+
844
+ The live session is unbounded: accepted variants and steered edits are written into `preview.html` in place as you go. A deterministic run-level gate offers `Start live review` or `Skip remaining review rounds and export as-is`; the latter exports without opening a session. The workflow-owned poll loop ends on the helper's `exit` event, and the exporter receives the preview exactly as it stands. There is no second opinion, decision stage, or later review session.
845
+
846
+ The session starts at `user-feedback-N-start`; durable `live-poll-N-M` and `live-reply-N-M` tool nodes own polling and acknowledgements, while `live-generate-*`, `live-steer-*`, `live-manual_edit_apply-*`, and `live-variant_mount_failed-*` mint model stages. Replies pass the event id before the status. Successful `variant_mounted` events are journal-only; `accept`, `discard`, and `prefetch` mint no model stage, and `timeout` is absorbed in the poll node. Nonzero helper exits fail the run rather than looking like timeouts. No `<artifact_dir>/feedback/` directory or per-session record is written.
815
847
 
816
- Each refinement round pauses at a deterministic run-level prompt before its `user-feedback-*` stage starts (the stage's browser long-poll never sets `awaiting_input`, so the gate is where the wait surfaces). The prompt fires the needs-attention badge and names the preview path and `file://` URL; choose `Start live review` to open the browser session (the stage prints the live `http://` review URL first — see it with `/workflow connect`), or `Skip remaining review rounds and export as-is` to accept the current design. Headless runs skip the gate. A feedback stage that fails outright fails the run; only a completed review with no requested changes counts as approval.
848
+ Impeccable 4.1.1 persists the selected app root for all Live helpers and supports SvelteKit, Nuxt, TanStack Start, Astro, Next.js, Vite, and static HTML injection. Configured files and generated adapter paths must remain project-relative, inside the real app root, and outside symlinked parents; the browser opener accepts only loopback HTTP(S) review URLs.
817
849
 
818
- Research context moves between stages as artifact files, not inline prompt payloads: the project design context is written to `<artifact_dir>/design-context.md` and the curated references brief to `<artifact_dir>/references.md`; `reference-discovery` reads the design context, and the generate and exporter stages read both files via `reads`. Only verbatim user annotations and the word-capped prior design summary travel inline.
850
+ Research context moves between stages as artifact files, not inline prompt payloads: the project design context is written to `<artifact_dir>/design-context.md` and the curated references brief to `<artifact_dir>/references.md`; `reference-discovery`, `generate-1`, and `exporter` read the required files via `reads`.
819
851
 
820
852
  ```text
821
853
  /workflow open-claude-design prompt="Design a kanban board component"
822
854
  ```
823
855
 
824
856
  | Input | Type | Required | Default | Description |
825
- | --------------------- | --------- | -------- | ------- | --------------------------------------------------------------------------- |
857
+ | --------------------- | --------- | -------- | ------- | ------------------------------------------------------------------------- |
826
858
  | `prompt` | `text` | ✓ | — | Design brief or description. |
827
859
  | `discover_references` | `boolean` | — | `true` | Discover current gallery references with browser tooling; set false to skip. |
828
- | `max_refinements` | `number` | — | `3` | Maximum generate/user-feedback loop iterations. |
829
860
 
830
- Child workflow outputs: `output_type`, `design_system`, `artifact`, `handoff`, `approved_for_export`, `refinements_completed`, `import_context`, `run_id`, `artifact_dir`, `preview_path`, `preview_file_url`, `spec_path`, `spec_file_url`, and `playwright_cli_status`. `open-claude-design` has no `result` output; it exposes only the declared fields listed here.
861
+ Child workflow outputs: `output_type`, `design_system`, `artifact`, `handoff`, `import_context`, `run_id`, `artifact_dir`, `preview_path`, `preview_file_url`, `spec_path`, `spec_file_url`, and `playwright_cli_status`. `open-claude-design` has no `result` output; it exposes only the declared fields listed here.
831
862
 
832
863
  ---
833
864
 
@@ -42,7 +42,11 @@ function isVerifier(value: WorkflowSerializableValue): value is VerifierDecision
42
42
  function isReducer(value: WorkflowSerializableValue): value is ReducerDecision {
43
43
  return isRecord(value) && (value.decision === "accept" || value.decision === "reject" || value.decision === "repair") && typeof value.rationale === "string" && Array.isArray(value.remaining_work) && value.remaining_work.every((item) => typeof item === "string");
44
44
  }
45
-
45
+ const INVALID_VERIFIER_REPORT: VerifierDecision = {
46
+ verdict: "fail",
47
+ evidence: [],
48
+ blocking_findings: ["Verifier stage produced no valid structured report."],
49
+ };
46
50
  export async function runAdversarialVerification(ctx: WorkflowRunContext<Inputs>): Promise<AdversarialVerificationResult> {
47
51
  const root = await stableArtifactRoot(ctx, "adversarial-verification");
48
52
  const rubricPath = join(root, "rubric.md");
@@ -56,15 +60,20 @@ export async function runAdversarialVerification(ctx: WorkflowRunContext<Inputs>
56
60
  let decision: ReducerDecision = { decision: "reject", rationale: "No valid reducer decision was produced.", remaining_work: ["Reducer did not return a valid structured decision."] };
57
61
  for (;;) {
58
62
  verifierArtifactPaths = Array.from({ length: ctx.inputs.verifier_count }, (_, index) => join(root, `verification-${repairsCompleted}-${index + 1}.json`));
59
- const reports = await ctx.parallel(verifierArtifactPaths.map((path, index) => ({
63
+ const reports = await ctx.parallel(verifierArtifactPaths.map((_, index) => ({
60
64
  name: `verifier-${repairsCompleted}-${index + 1}`,
61
65
  prompt: renderVerifierPrompt(ctx.inputs.task, candidatePath, rubricPath),
62
66
  context: "fresh" as const,
63
67
  reads: [candidatePath, rubricPath],
64
68
  schema: verifierSchema,
65
- output: path,
66
- outputMode: "file-only" as const,
67
69
  })), { concurrency: Math.min(ctx.inputs.verifier_count, 4), failFast: false });
70
+ // Verifier reports are inter-stage data: the reducer reads schema-shaped
71
+ // JSON from these paths, so the runner persists the structured decisions
72
+ // itself rather than routing them through the stage artifact channel.
73
+ await Promise.all(verifierArtifactPaths.map(async (path, index) => {
74
+ const report = structured(reports[index]?.structured, isVerifier) ?? INVALID_VERIFIER_REPORT;
75
+ await writeFile(path, `${JSON.stringify(report, null, 2)}\n`);
76
+ }));
68
77
  const validReports = reports.map((report) => structured(report.structured, isVerifier)).filter((report): report is VerifierDecision => report !== undefined);
69
78
  const allVerifiersPassed = validReports.length === ctx.inputs.verifier_count && validReports.every((report) => report.verdict === "pass");
70
79
  await writeFile(join(root, `verification-summary-${repairsCompleted}.json`), JSON.stringify(validReports, null, 2));
@@ -72,9 +81,11 @@ export async function runAdversarialVerification(ctx: WorkflowRunContext<Inputs>
72
81
  const reduced = await ctx.task(`reducer-${repairsCompleted}`, {
73
82
  prompt: renderReducerPrompt(ctx.inputs.task, candidatePath, verifierArtifactPaths, repairsCompleted, ctx.inputs.max_repairs),
74
83
  context: "fresh", reads: [candidatePath, rubricPath, ...verifierArtifactPaths], schema: reducerSchema,
75
- output: reviewReportPath, outputMode: "file-only",
76
84
  });
77
85
  decision = structured(reduced.structured, isReducer) ?? decision;
86
+ // Same inter-stage contract as the verifier reports above: the repair
87
+ // stage reads this path as the reducer's structured decision.
88
+ await writeFile(reviewReportPath, `${JSON.stringify(decision, null, 2)}\n`);
78
89
  if (decision.decision === "accept" && !allVerifiersPassed) {
79
90
  const remaining = validReports.flatMap((report) => report.blocking_findings);
80
91
  decision = repairsCompleted < ctx.inputs.max_repairs
@@ -6,6 +6,10 @@ import { runAdversarialVerification } from "./adversarial-verification-runner.js
6
6
  export default workflow({
7
7
  name: "adversarial-verification",
8
8
  description: "Produce a candidate, challenge it with fresh-context rubric-based verifiers, and reduce their evidence through a bounded repair loop.",
9
+ // The 15-minute default, stated rather than inherited: this is a per-workflow
10
+ // product decision, so a future change to the global default must not silently
11
+ // re-cadence a long autonomous run.
12
+ heartbeatIntervalMinutes: 15,
9
13
  inputs: {
10
14
  task: Type.String({ description: "Task whose candidate result must be independently verified." }),
11
15
  verifier_count: Type.Integer({ minimum: 1, maximum: 5, default: 3, description: "Number of independent verifiers per review round." }),
@@ -8,6 +8,10 @@ export const DEFAULT_ACTION_CATEGORIES = ["analysis", "implementation", "researc
8
8
  export default workflow({
9
9
  name: "classify-and-act",
10
10
  description: "Classify a task with structured confidence, route deterministically to an isolated category action, and ask for human selection when confidence is low.",
11
+ // The 15-minute default, stated rather than inherited: this is a per-workflow
12
+ // product decision, so a future change to the global default must not silently
13
+ // re-cadence a long autonomous run.
14
+ heartbeatIntervalMinutes: 15,
11
15
  inputs: {
12
16
  prompt: Type.String({ description: "Task to classify and execute." }),
13
17
  categories: Type.Array(Type.String({ minLength: 1 }), {
@@ -6,6 +6,10 @@ import { runFanOutAndSynthesize } from "./fan-out-and-synthesize-runner.js";
6
6
  export default workflow({
7
7
  name: "fan-out-and-synthesize",
8
8
  description: "Partition a task, run bounded independent artifact branches, then synthesize all evidence at an explicit barrier.",
9
+ // The 15-minute default, stated rather than inherited: this is a per-workflow
10
+ // product decision, so a future change to the global default must not silently
11
+ // re-cadence a long autonomous run.
12
+ heartbeatIntervalMinutes: 15,
9
13
  inputs: {
10
14
  prompt: Type.String({ description: "Task to partition, investigate, and synthesize." }),
11
15
  max_branches: Type.Integer({
@@ -48,11 +48,16 @@ export async function runGenerateAndFilter(ctx: WorkflowRunContext<Inputs>): Pro
48
48
  const filterPath = join(root, "filter.json");
49
49
  const filtered = await ctx.task("dedupe-and-filter", {
50
50
  prompt: renderFilterPrompt(ctx.inputs.prompt, candidatePaths, shortlistLimit), context: "fresh",
51
- reads: [manifestPath, ...candidatePaths], schema: filterSchema, output: filterPath, outputMode: "file-only",
51
+ reads: [manifestPath, ...candidatePaths], schema: filterSchema,
52
52
  });
53
+ const filteredDecision = filterDecision(filtered.structured);
54
+ // The filter report is inter-stage data: the judge and final-shortlist
55
+ // stages read schema-shaped JSON from this path, so the runner persists the
56
+ // structured decision itself rather than routing it through the artifact.
57
+ await writeFile(filterPath, `${JSON.stringify(filteredDecision ?? { shortlist: [], discarded: [] }, null, 2)}\n`);
53
58
  const selectCandidates = (paths: readonly string[]): string[] => [...new Set(paths.filter((path) => candidatePaths.includes(path)))].slice(0, shortlistLimit);
54
59
  const fallbackShortlist = candidatePaths.slice(0, shortlistLimit);
55
- const filteredShortlist = selectCandidates(filterDecision(filtered.structured)?.shortlist ?? []);
60
+ const filteredShortlist = selectCandidates(filteredDecision?.shortlist ?? []);
56
61
  let shortlist = filteredShortlist.length > 0 ? filteredShortlist : fallbackShortlist;
57
62
  let judgePath: string | null = null;
58
63
  let decisionPath = filterPath;
@@ -60,9 +65,12 @@ export async function runGenerateAndFilter(ctx: WorkflowRunContext<Inputs>): Pro
60
65
  judgePath = join(root, "judge.json");
61
66
  const judged = await ctx.task("judge", {
62
67
  prompt: renderJudgePrompt(ctx.inputs.prompt, filterPath, shortlistLimit), context: "fresh",
63
- reads: [filterPath, ...shortlist], schema: judgeSchema, output: judgePath, outputMode: "file-only",
68
+ reads: [filterPath, ...shortlist], schema: judgeSchema,
64
69
  });
65
- const judgedShortlist = selectCandidates(judgeDecision(judged.structured)?.shortlist ?? []);
70
+ const judgedDecision = judgeDecision(judged.structured);
71
+ // Same inter-stage contract as the filter report above.
72
+ await writeFile(judgePath, `${JSON.stringify(judgedDecision ?? { shortlist: [], rationale: "Judge stage produced no valid structured decision." }, null, 2)}\n`);
73
+ const judgedShortlist = selectCandidates(judgedDecision?.shortlist ?? []);
66
74
  shortlist = judgedShortlist.length > 0 ? judgedShortlist : shortlist;
67
75
  decisionPath = judgePath;
68
76
  }