@bastani/atomic 0.8.26-alpha.5 → 0.8.26-alpha.7

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 (264) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +7 -4
  3. package/dist/builtin/intercom/CHANGELOG.md +12 -0
  4. package/dist/builtin/intercom/package.json +2 -2
  5. package/dist/builtin/mcp/CHANGELOG.md +12 -0
  6. package/dist/builtin/mcp/package.json +3 -3
  7. package/dist/builtin/subagents/CHANGELOG.md +12 -0
  8. package/dist/builtin/subagents/agents/codebase-online-researcher.md +9 -9
  9. package/dist/builtin/subagents/agents/debugger.md +6 -6
  10. package/dist/builtin/subagents/package.json +4 -4
  11. package/dist/builtin/subagents/prompts/parallel-handoff-plan.md +1 -1
  12. package/dist/builtin/subagents/skills/browser/EXAMPLES.md +151 -0
  13. package/dist/builtin/subagents/skills/browser/LICENSE.txt +21 -0
  14. package/dist/builtin/subagents/skills/browser/REFERENCE.md +451 -0
  15. package/dist/builtin/subagents/skills/browser/SKILL.md +170 -0
  16. package/dist/builtin/subagents/skills/subagent/SKILL.md +4 -4
  17. package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +48 -10
  18. package/dist/builtin/subagents/src/runs/foreground/execution.ts +30 -9
  19. package/dist/builtin/subagents/src/runs/shared/final-drain.ts +34 -0
  20. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +416 -7
  21. package/dist/builtin/web-access/CHANGELOG.md +12 -0
  22. package/dist/builtin/web-access/package.json +2 -2
  23. package/dist/builtin/workflows/CHANGELOG.md +17 -0
  24. package/dist/builtin/workflows/builtin/deep-research-codebase.ts +4 -1
  25. package/dist/builtin/workflows/builtin/goal.ts +127 -99
  26. package/dist/builtin/workflows/builtin/open-claude-design.ts +224 -147
  27. package/dist/builtin/workflows/builtin/ralph.ts +160 -197
  28. package/dist/builtin/workflows/package.json +2 -2
  29. package/dist/builtin/workflows/skills/research-codebase/SKILL.md +1 -1
  30. package/dist/builtin/workflows/src/extension/index.ts +10 -2
  31. package/dist/builtin/workflows/src/extension/runtime.ts +35 -3
  32. package/dist/builtin/workflows/src/runs/background/status.ts +52 -6
  33. package/dist/builtin/workflows/src/runs/foreground/executor.ts +441 -15
  34. package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +69 -8
  35. package/dist/builtin/workflows/src/runs/shared/model-fallback.ts +402 -8
  36. package/dist/builtin/workflows/src/shared/persistence-restore.ts +182 -6
  37. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +76 -6
  38. package/dist/builtin/workflows/src/shared/stage-prompt.ts +33 -2
  39. package/dist/builtin/workflows/src/shared/store-types.ts +31 -0
  40. package/dist/builtin/workflows/src/shared/store.ts +99 -11
  41. package/dist/builtin/workflows/src/shared/workflow-failures.ts +758 -132
  42. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +9 -0
  43. package/dist/core/agent-session.d.ts +28 -1
  44. package/dist/core/agent-session.d.ts.map +1 -1
  45. package/dist/core/agent-session.js +110 -28
  46. package/dist/core/agent-session.js.map +1 -1
  47. package/dist/core/compaction/branch-summarization.d.ts +1 -1
  48. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  49. package/dist/core/compaction/branch-summarization.js +6 -3
  50. package/dist/core/compaction/branch-summarization.js.map +1 -1
  51. package/dist/core/compaction/compaction.d.ts.map +1 -1
  52. package/dist/core/compaction/compaction.js +23 -10
  53. package/dist/core/compaction/compaction.js.map +1 -1
  54. package/dist/core/compaction/context-compaction.d.ts +61 -0
  55. package/dist/core/compaction/context-compaction.d.ts.map +1 -0
  56. package/dist/core/compaction/context-compaction.js +602 -0
  57. package/dist/core/compaction/context-compaction.js.map +1 -0
  58. package/dist/core/compaction/index.d.ts +1 -0
  59. package/dist/core/compaction/index.d.ts.map +1 -1
  60. package/dist/core/compaction/index.js +1 -0
  61. package/dist/core/compaction/index.js.map +1 -1
  62. package/dist/core/index.d.ts +1 -1
  63. package/dist/core/index.d.ts.map +1 -1
  64. package/dist/core/index.js.map +1 -1
  65. package/dist/core/session-manager.d.ts +41 -1
  66. package/dist/core/session-manager.d.ts.map +1 -1
  67. package/dist/core/session-manager.js +146 -7
  68. package/dist/core/session-manager.js.map +1 -1
  69. package/dist/core/slash-commands.d.ts.map +1 -1
  70. package/dist/core/slash-commands.js +1 -0
  71. package/dist/core/slash-commands.js.map +1 -1
  72. package/dist/core/tools/ask-user-question/tool/format-answer.d.ts +5 -5
  73. package/dist/core/tools/ask-user-question/tool/format-answer.d.ts.map +1 -1
  74. package/dist/core/tools/ask-user-question/tool/format-answer.js +5 -5
  75. package/dist/core/tools/ask-user-question/tool/format-answer.js.map +1 -1
  76. package/dist/core/tools/ask-user-question/tool/response-envelope.d.ts +16 -3
  77. package/dist/core/tools/ask-user-question/tool/response-envelope.d.ts.map +1 -1
  78. package/dist/core/tools/ask-user-question/tool/response-envelope.js +21 -3
  79. package/dist/core/tools/ask-user-question/tool/response-envelope.js.map +1 -1
  80. package/dist/index.d.ts +3 -3
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +2 -2
  83. package/dist/index.js.map +1 -1
  84. package/dist/modes/index.d.ts +1 -1
  85. package/dist/modes/index.d.ts.map +1 -1
  86. package/dist/modes/index.js.map +1 -1
  87. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  88. package/dist/modes/interactive/components/chat-session-host.js +17 -0
  89. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  90. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  91. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  92. package/dist/modes/interactive/interactive-mode.js +74 -0
  93. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  94. package/dist/modes/rpc/rpc-client.d.ts +12 -7
  95. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  96. package/dist/modes/rpc/rpc-client.js +8 -1
  97. package/dist/modes/rpc/rpc-client.js.map +1 -1
  98. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  99. package/dist/modes/rpc/rpc-mode.js +4 -0
  100. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  101. package/dist/modes/rpc/rpc-types.d.ts +13 -2
  102. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  103. package/dist/modes/rpc/rpc-types.js.map +1 -1
  104. package/docs/compaction.md +42 -23
  105. package/docs/custom-provider.md +11 -9
  106. package/docs/extensions.md +35 -35
  107. package/docs/index.md +1 -8
  108. package/docs/json.md +14 -11
  109. package/docs/packages.md +2 -0
  110. package/docs/providers.md +4 -1
  111. package/docs/quickstart.md +5 -12
  112. package/docs/rpc.md +44 -8
  113. package/docs/sdk.md +1 -8
  114. package/docs/session-format.md +25 -12
  115. package/docs/sessions.md +2 -1
  116. package/docs/skills.md +1 -15
  117. package/docs/termux.md +9 -10
  118. package/docs/themes.md +2 -2
  119. package/docs/tmux.md +3 -3
  120. package/docs/tui.md +19 -32
  121. package/docs/usage.md +2 -0
  122. package/docs/workflows.md +44 -2
  123. package/package.json +4 -12
  124. package/dist/builtin/subagents/skills/browser-use/SKILL.md +0 -234
  125. package/dist/builtin/subagents/skills/browser-use/references/cdp-python.md +0 -76
  126. package/dist/builtin/subagents/skills/browser-use/references/multi-session.md +0 -92
  127. package/node_modules/@earendil-works/pi-tui/README.md +0 -779
  128. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +0 -54
  129. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +0 -1
  130. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +0 -632
  131. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +0 -1
  132. package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts +0 -22
  133. package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts.map +0 -1
  134. package/node_modules/@earendil-works/pi-tui/dist/components/box.js +0 -104
  135. package/node_modules/@earendil-works/pi-tui/dist/components/box.js.map +0 -1
  136. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts +0 -22
  137. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts.map +0 -1
  138. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js +0 -35
  139. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js.map +0 -1
  140. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +0 -249
  141. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +0 -1
  142. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +0 -1857
  143. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +0 -1
  144. package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts +0 -28
  145. package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts.map +0 -1
  146. package/node_modules/@earendil-works/pi-tui/dist/components/image.js +0 -89
  147. package/node_modules/@earendil-works/pi-tui/dist/components/image.js.map +0 -1
  148. package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts +0 -37
  149. package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts.map +0 -1
  150. package/node_modules/@earendil-works/pi-tui/dist/components/input.js +0 -378
  151. package/node_modules/@earendil-works/pi-tui/dist/components/input.js.map +0 -1
  152. package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts +0 -31
  153. package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts.map +0 -1
  154. package/node_modules/@earendil-works/pi-tui/dist/components/loader.js +0 -69
  155. package/node_modules/@earendil-works/pi-tui/dist/components/loader.js.map +0 -1
  156. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +0 -96
  157. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +0 -1
  158. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +0 -644
  159. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +0 -1
  160. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +0 -50
  161. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +0 -1
  162. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js +0 -159
  163. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +0 -1
  164. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts +0 -50
  165. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts.map +0 -1
  166. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js +0 -185
  167. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js.map +0 -1
  168. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts +0 -12
  169. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts.map +0 -1
  170. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js +0 -23
  171. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js.map +0 -1
  172. package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts +0 -19
  173. package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts.map +0 -1
  174. package/node_modules/@earendil-works/pi-tui/dist/components/text.js +0 -89
  175. package/node_modules/@earendil-works/pi-tui/dist/components/text.js.map +0 -1
  176. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts +0 -13
  177. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts.map +0 -1
  178. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js +0 -51
  179. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js.map +0 -1
  180. package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts +0 -39
  181. package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts.map +0 -1
  182. package/node_modules/@earendil-works/pi-tui/dist/editor-component.js +0 -2
  183. package/node_modules/@earendil-works/pi-tui/dist/editor-component.js.map +0 -1
  184. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +0 -16
  185. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts.map +0 -1
  186. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +0 -110
  187. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +0 -1
  188. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +0 -23
  189. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +0 -1
  190. package/node_modules/@earendil-works/pi-tui/dist/index.js +0 -32
  191. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +0 -1
  192. package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts +0 -193
  193. package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts.map +0 -1
  194. package/node_modules/@earendil-works/pi-tui/dist/keybindings.js +0 -174
  195. package/node_modules/@earendil-works/pi-tui/dist/keybindings.js.map +0 -1
  196. package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts +0 -184
  197. package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts.map +0 -1
  198. package/node_modules/@earendil-works/pi-tui/dist/keys.js +0 -1173
  199. package/node_modules/@earendil-works/pi-tui/dist/keys.js.map +0 -1
  200. package/node_modules/@earendil-works/pi-tui/dist/kill-ring.d.ts +0 -28
  201. package/node_modules/@earendil-works/pi-tui/dist/kill-ring.d.ts.map +0 -1
  202. package/node_modules/@earendil-works/pi-tui/dist/kill-ring.js +0 -44
  203. package/node_modules/@earendil-works/pi-tui/dist/kill-ring.js.map +0 -1
  204. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts +0 -3
  205. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts.map +0 -1
  206. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js +0 -53
  207. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js.map +0 -1
  208. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +0 -50
  209. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +0 -1
  210. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +0 -361
  211. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +0 -1
  212. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +0 -90
  213. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +0 -1
  214. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +0 -366
  215. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +0 -1
  216. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +0 -113
  217. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +0 -1
  218. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +0 -472
  219. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +0 -1
  220. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +0 -227
  221. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +0 -1
  222. package/node_modules/@earendil-works/pi-tui/dist/tui.js +0 -1106
  223. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +0 -1
  224. package/node_modules/@earendil-works/pi-tui/dist/undo-stack.d.ts +0 -17
  225. package/node_modules/@earendil-works/pi-tui/dist/undo-stack.d.ts.map +0 -1
  226. package/node_modules/@earendil-works/pi-tui/dist/undo-stack.js +0 -25
  227. package/node_modules/@earendil-works/pi-tui/dist/undo-stack.js.map +0 -1
  228. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +0 -84
  229. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +0 -1
  230. package/node_modules/@earendil-works/pi-tui/dist/utils.js +0 -1029
  231. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +0 -1
  232. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts +0 -25
  233. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts.map +0 -1
  234. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js +0 -96
  235. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js.map +0 -1
  236. package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
  237. package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
  238. package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
  239. package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
  240. package/node_modules/@earendil-works/pi-tui/package.json +0 -47
  241. package/node_modules/get-east-asian-width/index.d.ts +0 -60
  242. package/node_modules/get-east-asian-width/index.js +0 -30
  243. package/node_modules/get-east-asian-width/license +0 -9
  244. package/node_modules/get-east-asian-width/lookup-data.js +0 -21
  245. package/node_modules/get-east-asian-width/lookup.js +0 -138
  246. package/node_modules/get-east-asian-width/package.json +0 -71
  247. package/node_modules/get-east-asian-width/readme.md +0 -65
  248. package/node_modules/get-east-asian-width/utilities.js +0 -24
  249. package/node_modules/marked/LICENSE.md +0 -44
  250. package/node_modules/marked/README.md +0 -106
  251. package/node_modules/marked/bin/main.js +0 -282
  252. package/node_modules/marked/bin/marked.js +0 -15
  253. package/node_modules/marked/lib/marked.cjs +0 -2211
  254. package/node_modules/marked/lib/marked.cjs.map +0 -7
  255. package/node_modules/marked/lib/marked.d.cts +0 -728
  256. package/node_modules/marked/lib/marked.d.ts +0 -728
  257. package/node_modules/marked/lib/marked.esm.js +0 -2189
  258. package/node_modules/marked/lib/marked.esm.js.map +0 -7
  259. package/node_modules/marked/lib/marked.umd.js +0 -2213
  260. package/node_modules/marked/lib/marked.umd.js.map +0 -7
  261. package/node_modules/marked/man/marked.1 +0 -111
  262. package/node_modules/marked/man/marked.1.md +0 -92
  263. package/node_modules/marked/marked.min.js +0 -69
  264. package/node_modules/marked/package.json +0 -111
@@ -44,6 +44,7 @@ import {
44
44
  import { validateWorkflowModels } from "../runs/shared/model-fallback.js";
45
45
  import { runDetached } from "../runs/background/runner.js";
46
46
  import type { JobTracker } from "../runs/background/job-tracker.js";
47
+ import { appendRunEnd } from "../shared/persistence-session-entries.js";
47
48
  import { classifyWorkflowFailure } from "../shared/workflow-failures.js";
48
49
 
49
50
  // ---------------------------------------------------------------------------
@@ -389,13 +390,39 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
389
390
  return { ok: true, stageId: failedStageId };
390
391
  }
391
392
 
393
+ function finalizeResumedActiveBlockedSourceRun(source: RunSnapshot, continuationRunId: string): void {
394
+ const errorMessage = source.error ?? source.failureMessage ?? `workflow resumed in new run ${continuationRunId}`;
395
+ const metadata = {
396
+ ...(source.failureKind !== undefined ? { failureKind: source.failureKind } : {}),
397
+ ...(source.failureCode !== undefined ? { failureCode: source.failureCode } : {}),
398
+ failureRecoverability: "non_recoverable",
399
+ failureDisposition: "terminal_killed",
400
+ ...(source.failureMessage !== undefined ? { failureMessage: source.failureMessage } : {}),
401
+ ...(source.failedStageId !== undefined ? { failedStageId: source.failedStageId } : {}),
402
+ resumable: false,
403
+ ...(source.retryAfterMs !== undefined ? { retryAfterMs: source.retryAfterMs } : {}),
404
+ } as const;
405
+ const recorded = activeStore.recordRunEnd(source.id, "killed", undefined, errorMessage, metadata);
406
+ if (recorded && persistence !== undefined) {
407
+ appendRunEnd(persistence, {
408
+ runId: source.id,
409
+ status: "killed",
410
+ error: errorMessage,
411
+ ...metadata,
412
+ ts: Date.now(),
413
+ });
414
+ }
415
+ }
416
+
392
417
  function resumeFailedRun(sourceRunId: string, stageId?: string, options?: RuntimeDispatchOptions): ResumeFailedRunResult {
393
418
  const source = activeStore.runs().find((run) => run.id === sourceRunId);
394
419
  if (source === undefined) {
395
420
  return { ok: false, reason: "run_not_found", message: `run not found: ${sourceRunId}` };
396
421
  }
397
- if (source.status !== "failed" || source.endedAt === undefined || source.resumable === false) {
398
- return { ok: false, reason: "not_resumable", message: `run ${sourceRunId} is not a failed resumable workflow run` };
422
+ const isTerminalFailedResumable = source.status === "failed" && source.endedAt !== undefined && source.resumable !== false;
423
+ const isActiveBlockedResumable = source.endedAt === undefined && source.resumable === true && source.failureRecoverability === "recoverable";
424
+ if (!isTerminalFailedResumable && !isActiveBlockedResumable) {
425
+ return { ok: false, reason: "not_resumable", message: `run ${sourceRunId} is not a resumable workflow run` };
399
426
  }
400
427
  const def = registry.get(source.name);
401
428
  if (def === undefined) {
@@ -415,12 +442,17 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
415
442
  ...runOptions({ workflow: def.name, inputs: sourceInputs }, options?.policy),
416
443
  continuation: { source, resumeFromStageId: resolvedStage.stageId },
417
444
  });
445
+ if (isActiveBlockedResumable) {
446
+ finalizeResumedActiveBlockedSourceRun(source, accepted.runId);
447
+ }
418
448
  return {
419
449
  ok: true,
420
450
  runId: accepted.runId,
421
451
  sourceRunId: source.id,
422
452
  resumeFromStageId: resolvedStage.stageId,
423
- message: `Resuming failed workflow "${def.name}" from run ${source.id.slice(0, 8)} at stage ${resolvedStage.stageId.slice(0, 8)} (new run ${accepted.runId}).`,
453
+ message: isActiveBlockedResumable
454
+ ? `Resuming blocked workflow "${def.name}" from run ${source.id.slice(0, 8)} at stage ${resolvedStage.stageId.slice(0, 8)} (new run ${accepted.runId}).`
455
+ : `Resuming failed workflow "${def.name}" from run ${source.id.slice(0, 8)} at stage ${resolvedStage.stageId.slice(0, 8)} (new run ${accepted.runId}).`,
424
456
  };
425
457
  }
426
458
 
@@ -82,6 +82,14 @@ export interface RunDetail {
82
82
  readonly stages: readonly RunSnapshot["stages"][number][];
83
83
  readonly result?: WorkflowOutputValues;
84
84
  readonly error?: string;
85
+ readonly failureKind?: RunSnapshot["failureKind"];
86
+ readonly failureCode?: RunSnapshot["failureCode"];
87
+ readonly failureRecoverability?: RunSnapshot["failureRecoverability"];
88
+ readonly failureDisposition?: RunSnapshot["failureDisposition"];
89
+ readonly failedStageId?: string;
90
+ readonly resumable?: boolean;
91
+ readonly retryAfterMs?: number;
92
+ readonly blockedAt?: number;
85
93
  }
86
94
 
87
95
  export type InspectRunResult =
@@ -146,11 +154,26 @@ export function killRun(
146
154
  const previousStatus = run.status;
147
155
 
148
156
  // Abort active executor (no-op if not registered)
149
- opts?.cancellation?.abort(runId, "workflow killed");
150
-
151
- const recorded = activeStore.recordRunEnd(runId, "killed", undefined, "workflow killed");
157
+ const errorMessage = "workflow killed";
158
+ opts?.cancellation?.abort(runId, errorMessage);
159
+
160
+ const metadata = {
161
+ failureKind: "cancelled",
162
+ failureCode: "cancelled",
163
+ failureRecoverability: "non_recoverable",
164
+ failureDisposition: "terminal_killed",
165
+ failureMessage: errorMessage,
166
+ resumable: false,
167
+ } as const;
168
+ const recorded = activeStore.recordRunEnd(runId, "killed", undefined, errorMessage, metadata);
152
169
  if (recorded && opts?.persistence) {
153
- appendRunEnd(opts.persistence, { runId, status: "killed", ts: Date.now() });
170
+ appendRunEnd(opts.persistence, {
171
+ runId,
172
+ status: "killed",
173
+ error: errorMessage,
174
+ ...metadata,
175
+ ts: Date.now(),
176
+ });
154
177
  }
155
178
 
156
179
  return { ok: true, runId, previousStatus };
@@ -247,14 +270,29 @@ export function resumeRun(
247
270
  // Return a deep copy of the snapshot for safe consumption
248
271
  const snapshot = structuredClone(run);
249
272
  const resumedCopy = structuredClone(resumed);
250
- if (run.status === "failed" && run.endedAt !== undefined && run.resumable === false) {
273
+ if (run.status === "killed" || run.resumable === false) {
251
274
  return {
252
275
  ok: true,
253
276
  runId,
254
277
  snapshot,
255
278
  resumed: resumedCopy,
256
279
  mode: "not_resumable",
257
- message: "This failed workflow is not resumable; inspect the snapshot and rerun the workflow when ready.",
280
+ message: "This workflow is not resumable; inspect the snapshot and start a new workflow run when ready.",
281
+ };
282
+ }
283
+ if (
284
+ run.endedAt === undefined &&
285
+ run.resumable === true &&
286
+ run.failureRecoverability === "recoverable" &&
287
+ run.failedStageId !== undefined
288
+ ) {
289
+ return {
290
+ ok: true,
291
+ runId,
292
+ snapshot,
293
+ resumed: resumedCopy,
294
+ mode: resumedCopy.length > 0 ? "paused" : "snapshot",
295
+ message: `Workflow is blocked on a recoverable ${run.failureCode ?? run.failureKind ?? "workflow"} failure at stage ${run.failedStageId}; retry/resume after the issue clears.`,
258
296
  };
259
297
  }
260
298
  return {
@@ -441,6 +479,14 @@ export function inspectRun(
441
479
  stages: expandedStages.map((stage) => structuredClone(stage)),
442
480
  result: copy.result,
443
481
  error: copy.error,
482
+ failureKind: copy.failureKind,
483
+ failureCode: copy.failureCode,
484
+ failureRecoverability: copy.failureRecoverability,
485
+ failureDisposition: copy.failureDisposition,
486
+ failedStageId: copy.failedStageId,
487
+ resumable: copy.resumable,
488
+ retryAfterMs: copy.retryAfterMs,
489
+ blockedAt: copy.blockedAt,
444
490
  };
445
491
 
446
492
  return { ok: true, runId: copy.id, detail };