@bastani/atomic 0.9.11-alpha.9 → 0.9.12-alpha.1

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 (380) hide show
  1. package/CHANGELOG.md +147 -0
  2. package/README.md +1 -1
  3. package/dist/builtin/intercom/CHANGELOG.md +12 -0
  4. package/dist/builtin/intercom/closed-workflow-stage-message.ts +1 -1
  5. package/dist/builtin/intercom/contact-supervisor-tool.ts +1 -1
  6. package/dist/builtin/intercom/index-heavy.ts +2 -2
  7. package/dist/builtin/intercom/intercom-tool.ts +2 -2
  8. package/dist/builtin/intercom/intercom-utils.ts +1 -1
  9. package/dist/builtin/intercom/lifecycle.ts +2 -2
  10. package/dist/builtin/intercom/overlay.ts +2 -2
  11. package/dist/builtin/intercom/package.json +1 -1
  12. package/dist/builtin/intercom/reply-tracker.ts +1 -1
  13. package/dist/builtin/intercom/subagent-relay.ts +10 -7
  14. package/dist/builtin/mcp/CHANGELOG.md +16 -0
  15. package/dist/builtin/mcp/apps-cancellation.ts +1 -1
  16. package/dist/builtin/mcp/commands.ts +7 -7
  17. package/dist/builtin/mcp/direct-tool-executor.ts +1 -1
  18. package/dist/builtin/mcp/direct-tools.ts +3 -3
  19. package/dist/builtin/mcp/host-html-template.ts +1 -1
  20. package/dist/builtin/mcp/index.ts +3 -3
  21. package/dist/builtin/mcp/init.ts +6 -6
  22. package/dist/builtin/mcp/mcp-auth-flow.ts +1 -1
  23. package/dist/builtin/mcp/mcp-callback-server.ts +1 -1
  24. package/dist/builtin/mcp/mcp-panel-state.ts +1 -1
  25. package/dist/builtin/mcp/mcp-panel.ts +1 -1
  26. package/dist/builtin/mcp/metadata-cache.ts +1 -1
  27. package/dist/builtin/mcp/package.json +1 -1
  28. package/dist/builtin/mcp/proxy-call.ts +2 -2
  29. package/dist/builtin/mcp/proxy-info-modes.ts +2 -2
  30. package/dist/builtin/mcp/sampling-handler.ts +1 -1
  31. package/dist/builtin/mcp/server-manager.ts +3 -3
  32. package/dist/builtin/mcp/startup-warmup.ts +5 -5
  33. package/dist/builtin/mcp/state.ts +1 -1
  34. package/dist/builtin/mcp/tool-call-timeout.ts +1 -1
  35. package/dist/builtin/mcp/tool-metadata.ts +2 -2
  36. package/dist/builtin/mcp/types.ts +1 -1
  37. package/dist/builtin/mcp/ui-server.ts +4 -4
  38. package/dist/builtin/mcp/ui-session.ts +3 -3
  39. package/dist/builtin/subagents/CHANGELOG.md +26 -0
  40. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  41. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  42. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  43. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
  44. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  45. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  46. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  47. package/dist/builtin/subagents/agents/worker.md +2 -2
  48. package/dist/builtin/subagents/package.json +1 -1
  49. package/dist/builtin/subagents/src/extension/notification-content.ts +14 -9
  50. package/dist/builtin/subagents/src/runs/background/notify.ts +20 -4
  51. package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +5 -5
  52. package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +1 -1
  53. package/dist/builtin/subagents/src/runs/background/result-status.ts +2 -2
  54. package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +2 -2
  55. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +1 -1
  56. package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +1 -1
  57. package/dist/builtin/subagents/src/shared/artifacts.ts +1 -1
  58. package/dist/builtin/web-access/CHANGELOG.md +26 -0
  59. package/dist/builtin/web-access/content-tools.ts +1 -0
  60. package/dist/builtin/web-access/flat-string.ts +37 -0
  61. package/dist/builtin/web-access/github-api.ts +2 -1
  62. package/dist/builtin/web-access/github-extract.ts +3 -2
  63. package/dist/builtin/web-access/index-heavy.ts +1 -1
  64. package/dist/builtin/web-access/package.json +2 -2
  65. package/dist/builtin/workflows/CHANGELOG.md +68 -0
  66. package/dist/builtin/workflows/README.md +1 -1
  67. package/dist/builtin/workflows/builtin/goal-ledger.ts +6 -4
  68. package/dist/builtin/workflows/builtin/goal-prompts.ts +4 -1
  69. package/dist/builtin/workflows/builtin/goal-runner.ts +2 -1
  70. package/dist/builtin/workflows/builtin/goal.ts +1 -1
  71. package/dist/builtin/workflows/builtin/ralph-core.ts +15 -13
  72. package/dist/builtin/workflows/builtin/ralph-forked-prompts.ts +7 -6
  73. package/dist/builtin/workflows/builtin/ralph-models.ts +4 -4
  74. package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +2 -1
  75. package/dist/builtin/workflows/builtin/ralph-runner.ts +7 -9
  76. package/dist/builtin/workflows/builtin/ralph.ts +2 -1
  77. package/dist/builtin/workflows/builtin/shared-prompts.ts +34 -7
  78. package/dist/builtin/workflows/package.json +1 -1
  79. package/dist/builtin/workflows/src/authoring/keep-context.ts +46 -0
  80. package/dist/builtin/workflows/src/authoring.d.ts +11 -0
  81. package/dist/builtin/workflows/src/durable/completed-catalog.ts +14 -8
  82. package/dist/builtin/workflows/src/durable/completed-inspection.ts +10 -11
  83. package/dist/builtin/workflows/src/durable/resume-catalog.ts +1 -1
  84. package/dist/builtin/workflows/src/durable/resume-eligibility.ts +42 -0
  85. package/dist/builtin/workflows/src/durable/resume-runtime.ts +36 -37
  86. package/dist/builtin/workflows/src/durable/tool-primitive.ts +10 -2
  87. package/dist/builtin/workflows/src/engine/run.ts +1 -0
  88. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +12 -8
  89. package/dist/builtin/workflows/src/extension/hil-answer-notifications.ts +5 -2
  90. package/dist/builtin/workflows/src/extension/index.bundle.mjs +2001 -897
  91. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +6 -3
  92. package/dist/builtin/workflows/src/extension/postmortem-deps.ts +3 -2
  93. package/dist/builtin/workflows/src/extension/render-result.ts +4 -11
  94. package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +17 -20
  95. package/dist/builtin/workflows/src/extension/runtime.ts +3 -3
  96. package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +1 -1
  97. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +3 -7
  98. package/dist/builtin/workflows/src/extension/workflow-durable-resume-command.ts +21 -24
  99. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +4 -0
  100. package/dist/builtin/workflows/src/extension/workflow-resume-picker-rows.ts +38 -26
  101. package/dist/builtin/workflows/src/extension/workflow-resume-shadow.ts +2 -1
  102. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +56 -64
  103. package/dist/builtin/workflows/src/extension/workflow-schema.ts +2 -2
  104. package/dist/builtin/workflows/src/extension/workflow-status-summary.ts +0 -5
  105. package/dist/builtin/workflows/src/extension/workflow-targets.ts +17 -20
  106. package/dist/builtin/workflows/src/extension/workflow-tool-content.ts +1 -1
  107. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +24 -51
  108. package/dist/builtin/workflows/src/extension/workflow-tool-inspection.ts +7 -29
  109. package/dist/builtin/workflows/src/extension/workflow-tool-send.ts +5 -13
  110. package/dist/builtin/workflows/src/extension/workflow-tool.ts +4 -13
  111. package/dist/builtin/workflows/src/runs/background/quit.ts +4 -3
  112. package/dist/builtin/workflows/src/runs/background/run-inspect.ts +8 -8
  113. package/dist/builtin/workflows/src/runs/background/status.ts +2 -1
  114. package/dist/builtin/workflows/src/runs/background/workflow-lifecycle-aggregate.ts +2 -1
  115. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +5 -5
  116. package/dist/builtin/workflows/src/runs/foreground/executor-lifecycle.ts +4 -0
  117. package/dist/builtin/workflows/src/runs/foreground/executor-scheduler.ts +2 -0
  118. package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +23 -8
  119. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +6 -2
  120. package/dist/builtin/workflows/src/runs/foreground/executor-task-prompts.ts +5 -0
  121. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +56 -10
  122. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +6 -0
  123. package/dist/builtin/workflows/src/runs/foreground/stage-runner-output.ts +137 -6
  124. package/dist/builtin/workflows/src/sdk-surface.ts +1 -0
  125. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +2 -0
  126. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +2 -0
  127. package/dist/builtin/workflows/src/shared/expanded-workflow-graph.ts +159 -10
  128. package/dist/builtin/workflows/src/shared/flat-string.ts +33 -0
  129. package/dist/builtin/workflows/src/shared/graph-store-snapshot.ts +144 -0
  130. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +2 -3
  131. package/dist/builtin/workflows/src/shared/run-id.ts +36 -0
  132. package/dist/builtin/workflows/src/shared/store-internal.ts +32 -3
  133. package/dist/builtin/workflows/src/shared/store-observation.ts +10 -0
  134. package/dist/builtin/workflows/src/shared/store-public-types.ts +8 -0
  135. package/dist/builtin/workflows/src/shared/store-run-methods.ts +14 -0
  136. package/dist/builtin/workflows/src/shared/store-types.ts +4 -0
  137. package/dist/builtin/workflows/src/shared/types.ts +2 -0
  138. package/dist/builtin/workflows/src/shared/workflow-artifacts.ts +261 -0
  139. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +39 -23
  140. package/dist/builtin/workflows/src/tui/graph-canvas.ts +26 -9
  141. package/dist/builtin/workflows/src/tui/graph-view-constants.ts +3 -0
  142. package/dist/builtin/workflows/src/tui/graph-view-graph-render.ts +95 -98
  143. package/dist/builtin/workflows/src/tui/graph-view-render.ts +7 -20
  144. package/dist/builtin/workflows/src/tui/graph-view-state.ts +160 -13
  145. package/dist/builtin/workflows/src/tui/layout.ts +8 -2
  146. package/dist/builtin/workflows/src/tui/node-card.ts +57 -45
  147. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +4 -2
  148. package/dist/builtin/workflows/src/tui/prompt-card-render.ts +291 -21
  149. package/dist/builtin/workflows/src/tui/prompt-card.ts +1 -1
  150. package/dist/builtin/workflows/src/tui/renderers.ts +0 -1
  151. package/dist/builtin/workflows/src/tui/run-detail.ts +52 -35
  152. package/dist/builtin/workflows/src/tui/run-identity-rows.ts +97 -0
  153. package/dist/builtin/workflows/src/tui/session-overlays.ts +24 -3
  154. package/dist/builtin/workflows/src/tui/session-picker.ts +94 -41
  155. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +190 -26
  156. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +52 -18
  157. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +9 -5
  158. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +44 -4
  159. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +3 -1
  160. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +3 -2
  161. package/dist/builtin/workflows/src/tui/status-list.ts +67 -45
  162. package/dist/builtin/workflows/src/tui/store-widget-installer.ts +7 -6
  163. package/dist/builtin/workflows/src/tui/widget.ts +49 -40
  164. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +15 -10
  165. package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +21 -8
  166. package/dist/core/agent-session-accessors.d.ts.map +1 -1
  167. package/dist/core/agent-session-accessors.js +5 -0
  168. package/dist/core/agent-session-accessors.js.map +1 -1
  169. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  170. package/dist/core/agent-session-auto-compaction.js +5 -0
  171. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  172. package/dist/core/agent-session-compaction.d.ts.map +1 -1
  173. package/dist/core/agent-session-compaction.js +3 -0
  174. package/dist/core/agent-session-compaction.js.map +1 -1
  175. package/dist/core/agent-session-events.d.ts.map +1 -1
  176. package/dist/core/agent-session-events.js +2 -1
  177. package/dist/core/agent-session-events.js.map +1 -1
  178. package/dist/core/agent-session-message-queue.d.ts +3 -7
  179. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  180. package/dist/core/agent-session-message-queue.js +27 -13
  181. package/dist/core/agent-session-message-queue.js.map +1 -1
  182. package/dist/core/agent-session-methods.d.ts +6 -4
  183. package/dist/core/agent-session-methods.d.ts.map +1 -1
  184. package/dist/core/agent-session-methods.js.map +1 -1
  185. package/dist/core/agent-session-persistent-custom-messages.d.ts.map +1 -1
  186. package/dist/core/agent-session-persistent-custom-messages.js +6 -3
  187. package/dist/core/agent-session-persistent-custom-messages.js.map +1 -1
  188. package/dist/core/agent-session-post-tool-compaction.d.ts.map +1 -1
  189. package/dist/core/agent-session-post-tool-compaction.js +11 -2
  190. package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
  191. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  192. package/dist/core/agent-session-runtime.js +5 -3
  193. package/dist/core/agent-session-runtime.js.map +1 -1
  194. package/dist/core/agent-session-tree.d.ts.map +1 -1
  195. package/dist/core/agent-session-tree.js +4 -0
  196. package/dist/core/agent-session-tree.js.map +1 -1
  197. package/dist/core/agent-session-types.d.ts +4 -0
  198. package/dist/core/agent-session-types.d.ts.map +1 -1
  199. package/dist/core/agent-session-types.js.map +1 -1
  200. package/dist/core/agent-session.d.ts +3 -2
  201. package/dist/core/agent-session.d.ts.map +1 -1
  202. package/dist/core/agent-session.js +1 -0
  203. package/dist/core/agent-session.js.map +1 -1
  204. package/dist/core/async/session-manager.d.ts +1 -1
  205. package/dist/core/async/session-manager.js.map +1 -1
  206. package/dist/core/auth-storage-backends.d.ts.map +1 -1
  207. package/dist/core/auth-storage-backends.js +12 -1
  208. package/dist/core/auth-storage-backends.js.map +1 -1
  209. package/dist/core/bounded-model-refresh.d.ts +14 -0
  210. package/dist/core/bounded-model-refresh.d.ts.map +1 -0
  211. package/dist/core/bounded-model-refresh.js +38 -0
  212. package/dist/core/bounded-model-refresh.js.map +1 -0
  213. package/dist/core/compaction/branch-summarization.js.map +1 -1
  214. package/dist/core/compaction/compaction-boundary.d.ts +2 -2
  215. package/dist/core/compaction/compaction-boundary.js.map +1 -1
  216. package/dist/core/compaction/compaction-parameters.d.ts +5 -0
  217. package/dist/core/compaction/compaction-parameters.d.ts.map +1 -1
  218. package/dist/core/compaction/compaction-parameters.js +6 -5
  219. package/dist/core/compaction/compaction-parameters.js.map +1 -1
  220. package/dist/core/compaction/compaction-runner.d.ts +4 -0
  221. package/dist/core/compaction/compaction-runner.d.ts.map +1 -1
  222. package/dist/core/compaction/compaction-runner.js +5 -1
  223. package/dist/core/compaction/compaction-runner.js.map +1 -1
  224. package/dist/core/compaction/compaction-types.d.ts +7 -1
  225. package/dist/core/compaction/compaction-types.d.ts.map +1 -1
  226. package/dist/core/compaction/compaction-types.js.map +1 -1
  227. package/dist/core/compaction/deleted-ranges.d.ts.map +1 -1
  228. package/dist/core/compaction/deleted-ranges.js +2 -0
  229. package/dist/core/compaction/deleted-ranges.js.map +1 -1
  230. package/dist/core/compaction/fallback-planner.d.ts +1 -1
  231. package/dist/core/compaction/fallback-planner.js.map +1 -1
  232. package/dist/core/compaction/range-planner.d.ts +3 -3
  233. package/dist/core/compaction/range-planner.d.ts.map +1 -1
  234. package/dist/core/compaction/range-planner.js +12 -14
  235. package/dist/core/compaction/range-planner.js.map +1 -1
  236. package/dist/core/compaction/transcript-serialization.d.ts +12 -0
  237. package/dist/core/compaction/transcript-serialization.d.ts.map +1 -1
  238. package/dist/core/compaction/transcript-serialization.js +99 -1
  239. package/dist/core/compaction/transcript-serialization.js.map +1 -1
  240. package/dist/core/compaction/utils.d.ts +3 -0
  241. package/dist/core/compaction/utils.d.ts.map +1 -1
  242. package/dist/core/compaction/utils.js +16 -0
  243. package/dist/core/compaction/utils.js.map +1 -1
  244. package/dist/core/context-tool-pairing.d.ts +4 -4
  245. package/dist/core/context-tool-pairing.js +4 -4
  246. package/dist/core/context-tool-pairing.js.map +1 -1
  247. package/dist/core/http-dispatcher.d.ts.map +1 -1
  248. package/dist/core/http-dispatcher.js +26 -1
  249. package/dist/core/http-dispatcher.js.map +1 -1
  250. package/dist/core/messages.d.ts +18 -6
  251. package/dist/core/messages.d.ts.map +1 -1
  252. package/dist/core/messages.js +46 -18
  253. package/dist/core/messages.js.map +1 -1
  254. package/dist/core/model-refresh-timeout.d.ts +9 -0
  255. package/dist/core/model-refresh-timeout.d.ts.map +1 -0
  256. package/dist/core/model-refresh-timeout.js +9 -0
  257. package/dist/core/model-refresh-timeout.js.map +1 -0
  258. package/dist/core/model-runtime-snapshot.d.ts +3 -0
  259. package/dist/core/model-runtime-snapshot.d.ts.map +1 -1
  260. package/dist/core/model-runtime-snapshot.js +59 -0
  261. package/dist/core/model-runtime-snapshot.js.map +1 -1
  262. package/dist/core/model-runtime.d.ts +7 -1
  263. package/dist/core/model-runtime.d.ts.map +1 -1
  264. package/dist/core/model-runtime.js +72 -17
  265. package/dist/core/model-runtime.js.map +1 -1
  266. package/dist/core/sdk.d.ts.map +1 -1
  267. package/dist/core/sdk.js +4 -3
  268. package/dist/core/sdk.js.map +1 -1
  269. package/dist/core/session-manager-core.d.ts +1 -1
  270. package/dist/core/session-manager-core.d.ts.map +1 -1
  271. package/dist/core/session-manager-core.js +2 -2
  272. package/dist/core/session-manager-core.js.map +1 -1
  273. package/dist/core/session-manager-entries.d.ts +1 -1
  274. package/dist/core/session-manager-entries.d.ts.map +1 -1
  275. package/dist/core/session-manager-entries.js +2 -1
  276. package/dist/core/session-manager-entries.js.map +1 -1
  277. package/dist/core/session-manager-history.d.ts.map +1 -1
  278. package/dist/core/session-manager-history.js +2 -2
  279. package/dist/core/session-manager-history.js.map +1 -1
  280. package/dist/core/session-manager-types.d.ts +3 -0
  281. package/dist/core/session-manager-types.d.ts.map +1 -1
  282. package/dist/core/session-manager-types.js.map +1 -1
  283. package/dist/core/tools/bash-async-execution.d.ts +1 -1
  284. package/dist/core/tools/bash-async-execution.js.map +1 -1
  285. package/dist/core/tools/bash.js.map +1 -1
  286. package/dist/core/tools/oversized-tool-result.js.map +1 -1
  287. package/dist/extensions/index.d.ts +1 -1
  288. package/dist/extensions/index.js.map +1 -1
  289. package/dist/extensions/llama/huggingface-ui.d.ts +2 -2
  290. package/dist/extensions/llama/huggingface-ui.js.map +1 -1
  291. package/dist/extensions/llama/index.d.ts +1 -1
  292. package/dist/extensions/llama/index.js.map +1 -1
  293. package/dist/extensions/llama/ui.d.ts +1 -1
  294. package/dist/extensions/llama/ui.js.map +1 -1
  295. package/dist/index.d.ts +1 -1
  296. package/dist/index.d.ts.map +1 -1
  297. package/dist/index.js.map +1 -1
  298. package/dist/main-app-mode.d.ts +1 -0
  299. package/dist/main-app-mode.d.ts.map +1 -1
  300. package/dist/main-app-mode.js +3 -0
  301. package/dist/main-app-mode.js.map +1 -1
  302. package/dist/main.d.ts.map +1 -1
  303. package/dist/main.js +8 -3
  304. package/dist/main.js.map +1 -1
  305. package/dist/modes/interactive/components/chat-session-host-actions.d.ts +7 -2
  306. package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
  307. package/dist/modes/interactive/components/chat-session-host-actions.js +13 -4
  308. package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
  309. package/dist/modes/interactive/components/chat-session-host-editor.d.ts +3 -1
  310. package/dist/modes/interactive/components/chat-session-host-editor.d.ts.map +1 -1
  311. package/dist/modes/interactive/components/chat-session-host-editor.js +2 -2
  312. package/dist/modes/interactive/components/chat-session-host-editor.js.map +1 -1
  313. package/dist/modes/interactive/components/chat-session-host-events.d.ts +3 -0
  314. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  315. package/dist/modes/interactive/components/chat-session-host-events.js +5 -4
  316. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  317. package/dist/modes/interactive/components/chat-session-host.d.ts +16 -2
  318. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  319. package/dist/modes/interactive/components/chat-session-host.js +35 -5
  320. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  321. package/dist/modes/interactive/components/index.d.ts +1 -0
  322. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  323. package/dist/modes/interactive/components/index.js.map +1 -1
  324. package/dist/modes/interactive/components/model-selector.d.ts +0 -1
  325. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  326. package/dist/modes/interactive/components/model-selector.js +25 -35
  327. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  328. package/dist/modes/interactive/interactive-editor-actions.js +2 -1
  329. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  330. package/dist/modes/interactive/interactive-input-handling.js +1 -1
  331. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  332. package/dist/modes/interactive/interactive-mode-surface.d.ts +4 -1
  333. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  334. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  335. package/dist/modes/interactive/interactive-model-routing.js +4 -1
  336. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  337. package/dist/modes/interactive/interactive-pause.d.ts +3 -1
  338. package/dist/modes/interactive/interactive-pause.d.ts.map +1 -1
  339. package/dist/modes/interactive/interactive-pause.js +5 -1
  340. package/dist/modes/interactive/interactive-pause.js.map +1 -1
  341. package/dist/modes/interactive/interactive-queueing.js +3 -3
  342. package/dist/modes/interactive/interactive-queueing.js.map +1 -1
  343. package/dist/modes/interactive-engine/engine-health.d.ts +6 -0
  344. package/dist/modes/interactive-engine/engine-health.d.ts.map +1 -1
  345. package/dist/modes/interactive-engine/engine-health.js +15 -1
  346. package/dist/modes/interactive-engine/engine-health.js.map +1 -1
  347. package/dist/modes/interactive-engine/isolated-auth.js +1 -1
  348. package/dist/modes/interactive-engine/isolated-auth.js.map +1 -1
  349. package/dist/modes/interactive-engine/isolated-runtime.d.ts +1 -0
  350. package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
  351. package/dist/modes/interactive-engine/isolated-runtime.js +7 -1
  352. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
  353. package/dist/modes/interactive-engine/remote-model-catalog.d.ts.map +1 -1
  354. package/dist/modes/interactive-engine/remote-model-catalog.js +5 -1
  355. package/dist/modes/interactive-engine/remote-model-catalog.js.map +1 -1
  356. package/dist/modes/interactive-engine/remote-queue-pause.d.ts +1 -1
  357. package/dist/modes/interactive-engine/remote-queue-pause.js.map +1 -1
  358. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  359. package/dist/modes/rpc/rpc-command-handler.js +23 -7
  360. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  361. package/dist/modes/rpc/rpc-input-scheduler.js +1 -1
  362. package/dist/modes/rpc/rpc-input-scheduler.js.map +1 -1
  363. package/dist/modes/rpc/rpc-types.d.ts +2 -1
  364. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  365. package/dist/modes/rpc/rpc-types.js.map +1 -1
  366. package/docs/compaction.md +24 -0
  367. package/docs/custom-provider.md +3 -3
  368. package/docs/extensions.md +3 -1
  369. package/docs/index.md +10 -0
  370. package/docs/keybindings.md +1 -1
  371. package/docs/models.md +2 -0
  372. package/docs/providers.md +7 -3
  373. package/docs/quickstart.md +7 -1
  374. package/docs/session-format.md +2 -0
  375. package/docs/termux.md +3 -1
  376. package/docs/usage.md +3 -2
  377. package/docs/workflows.md +138 -46
  378. package/npm-shrinkwrap.json +69 -37
  379. package/package.json +4 -4
  380. package/dist/builtin/workflows/src/tui/toast.ts +0 -107
@@ -7,6 +7,7 @@ import {
7
7
  } from "../shared/returned-run-status.js";
8
8
  import { isTopLevelWorkflowRun } from "../shared/run-visibility.js";
9
9
  import type { Store } from "../shared/store.js";
10
+ import { readGraphStoreSnapshot, subscribeStoreInvalidation } from "../shared/store-observation.js";
10
11
  import type {
11
12
  PendingPrompt,
12
13
  PromptKind,
@@ -175,7 +176,9 @@ export function installWorkflowLifecycleNotifications(options: WorkflowLifecycle
175
176
  const notifyOn = new Set<WorkflowLifecycleNoticeKind>(options.config.notifyOn);
176
177
  const state = options.state ?? createWorkflowLifecycleNotificationState();
177
178
  let delivery!: ReturnType<typeof createLifecycleNoticeDelivery>;
178
- if (options.seedExisting !== false) seedWorkflowLifecycleNotificationState(state, options.store.snapshot());
179
+ if (options.seedExisting !== false) {
180
+ seedWorkflowLifecycleNotificationState(state, readGraphStoreSnapshot(options.store));
181
+ }
179
182
 
180
183
  const emit = (details: WorkflowLifecycleNoticeDetails): boolean | Promise<boolean> => {
181
184
  try {
@@ -266,8 +269,8 @@ export function installWorkflowLifecycleNotifications(options: WorkflowLifecycle
266
269
  if (notifyOn.has(details.kind)) delivery.deliver(key, details);
267
270
  }
268
271
 
269
- const unsubscribe = options.store.subscribe(inspect);
270
- inspect(options.store.snapshot());
272
+ const unsubscribe = subscribeStoreInvalidation(options.store, () => inspect(readGraphStoreSnapshot(options.store)));
273
+ inspect(readGraphStoreSnapshot(options.store));
271
274
  return () => {
272
275
  unsubscribe();
273
276
  delivery.dispose();
@@ -22,6 +22,7 @@ import {
22
22
  import { stageControlRegistry } from "../runs/foreground/stage-control-registry.js";
23
23
  import type { StageAdapters } from "../runs/foreground/stage-runner.js";
24
24
  import { store } from "../shared/store.js";
25
+ import { readGraphStoreSnapshot } from "../shared/store-observation.js";
25
26
 
26
27
  export interface PostMortemResolverDeps {
27
28
  readonly adapters: StageAdapters;
@@ -33,7 +34,7 @@ function resolveStageCwd(runId: string): string | undefined {
33
34
  try {
34
35
  const backend = getDurableBackend();
35
36
  const owningHandle = backend.getWorkflow(runId);
36
- const run = store.snapshot().runs.find((candidate) => candidate.id === runId);
37
+ const run = readGraphStoreSnapshot(store).runs.find((candidate) => candidate.id === runId);
37
38
  const rootRunId = run?.rootRunId ?? owningHandle?.rootWorkflowId;
38
39
  const cwdHandle = rootRunId === undefined ? owningHandle : (backend.getWorkflow(rootRunId) ?? owningHandle);
39
40
  return cwdHandle?.workflowCwd ?? cwdHandle?.invocationCwd ?? undefined;
@@ -61,7 +62,7 @@ export function createPostMortemHandleResolver(
61
62
  deps: PostMortemResolverDeps,
62
63
  ): (runId: string, stageId: string) => EnsurePostMortemStageHandleResult | undefined {
63
64
  return (runId, stageId) => {
64
- const run = store.snapshot().runs.find((candidate) => candidate.id === runId);
65
+ const run = readGraphStoreSnapshot(store).runs.find((candidate) => candidate.id === runId);
65
66
  const stage = run?.stages.find((candidate) => candidate.id === stageId);
66
67
  if (stage === undefined) return undefined;
67
68
  return ensurePostMortemStageHandle(runId, stage, postMortemDepsForRun(runId, deps));
@@ -442,9 +442,7 @@ export function renderResult(result: WorkflowToolResult, opts?: RenderResultOpts
442
442
  const r = result as StageListResult;
443
443
  if (r.error) return renderNotice("WORKFLOW STAGES", `${r.runId || "(none)"}: ${r.error}`, opts, themed);
444
444
  const counts = r.stages
445
- .map(
446
- (s) => `${s.name} (${s.id.slice(0, 12)}): ${s.status}${s.skippedReason ? ` — ${s.skippedReason}` : ""}`,
447
- )
445
+ .map((s) => `${s.name} (${s.id}): ${s.status}${s.skippedReason ? ` — ${s.skippedReason}` : ""}`)
448
446
  .join("; ");
449
447
  return renderNotice("WORKFLOW STAGES", `${r.runId}: ${r.filter} — ${counts || "no stages"}`, opts, themed);
450
448
  }
@@ -456,7 +454,7 @@ export function renderResult(result: WorkflowToolResult, opts?: RenderResultOpts
456
454
  const extra = r.stage.error ? ` — ${r.stage.error}` : r.stage.result ? ` — ${r.stage.result}` : "";
457
455
  return renderNotice(
458
456
  "WORKFLOW STAGE",
459
- `${r.runId}: ${r.stage.name} (${r.stage.id.slice(0, 12)}) ${r.stage.status}${extra}`,
457
+ `${r.runId}: ${r.stage.name} (${r.stage.id}) ${r.stage.status}${extra}`,
460
458
  opts,
461
459
  themed,
462
460
  );
@@ -468,7 +466,7 @@ export function renderResult(result: WorkflowToolResult, opts?: RenderResultOpts
468
466
  const suffix = r.truncated ? " (truncated)" : "";
469
467
  return renderNotice(
470
468
  "WORKFLOW TRANSCRIPT",
471
- `${r.runId}/${r.stageId.slice(0, 12)} ${r.source}: ${text}${suffix}`,
469
+ `${r.runId}/${r.stageId} ${r.source}: ${text}${suffix}`,
472
470
  opts,
473
471
  themed,
474
472
  );
@@ -476,12 +474,7 @@ export function renderResult(result: WorkflowToolResult, opts?: RenderResultOpts
476
474
 
477
475
  case "send": {
478
476
  const r = result as SendResult;
479
- return renderNotice(
480
- "WORKFLOW SEND",
481
- `${r.runId}/${r.stageId.slice(0, 12)} ${r.delivery}: ${r.message}`,
482
- opts,
483
- themed,
484
- );
477
+ return renderNotice("WORKFLOW SEND", `${r.runId}/${r.stageId} ${r.delivery}: ${r.message}`, opts, themed);
485
478
  }
486
479
 
487
480
  case "pause": {
@@ -25,17 +25,17 @@ import { discoverWorkflows } from "./discovery.js";
25
25
 
26
26
  export interface DurableResumeRuntime {
27
27
  resumeDurableWorkflow(
28
- workflowIdOrPrefix: string,
28
+ workflowId: string,
29
29
  options?: { readonly policy?: WorkflowExecutionPolicy },
30
30
  ): Promise<ResumeDurableResult>;
31
31
  listDurableResumable(): readonly ResumableWorkflowEntry[];
32
- prepareDurableResumable(workflowIdOrPrefix?: string): Promise<readonly ResumableWorkflowEntry[]>;
32
+ prepareDurableResumable(workflowId?: string): Promise<readonly ResumableWorkflowEntry[]>;
33
33
  prepareDurableCatalog?(): Promise<DurableWorkflowCatalogEntries>;
34
34
  /** Hydrate a bounded set of known DBOS workflow ids. */
35
35
  prepareDurableResumableForIds?(workflowIds: readonly string[]): Promise<readonly ResumableWorkflowEntry[]>;
36
36
  prepareCompletedDurable?(): Promise<readonly ResumableWorkflowEntry[]>;
37
37
  openCompletedDurableWorkflow?(
38
- workflowIdOrPrefix: string,
38
+ workflowId: string,
39
39
  catalog?: readonly ResumableWorkflowEntry[],
40
40
  ): OpenCompletedDurableResult;
41
41
  }
@@ -60,18 +60,18 @@ export function createDurableResumeRuntime(deps: DurableResumeRuntimeDeps): Dura
60
60
  const ids = deps.store
61
61
  .runs()
62
62
  .map((run) => run.id)
63
- .filter((id) => target === undefined || id === target || id.startsWith(target));
63
+ .filter((id) => target === undefined || id === target);
64
64
  for (const id of ids) await backend.hydrateWorkflow(id);
65
65
  };
66
66
  let preparedCatalog: readonly ResumableWorkflowEntry[] = [];
67
67
  return {
68
- async resumeDurableWorkflow(workflowIdOrPrefix, options): Promise<ResumeDurableResult> {
68
+ async resumeDurableWorkflow(workflowId, options): Promise<ResumeDurableResult> {
69
69
  await deps.ensureReady();
70
70
  const backend = getDurableBackend();
71
71
  if (preparedCatalog.length === 0) {
72
- preparedCatalog = await prepareRuntimeDurableResumable(() => backend, workflowIdOrPrefix);
72
+ preparedCatalog = await prepareRuntimeDurableResumable(() => backend, workflowId);
73
73
  }
74
- const resolved = resolveCatalogEntry(workflowIdOrPrefix, preparedCatalog);
74
+ const resolved = resolveCatalogEntry(workflowId, preparedCatalog);
75
75
  if (resolved !== undefined) await backend.hydrateWorkflow(resolved.workflowId);
76
76
  const adapterDeps: ResumeDurableDeps = {
77
77
  registry: deps.registry,
@@ -81,17 +81,17 @@ export function createDurableResumeRuntime(deps: DurableResumeRuntimeDeps): Dura
81
81
  (await discoverWorkflows({ cwd: cwd ?? deps.runtimeCwd })).registry.get(name),
82
82
  ...(deps.jobs !== undefined ? { jobs: deps.jobs } : {}),
83
83
  };
84
- return await resumeDurableWorkflowAdapter(workflowIdOrPrefix, adapterDeps, preparedCatalog);
84
+ return await resumeDurableWorkflowAdapter(workflowId, adapterDeps, preparedCatalog);
85
85
  },
86
86
  listDurableResumable(): readonly ResumableWorkflowEntry[] {
87
87
  return getDurableBackend().listResumableWorkflows();
88
88
  },
89
- async prepareDurableResumable(workflowIdOrPrefix) {
89
+ async prepareDurableResumable(workflowId) {
90
90
  await deps.ensureReady();
91
91
  const backend = getDurableBackend();
92
92
  try {
93
- await hydrateStoredWorkflowCandidates(backend, workflowIdOrPrefix);
94
- preparedCatalog = await prepareRuntimeDurableResumable(() => backend, workflowIdOrPrefix);
93
+ await hydrateStoredWorkflowCandidates(backend, workflowId);
94
+ preparedCatalog = await prepareRuntimeDurableResumable(() => backend, workflowId);
95
95
  return preparedCatalog;
96
96
  } finally {
97
97
  purgeSuppressedWorkflowRuns(backend, deps.store);
@@ -131,12 +131,12 @@ export function createDurableResumeRuntime(deps: DurableResumeRuntimeDeps): Dura
131
131
  purgeSuppressedWorkflowRuns(backend, deps.store);
132
132
  }
133
133
  },
134
- openCompletedDurableWorkflow(workflowIdOrPrefix, catalog) {
134
+ openCompletedDurableWorkflow(workflowId, catalog) {
135
135
  const backend = getDurableBackend();
136
- const entry = resolveCatalogEntry(workflowIdOrPrefix, catalog ?? []);
137
- const handle = backend.getWorkflow(entry?.workflowId ?? workflowIdOrPrefix);
136
+ const entry = resolveCatalogEntry(workflowId, catalog ?? []);
137
+ const handle = backend.getWorkflow(entry?.workflowId ?? workflowId);
138
138
  return openCompletedSnapshot(
139
- workflowIdOrPrefix,
139
+ workflowId,
140
140
  {
141
141
  durableBackend: backend,
142
142
  store: deps.store,
@@ -152,11 +152,8 @@ export function createDurableResumeRuntime(deps: DurableResumeRuntimeDeps): Dura
152
152
  }
153
153
 
154
154
  function resolveCatalogEntry(
155
- workflowIdOrPrefix: string,
155
+ workflowId: string,
156
156
  catalog: readonly ResumableWorkflowEntry[],
157
157
  ): ResumableWorkflowEntry | undefined {
158
- const exact = catalog.find((entry) => entry.workflowId === workflowIdOrPrefix);
159
- if (exact !== undefined) return exact;
160
- const matches = catalog.filter((entry) => entry.workflowId.startsWith(workflowIdOrPrefix));
161
- return matches.length === 1 ? matches[0] : undefined;
158
+ return catalog.find((entry) => entry.workflowId === workflowId);
162
159
  }
@@ -172,11 +172,11 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
172
172
  }
173
173
 
174
174
  function matchesResumeStageIdentifier(stage: RunSnapshot["stages"][number], identifier: string): boolean {
175
- return stage.id === identifier || stage.name === identifier || stage.id.startsWith(identifier);
175
+ return stage.id === identifier || stage.name === identifier;
176
176
  }
177
177
 
178
178
  function stageLabel(stage: RunSnapshot["stages"][number]): string {
179
- return `${stage.name} (${stage.id.slice(0, 12)})`;
179
+ return `${stage.name} (${stage.id})`;
180
180
  }
181
181
 
182
182
  function resolveUniqueResumeStage(
@@ -261,7 +261,7 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
261
261
  };
262
262
  }
263
263
  const stageMessage = (verb: string, runId: string): string =>
264
- `${verb} workflow "${def.name}" from run ${source.id.slice(0, 8)} at stage ${resolvedStage.stageId.slice(0, 8)} (run ${runId.slice(0, 8)}).`;
264
+ `${verb} workflow "${def.name}" from run ${source.id} at stage ${resolvedStage.stageId} (run ${runId}).`;
265
265
  const launchContinuation = () =>
266
266
  launchDetachedUntilStartup(def, sourceInputs, {
267
267
  ...runOptions(options?.policy),
@@ -43,7 +43,7 @@ function workflowNameItems(runtime: ExtensionRuntime): PiArgumentCompletion[] {
43
43
  function runIdItems(): PiArgumentCompletion[] {
44
44
  return topLevelWorkflowRuns(store.runs()).map((run) => ({
45
45
  value: `${run.id} `,
46
- label: run.id.slice(0, 8),
46
+ label: run.id,
47
47
  description: `${run.name} — ${run.status}`,
48
48
  }));
49
49
  }
@@ -35,7 +35,7 @@ import {
35
35
  import { workflowPolicyFromContext } from "./workflow-policy.js";
36
36
  import { normalizeWorkflowReloadReport, type WorkflowReloadReport } from "./workflow-reload-report.js";
37
37
  import { handleRunControlCommand, type WorkflowRunControlDeps } from "./workflow-run-control-command.js";
38
- import { overlaySurfaceFromContext, reloadFailureMessage, resolveRunIdPrefix } from "./workflow-targets.js";
38
+ import { overlaySurfaceFromContext, reloadFailureMessage, resolveRunId } from "./workflow-targets.js";
39
39
 
40
40
  export interface WorkflowSlashCommandDeps {
41
41
  runtimeProxy: ExtensionRuntime;
@@ -150,13 +150,9 @@ async function workflowSlashHandler(
150
150
  if (subcommand === "status") {
151
151
  const target = parts[1];
152
152
  if (target && !target.startsWith("--")) {
153
- const resolved = resolveRunIdPrefix(target);
153
+ const resolved = resolveRunId(target);
154
+ if (resolved.kind === "malformed") return fail(resolved.message);
154
155
  if (resolved.kind === "not_found") return fail(`Run not found: ${target}`);
155
- if (resolved.kind === "ambiguous") {
156
- return fail(
157
- `Ambiguous run prefix "${target}" matches: ${resolved.matches.map((id) => id.slice(0, 12)).join(", ")}`,
158
- );
159
- }
160
156
  const inspected = inspectRun(resolved.runId);
161
157
  if (!inspected.ok) return fail(`Run not found: ${target}`);
162
158
  emitChatSurface(pi, { kind: "detail", detail: inspected.detail });
@@ -2,10 +2,13 @@ import { listOpenableCompletedWorkflows } from "../durable/completed-catalog.js"
2
2
  import { openCompletedDurableWorkflow } from "../durable/completed-inspection.js";
3
3
  import { getDurableBackend } from "../durable/factory.js";
4
4
  import { formatResumableWorkflowList } from "../durable/resume-catalog.js";
5
+ import { isWorkflowRunResumable } from "../durable/resume-eligibility.js";
5
6
  import { type DurableWorkflowDeleteOutcome, deleteDurableWorkflowIfSafe } from "../durable/retention-policy.js";
6
7
  import type { ResumableWorkflowEntry } from "../durable/types.js";
8
+ import { isFullRunId, malformedRunIdMessage } from "../shared/run-id.js";
7
9
  import { store } from "../shared/store.js";
8
10
  import type { RunSnapshot } from "../shared/store-types.js";
11
+ import { workflowRunResumeCandidate } from "../shared/workflow-artifacts.js";
9
12
  import type { GraphOverlayPort } from "../tui/overlay-adapter.js";
10
13
  import { openWorkflowResumeSelector } from "../tui/workflow-resume-selector.js";
11
14
  import type { ExtensionAPI, PiCommandContext } from "./public-types.js";
@@ -37,12 +40,12 @@ export interface WorkflowResumeTarget {
37
40
 
38
41
  export type WorkflowResumeTargetResolution =
39
42
  | WorkflowResumeTarget
40
- | { readonly kind: "ambiguous"; readonly matches: readonly WorkflowResumeTarget[] }
43
+ | { readonly kind: "malformed"; readonly message: string }
41
44
  | { readonly kind: "not_found" };
42
45
 
43
46
  export async function prepareWorkflowResumeCatalog(
44
47
  runtime: ExtensionRuntime,
45
- activeLiveIds: ReadonlySet<string>,
48
+ suppressedLiveIds: ReadonlySet<string>,
46
49
  target?: string,
47
50
  ): Promise<WorkflowResumeCatalog> {
48
51
  const shared = await runtime.prepareDurableCatalog?.();
@@ -50,8 +53,11 @@ export async function prepareWorkflowResumeCatalog(
50
53
  const backend = getDurableBackend();
51
54
  const isDisplayLoadable = (entry: ResumableWorkflowEntry): boolean =>
52
55
  shared !== undefined || backend.isWorkflowLoadable(entry.workflowId);
56
+ // The durable catalog is already produced by `listResumableWorkflows()`, which
57
+ // applies `isDurableWorkflowResumable`; re-filtering here would only drop rows
58
+ // a hydrating backend has not yet materialized.
53
59
  const resumable = filterSelectorDurableEntries(runtime, prepared).filter(
54
- (entry) => !activeLiveIds.has(entry.workflowId) && isDisplayLoadable(entry),
60
+ (entry) => !suppressedLiveIds.has(entry.workflowId) && isDisplayLoadable(entry),
55
61
  );
56
62
  const completed =
57
63
  shared?.completed ??
@@ -60,7 +66,7 @@ export async function prepareWorkflowResumeCatalog(
60
66
  : listOpenableCompletedWorkflows(backend));
61
67
  return {
62
68
  resumable,
63
- completed: completed.filter((entry) => !activeLiveIds.has(entry.workflowId) && isDisplayLoadable(entry)),
69
+ completed: completed.filter((entry) => isDisplayLoadable(entry)),
64
70
  };
65
71
  }
66
72
 
@@ -99,8 +105,8 @@ export async function handleDurableResume(
99
105
  // directory a second time for the same command invocation.
100
106
  catalog.completed,
101
107
  );
102
- if (resolved.kind === "ambiguous") {
103
- fail(`Ambiguous workflow prefix "${target}" matches: ${formatMatches(resolved.matches)}`);
108
+ if (resolved.kind === "malformed") {
109
+ fail(resolved.message);
104
110
  return true;
105
111
  }
106
112
  if (resolved.kind === "completed") {
@@ -191,21 +197,16 @@ export function resolveWorkflowResumeTarget(
191
197
  name: run.name,
192
198
  });
193
199
  }
200
+ if (!isFullRunId(target)) return { kind: "malformed", message: malformedRunIdMessage(target) };
194
201
  const exact = targets.get(target);
195
- if (exact !== undefined) return exact;
196
- const matches = [...targets.values()].filter((candidate) => candidate.workflowId.startsWith(target));
197
- if (matches.length === 0) return { kind: "not_found" };
198
- if (matches.length === 1) return matches[0]!;
199
- return { kind: "ambiguous", matches };
202
+ return exact ?? { kind: "not_found" };
200
203
  }
201
204
 
202
205
  function isExplicitResumeCandidate(run: RunSnapshot): boolean {
203
- if (run.status === "completed" || run.status === "paused" || run.exitReason === "quit") return true;
204
- if (run.stages.some((stage) => stage.status === "paused")) return true;
205
- if (run.status === "failed") return run.resumable !== false;
206
- if (run.endedAt !== undefined) return false;
207
- if (run.status === "running") return true;
208
- return run.resumable === true && run.failureRecoverability === "recoverable";
206
+ if (run.status === "completed") return true;
207
+ return (
208
+ isWorkflowRunResumable(workflowRunResumeCandidate(run)) || (run.endedAt === undefined && run.status === "running")
209
+ );
209
210
  }
210
211
 
211
212
  async function resumeDurableTarget(
@@ -247,14 +248,14 @@ function openCompletedTarget(
247
248
 
248
249
  function openCompleted(
249
250
  runtime: ExtensionRuntime,
250
- workflowIdOrPrefix: string,
251
+ workflowId: string,
251
252
  catalog: readonly ResumableWorkflowEntry[],
252
253
  beforeRestoreCompleted?: (snapshots: readonly RunSnapshot[]) => void,
253
254
  ) {
254
255
  return (
255
- runtime.openCompletedDurableWorkflow?.(workflowIdOrPrefix, catalog) ??
256
+ runtime.openCompletedDurableWorkflow?.(workflowId, catalog) ??
256
257
  openCompletedDurableWorkflow(
257
- workflowIdOrPrefix,
258
+ workflowId,
258
259
  {
259
260
  durableBackend: getDurableBackend(),
260
261
  store,
@@ -264,7 +265,3 @@ function openCompleted(
264
265
  )
265
266
  );
266
267
  }
267
-
268
- function formatMatches(entries: readonly WorkflowResumeTarget[]): string {
269
- return entries.map((entry) => `${entry.name} (${entry.workflowId.slice(0, 8)})`).join(", ");
270
- }
@@ -4,6 +4,7 @@ export const WORKFLOW_TOOL_DESCRIPTION =
4
4
  "discover with list/get/inputs/models, list session runs with status (no runId; statusFilter narrows the list), inspect status/stages/stage details, " +
5
5
  "send prompt answers or steering only while the root workflow is nonterminal, pause/resume/interrupt/quit runs, and reload workflow resources. " +
6
6
  "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. " +
7
+ "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. " +
7
8
  "For transcripts, prefer status/stages/stage to get sessionFile/transcriptPath, " +
8
9
  "quote the exact path without rewriting separators (Windows backslashes are valid), " +
9
10
  "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. " +
@@ -37,6 +38,8 @@ export const DEFAULT_PROMPT_GUIDANCE: string[] = [
37
38
  - Only skip workflows for tiny, deterministic, low-risk answers or direct edits where stage tracking clearly costs more than it adds, typically a single-file/no-test/no-review change or a simple answer.`,
38
39
  `**Workflow discovery and lifecycle**:
39
40
  - For unfamiliar named workflows, discover with \`action: "list"\`, inspect with \`action: "get"\` or \`action: "inputs"\`, and run with \`action: "run"\`, \`workflow\`, and validated \`inputs\`; do not invent workflow names or input keys.
41
+ - Wrap critical parts of the \`inputs\` you pass — objective, prompt, acceptance criteria — in \`<keepContext>\` / \`</keepContext>\`. Tagged text survives compaction verbatim regardless of the compression ratio, and stages inherit it because workflows inject your inputs into their prompts. A long stage is compacted repeatedly, and compaction ranks lines individually: a verbose restated objective outlives the one line that bounds it, so a stage can end up executing a coherent but unbounded version of what you asked for. Decide this per launch rather than tagging everything — tag role constraints, prohibitions, must-hold criteria, and identifiers such as a target branch, worktree path, or issue number; leave background, quoted issue text, and reference material untagged and pass bulk through files and \`reads\`. Protected lines count against the keep target rather than raising it, so an over-tagged input makes the evidence stages need compress harder.
42
+ - Tag steering the same way. A \`send\` amendment is authoritative and stages must carry it forward, but it arrives late in an already-long session and is exactly one short message competing with the whole transcript; \`<keepContext>\` around the requirement keeps it from being compacted away before the stage acts on it.
40
43
  - In interactive chat, named workflow launches run in the background. Run \`/workflow connect <run>\` to see agents working and chat with and steer each stage. Inspection and control calls (\`status\`, \`stages\`, \`stage\`, \`transcript\`, \`send\`, \`pause\`, \`resume\`, \`interrupt\`, \`quit\`) remain available while work runs.
41
44
  - \`workflow send\` is nonterminal-only: once the authoritative root run has completed, failed, skipped, been cancelled or killed, or ended terminal-blocked, start a new workflow if tracked work remains. Proceed inline only when the remaining task is small, deterministic, and low risk. Use explicit \`/workflow attach <run> <stage>\` for user-driven post-mortem chat; it does not resume or modify workflow execution.
42
45
  - Natural-language instructions to create or use a worktree do not enable runner isolation. A named workflow must declare and implement any worktree and feature-branch inputs it supports; inspect its inputs and pass a distinct path and branch for each concurrent item. Reusable \`baseBranch\` binding creates a missing target as a detached checkout from that base or reuses an existing same-repository worktree as-is; neither case checks out a separate feature-branch input.
@@ -55,6 +58,7 @@ export const DEFAULT_PROMPT_GUIDANCE: string[] = [
55
58
  - Every workflow invocation automatically receives one stable, non-default Intercom group. Intercom-capable stages inherit it, nested workflows keep the top-level invocation group, and subagents inherit their launching stage's group. Do not mint or thread group names through ordinary workflow definitions. Use an explicit \`group\` only for an intentional override: a named group or \`group: true\` creates a subgroup, while \`group: "default"\` opts into the shared default group. Stages without Intercom access receive no group, and \`contact_supervisor\` still crosses group boundaries for authorized escalation.
56
59
  - Prefer \`ctx.tool(name, args, fn)\` for workflow-owned TypeScript operations with side effects, such as filesystem writes, network mutations, and external API actions. It creates a tracked, non-attachable durable graph node before invoking \`fn\`; it may be used before, between, after, or without model stages. A completed \`ctx.tool\` call is durably checkpointed with its serializable result, so resume replays that result without rerunning \`fn\`. For checks that may fail during a bounded repair loop, opt into \`failureMode: "return"\`, branch on the typed outcome, and pass only the needed error fields to the repair stage or artifact yourself; Atomic does not inject failure evidence into later prompts. Cancellation and storage faults still throw. Keep pure computation and side-effect-free transformations as ordinary TypeScript. Do not wrap agent-stage internals or every function call indiscriminately; this rule applies to side effects orchestrated directly by the workflow definition.
57
60
  - Pass large stage context through files/artifacts and \`reads\` with an explicit \`Read the file at <path>...\` prompt rather than large \`previous\` payloads or injected session history.
61
+ - Wrap critical stage-prompt content in \`<keepContext>\` / \`</keepContext>\`. Tagged content survives compression verbatim regardless of the compression ratio, and every line of the span including the tag lines is protected. A long-running stage will be compacted, and compaction ranks lines individually: an objective is verbose and restated while the constraint that narrows it is usually one line, so the constraint is the cheaper deletion and what survives reads as broader permission than intended. Tag role constraints that bound a stage to part of the work, acceptance criteria and immutable contracts, explicit prohibitions, and identifiers a stage must not lose such as a target branch, worktree path, or run ID. Do not tag bulk context: protected lines count against the keep target rather than raising it, so a large protected span makes the surrounding transcript compress harder — tag the constraint, not the material it applies to.
58
62
  - Separate implementation/review acceptance from explicitly authorized final actions such as PR/MR/review creation, release tagging, deployment, or publication. Stop implementation loops once acceptance is proven and carry a remaining final action separately.
59
63
  - A model stage sees its local prompt, artifacts, tools, and reads, not the graph name or surrounding implementation. State the concrete action, evidence, and success criteria directly.`,
60
64
  ];
@@ -9,51 +9,63 @@
9
9
  */
10
10
 
11
11
  import { getDurableBackend } from "../durable/factory.js";
12
+ import { isWorkflowRunResumable } from "../durable/resume-eligibility.js";
12
13
  import type { ResumableWorkflowEntry } from "../durable/types.js";
13
14
  import { topLevelWorkflowRuns } from "../shared/run-visibility.js";
14
15
  import type { Store } from "../shared/store.js";
16
+ import { subscribeStoreInvalidation } from "../shared/store-observation.js";
15
17
  import type { RunSnapshot } from "../shared/store-types.js";
18
+ import { workflowRunResumeCandidate } from "../shared/workflow-artifacts.js";
16
19
  import type { WorkflowResumeRefresh } from "../tui/workflow-resume-selector.js";
17
20
  import type { ExtensionRuntime } from "./runtime.js";
18
21
  import { prepareWorkflowResumeCatalog } from "./workflow-durable-resume-command.js";
19
- import { reconcileDurableResumeShadow } from "./workflow-resume-shadow.js";
22
+ import { classifyDurableResumeShadow } from "./workflow-resume-shadow.js";
20
23
 
21
24
  export interface ResumePickerLiveSource {
22
25
  readonly liveRuns: readonly RunSnapshot[];
23
- readonly activeLiveIds: ReadonlySet<string>;
26
+ /** Live ids whose resumable durable duplicates must be suppressed. */
27
+ readonly suppressedLiveIds: ReadonlySet<string>;
24
28
  }
25
29
 
26
- function isActiveRecoverableBlock(run: RunSnapshot): boolean {
27
- return run.endedAt === undefined && run.resumable === true && run.failureRecoverability === "recoverable";
30
+ /** A live run is resumable when the shared predicate accepts it and the durable
31
+ * backend has not explicitly deleted it. A live paused/quit run resumes through
32
+ * its live stage controls, so it must NOT require a durable checkpoint here;
33
+ * a restored snapshot that depends on durable state is filtered by its shadow
34
+ * classification instead.
35
+ */
36
+ function isResumableLiveRun(run: RunSnapshot): boolean {
37
+ if (!getDurableBackend().isWorkflowLoadable(run.id)) return false;
38
+ return isWorkflowRunResumable(workflowRunResumeCandidate(run));
28
39
  }
29
40
 
30
41
  export function collectResumePickerLiveRuns(runStore: Store): ResumePickerLiveSource {
31
- const durableResumeShadows = new Set(
32
- topLevelWorkflowRuns(runStore.runs())
33
- .filter((run) => reconcileDurableResumeShadow(run, runStore))
34
- .map((run) => run.id),
35
- );
36
- const liveRuns = topLevelWorkflowRuns(runStore.runs()).filter(
37
- (run) =>
38
- !durableResumeShadows.has(run.id) &&
39
- (run.status === "paused" ||
40
- (run.status === "failed" && run.resumable !== false) ||
41
- isActiveRecoverableBlock(run)) &&
42
- getDurableBackend().isWorkflowLoadable(run.id),
43
- );
42
+ // `eligible` rows are re-listed from the durable catalog, and `ineligible`
43
+ // rows have no durable checkpoint or pending prompt progress, so the resume
44
+ // path would refuse them. Only `not_shadow` runs can actually be resumed here.
45
+ const runs = topLevelWorkflowRuns(runStore.runs());
46
+ const shadowClassification = new Map(runs.map((run) => [run.id, classifyDurableResumeShadow(run, runStore)]));
47
+ const isOfferable = (run: RunSnapshot): boolean => shadowClassification.get(run.id) === "not_shadow";
48
+ const resumableById = new Map(runs.map((run) => [run.id, isResumableLiveRun(run)]));
49
+ const liveRuns = runs.filter((run) => isOfferable(run) && resumableById.get(run.id) === true);
50
+ const isCurrentlyRunning = (run: RunSnapshot): boolean =>
51
+ run.endedAt === undefined && run.status === "running" && run.exitReason !== "quit";
44
52
  const activeLiveIds = new Set(
45
- topLevelWorkflowRuns(runStore.runs())
53
+ runs
46
54
  .filter(
47
55
  (run) =>
48
- !durableResumeShadows.has(run.id) &&
49
- run.endedAt === undefined &&
50
- run.status === "running" &&
51
- !isActiveRecoverableBlock(run) &&
52
- run.exitReason !== "quit",
56
+ shadowClassification.get(run.id) !== "eligible" &&
57
+ isCurrentlyRunning(run) &&
58
+ resumableById.get(run.id) !== true,
53
59
  )
54
60
  .map((run) => run.id),
55
61
  );
56
- return { liveRuns, activeLiveIds };
62
+ // A non-running snapshot rejected by the shared predicate must not reappear as
63
+ // a resumable durable row. Completed inspection rows remain visible separately.
64
+ const rejectedLiveIds = new Set(
65
+ runs.filter((run) => !isCurrentlyRunning(run) && resumableById.get(run.id) !== true).map((run) => run.id),
66
+ );
67
+ const suppressedLiveIds = new Set([...activeLiveIds, ...rejectedLiveIds]);
68
+ return { liveRuns, suppressedLiveIds };
57
69
  }
58
70
 
59
71
  export interface ResumePickerLiveUpdateOptions {
@@ -66,10 +78,10 @@ export function resumePickerLiveUpdateOptions(
66
78
  runtime: ExtensionRuntime,
67
79
  ): ResumePickerLiveUpdateOptions {
68
80
  return {
69
- watch: (onChange) => runStore.subscribe(() => onChange()),
81
+ watch: (onChange) => subscribeStoreInvalidation(runStore, onChange),
70
82
  refresh: async () => {
71
83
  const current = collectResumePickerLiveRuns(runStore);
72
- const catalog = await prepareWorkflowResumeCatalog(runtime, current.activeLiveIds);
84
+ const catalog = await prepareWorkflowResumeCatalog(runtime, current.suppressedLiveIds);
73
85
  return {
74
86
  liveRuns: current.liveRuns,
75
87
  catalog: { durable: catalog.resumable, completed: catalog.completed },
@@ -5,6 +5,7 @@ import { getLoadableDurableWorkflow } from "../durable/workflow-status-transitio
5
5
  import { type JobTracker, jobTracker } from "../runs/background/job-tracker.js";
6
6
  import { type StageControlRegistry, stageControlRegistry } from "../runs/foreground/stage-control-registry.js";
7
7
  import { expandWorkflowGraph } from "../shared/expanded-workflow-graph.js";
8
+ import { readGraphStoreSnapshot } from "../shared/store-observation.js";
8
9
  import type { Store } from "../shared/store-public-types.js";
9
10
  import type { RunSnapshot } from "../shared/store-types.js";
10
11
 
@@ -28,7 +29,7 @@ export function classifyDurableResumeShadow(
28
29
  const jobs = deps.jobs ?? jobTracker;
29
30
  if (jobs.has(run.id)) return "not_shadow";
30
31
  const controls = deps.stageControls ?? stageControlRegistry;
31
- const graph = expandWorkflowGraph(store.snapshot(), run.id);
32
+ const graph = expandWorkflowGraph(readGraphStoreSnapshot(store), run.id);
32
33
  const controlRunIds = new Set<string>([run.id]);
33
34
  for (const stage of graph.stages) controlRunIds.add(stage.workflowGraphTarget.runId);
34
35
  if ([...controlRunIds].some((runId) => controls.run(runId).stages().length > 0)) return "not_shadow";