@bastani/atomic 0.9.2 → 0.9.3-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 (606) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/cursor/CHANGELOG.md +15 -0
  4. package/dist/builtin/cursor/README.md +2 -1
  5. package/dist/builtin/cursor/package.json +2 -2
  6. package/dist/builtin/cursor/src/cursor-models-raw.json +2 -9
  7. package/dist/builtin/cursor/src/model-mapper.ts +14 -3
  8. package/dist/builtin/cursor/src/proto/protobuf-codec-base64.ts +22 -0
  9. package/dist/builtin/cursor/src/proto/protobuf-codec-request.ts +53 -13
  10. package/dist/builtin/cursor/src/proto/protobuf-codec-wire.ts +24 -7
  11. package/dist/builtin/cursor/src/proto/protobuf-codec.ts +3 -2
  12. package/dist/builtin/cursor/src/stream.ts +5 -11
  13. package/dist/builtin/cursor/src/transport-types.ts +3 -0
  14. package/dist/builtin/cursor/src/transport.ts +1 -0
  15. package/dist/builtin/intercom/package.json +1 -1
  16. package/dist/builtin/mcp/CHANGELOG.md +6 -0
  17. package/dist/builtin/mcp/direct-tools.ts +4 -2
  18. package/dist/builtin/mcp/package.json +1 -1
  19. package/dist/builtin/mcp/proxy-call.ts +3 -1
  20. package/dist/builtin/mcp/utils.ts +18 -7
  21. package/dist/builtin/subagents/CHANGELOG.md +20 -0
  22. package/dist/builtin/subagents/README.md +6 -6
  23. package/dist/builtin/subagents/agents/code-simplifier.md +7 -6
  24. package/dist/builtin/subagents/agents/codebase-analyzer.md +5 -4
  25. package/dist/builtin/subagents/agents/codebase-locator.md +3 -3
  26. package/dist/builtin/subagents/agents/codebase-online-researcher.md +10 -10
  27. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +4 -4
  28. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +3 -3
  29. package/dist/builtin/subagents/agents/codebase-research-locator.md +4 -4
  30. package/dist/builtin/subagents/agents/debugger.md +5 -5
  31. package/dist/builtin/subagents/agents/worker.md +56 -0
  32. package/dist/builtin/subagents/package.json +1 -1
  33. package/dist/builtin/subagents/skills/subagent/SKILL.md +11 -11
  34. package/dist/builtin/subagents/src/agents/agent-loaders.ts +3 -5
  35. package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +3 -3
  36. package/dist/builtin/subagents/src/extension/fanout-child.ts +1 -0
  37. package/dist/builtin/subagents/src/extension/index.ts +6 -3
  38. package/dist/builtin/subagents/src/extension/schemas.ts +2 -7
  39. package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -3
  40. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -4
  41. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +15 -1
  42. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +35 -1
  43. package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +1 -1
  44. package/dist/builtin/subagents/src/runs/shared/nested-render.ts +2 -2
  45. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -1
  46. package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +4 -2
  47. package/dist/builtin/subagents/src/shared/types-async.ts +1 -0
  48. package/dist/builtin/subagents/src/shared/types-depth.ts +5 -5
  49. package/dist/builtin/subagents/src/shared/types-runtime.ts +2 -1
  50. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +27 -5
  51. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -2
  52. package/dist/builtin/subagents/src/tui/render-layout.ts +27 -4
  53. package/dist/builtin/subagents/src/tui/render-result-animation.ts +22 -31
  54. package/dist/builtin/subagents/src/tui/render-result-compact.ts +6 -6
  55. package/dist/builtin/subagents/src/tui/render-result.ts +20 -19
  56. package/dist/builtin/subagents/src/tui/render-status-progress.ts +3 -3
  57. package/dist/builtin/subagents/src/tui/render-widget.ts +46 -7
  58. package/dist/builtin/subagents/src/tui/render.ts +2 -2
  59. package/dist/builtin/web-access/package.json +1 -1
  60. package/dist/builtin/workflows/CHANGELOG.md +56 -0
  61. package/dist/builtin/workflows/README.md +3 -3
  62. package/dist/builtin/workflows/builtin/goal-artifacts.ts +11 -6
  63. package/dist/builtin/workflows/builtin/goal-ledger.ts +33 -1
  64. package/dist/builtin/workflows/builtin/goal-prompts.ts +23 -28
  65. package/dist/builtin/workflows/builtin/goal-reducer.ts +2 -2
  66. package/dist/builtin/workflows/builtin/goal-reports.ts +2 -5
  67. package/dist/builtin/workflows/builtin/goal-review.ts +1 -1
  68. package/dist/builtin/workflows/builtin/goal-runner.ts +10 -17
  69. package/dist/builtin/workflows/builtin/open-claude-design-feedback.ts +3 -3
  70. package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +1 -3
  71. package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +1 -1
  72. package/dist/builtin/workflows/builtin/ralph-core.ts +7 -17
  73. package/dist/builtin/workflows/builtin/ralph-runner.ts +11 -18
  74. package/dist/builtin/workflows/builtin/shared-prompts.ts +1 -1
  75. package/dist/builtin/workflows/package.json +1 -1
  76. package/dist/builtin/workflows/src/authoring.d.ts +1 -1
  77. package/dist/builtin/workflows/src/durable/backend.ts +343 -0
  78. package/dist/builtin/workflows/src/durable/child-primitive.ts +79 -0
  79. package/dist/builtin/workflows/src/durable/dbos-backend.ts +421 -0
  80. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +171 -0
  81. package/dist/builtin/workflows/src/durable/factory.ts +96 -0
  82. package/dist/builtin/workflows/src/durable/file-backend.ts +433 -0
  83. package/dist/builtin/workflows/src/durable/index.ts +73 -0
  84. package/dist/builtin/workflows/src/durable/resume-catalog.ts +217 -0
  85. package/dist/builtin/workflows/src/durable/resume-runtime.ts +299 -0
  86. package/dist/builtin/workflows/src/durable/scoped-backend.ts +171 -0
  87. package/dist/builtin/workflows/src/durable/stage-primitive.ts +284 -0
  88. package/dist/builtin/workflows/src/durable/tool-primitive.ts +180 -0
  89. package/dist/builtin/workflows/src/durable/types.ts +168 -0
  90. package/dist/builtin/workflows/src/durable/ui-primitive.ts +96 -0
  91. package/dist/builtin/workflows/src/engine/options.ts +3 -0
  92. package/dist/builtin/workflows/src/engine/primitives/parallel.ts +2 -2
  93. package/dist/builtin/workflows/src/engine/primitives/task.ts +4 -4
  94. package/dist/builtin/workflows/src/engine/primitives/ui.ts +22 -8
  95. package/dist/builtin/workflows/src/engine/primitives/workflow.ts +8 -0
  96. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +69 -0
  97. package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +31 -0
  98. package/dist/builtin/workflows/src/engine/run.ts +148 -6
  99. package/dist/builtin/workflows/src/engine/runtime.ts +8 -2
  100. package/dist/builtin/workflows/src/extension/config-loader.ts +35 -15
  101. package/dist/builtin/workflows/src/extension/discovery.ts +20 -8
  102. package/dist/builtin/workflows/src/extension/extension-factory.ts +6 -12
  103. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +5 -1
  104. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +4 -2
  105. package/dist/builtin/workflows/src/extension/runtime.ts +48 -9
  106. package/dist/builtin/workflows/src/extension/wiring.ts +1 -1
  107. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +143 -4
  108. package/dist/builtin/workflows/src/runs/background/quit.ts +61 -0
  109. package/dist/builtin/workflows/src/runs/background/status.ts +1 -0
  110. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +5 -5
  111. package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +74 -33
  112. package/dist/builtin/workflows/src/runs/foreground/executor-stage-context.ts +20 -1
  113. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +8 -7
  114. package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +1 -0
  115. package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +1 -1
  116. package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +19 -2
  117. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +4 -0
  118. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +10 -10
  119. package/dist/builtin/workflows/src/runs/foreground/stage-runner-options.ts +5 -1
  120. package/dist/builtin/workflows/src/runs/foreground/stage-runner-send-user-message.ts +25 -0
  121. package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +3 -0
  122. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +16 -0
  123. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +20 -0
  124. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +23 -1
  125. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +30 -1
  126. package/dist/builtin/workflows/src/shared/store-public-types.ts +6 -2
  127. package/dist/builtin/workflows/src/shared/store-run-methods.ts +12 -6
  128. package/dist/builtin/workflows/src/shared/types.ts +55 -0
  129. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +11 -10
  130. package/dist/builtin/workflows/src/tui/graph-view-constants.ts +1 -1
  131. package/dist/builtin/workflows/src/tui/graph-view-graph-render.ts +41 -0
  132. package/dist/builtin/workflows/src/tui/graph-view-input.ts +82 -24
  133. package/dist/builtin/workflows/src/tui/graph-view-render.ts +7 -0
  134. package/dist/builtin/workflows/src/tui/graph-view-state.ts +22 -2
  135. package/dist/builtin/workflows/src/tui/graph-view-types.ts +4 -5
  136. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +9 -11
  137. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +9 -3
  138. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +11 -2
  139. package/dist/builtin/workflows/src/tui/stage-chat-view-live-events.ts +35 -0
  140. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +51 -17
  141. package/dist/builtin/workflows/src/tui/stage-chat-view-status.ts +36 -0
  142. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +5 -1
  143. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +3 -1
  144. package/dist/builtin/workflows/src/tui/status-list.ts +14 -2
  145. package/dist/builtin/workflows/src/tui/widget.ts +23 -8
  146. package/dist/builtin/workflows/src/tui/workflow-attach-pane-types.ts +5 -4
  147. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +8 -8
  148. package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +151 -0
  149. package/dist/cli/args.d.ts.map +1 -1
  150. package/dist/cli/args.js +9 -9
  151. package/dist/cli/args.js.map +1 -1
  152. package/dist/config-self-update.d.ts.map +1 -1
  153. package/dist/config-self-update.js +3 -4
  154. package/dist/config-self-update.js.map +1 -1
  155. package/dist/config.d.ts.map +1 -1
  156. package/dist/config.js +4 -5
  157. package/dist/config.js.map +1 -1
  158. package/dist/core/agent-session-bash.d.ts +1 -0
  159. package/dist/core/agent-session-bash.d.ts.map +1 -1
  160. package/dist/core/agent-session-bash.js +1 -0
  161. package/dist/core/agent-session-bash.js.map +1 -1
  162. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  163. package/dist/core/agent-session-tool-registry.js +23 -0
  164. package/dist/core/agent-session-tool-registry.js.map +1 -1
  165. package/dist/core/bash-executor.d.ts +2 -0
  166. package/dist/core/bash-executor.d.ts.map +1 -1
  167. package/dist/core/bash-executor.js +1 -0
  168. package/dist/core/bash-executor.js.map +1 -1
  169. package/dist/core/compaction/compaction.d.ts +29 -0
  170. package/dist/core/compaction/compaction.d.ts.map +1 -1
  171. package/dist/core/compaction/compaction.js +36 -1
  172. package/dist/core/compaction/compaction.js.map +1 -1
  173. package/dist/core/compaction/context-compaction-metrics.d.ts +14 -2
  174. package/dist/core/compaction/context-compaction-metrics.d.ts.map +1 -1
  175. package/dist/core/compaction/context-compaction-metrics.js +50 -1
  176. package/dist/core/compaction/context-compaction-metrics.js.map +1 -1
  177. package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
  178. package/dist/core/compaction/context-compaction-prompt.js +2 -0
  179. package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
  180. package/dist/core/compaction/context-compaction-runner.d.ts.map +1 -1
  181. package/dist/core/compaction/context-compaction-runner.js +1 -1
  182. package/dist/core/compaction/context-compaction-runner.js.map +1 -1
  183. package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
  184. package/dist/core/compaction/context-deletion-application.js +5 -5
  185. package/dist/core/compaction/context-deletion-application.js.map +1 -1
  186. package/dist/core/compaction/context-deletion-targets.d.ts +2 -0
  187. package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
  188. package/dist/core/compaction/context-deletion-targets.js +23 -3
  189. package/dist/core/compaction/context-deletion-targets.js.map +1 -1
  190. package/dist/core/compaction/context-deletion-tool-definitions.d.ts +6 -0
  191. package/dist/core/compaction/context-deletion-tool-definitions.d.ts.map +1 -1
  192. package/dist/core/compaction/context-deletion-tool-definitions.js.map +1 -1
  193. package/dist/core/compaction/context-deletion-tools.d.ts.map +1 -1
  194. package/dist/core/compaction/context-deletion-tools.js +18 -10
  195. package/dist/core/compaction/context-deletion-tools.js.map +1 -1
  196. package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
  197. package/dist/core/compaction/context-transcript-analysis.js +2 -4
  198. package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
  199. package/dist/core/copilot-gemini-tool-arguments.d.ts.map +1 -1
  200. package/dist/core/copilot-gemini-tool-arguments.js +2 -60
  201. package/dist/core/copilot-gemini-tool-arguments.js.map +1 -1
  202. package/dist/core/extensions/context-types.d.ts +2 -0
  203. package/dist/core/extensions/context-types.d.ts.map +1 -1
  204. package/dist/core/extensions/context-types.js.map +1 -1
  205. package/dist/core/extensions/index.d.ts +2 -2
  206. package/dist/core/extensions/index.d.ts.map +1 -1
  207. package/dist/core/extensions/index.js +1 -1
  208. package/dist/core/extensions/index.js.map +1 -1
  209. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  210. package/dist/core/extensions/loader-virtual-modules.js +57 -32
  211. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  212. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  213. package/dist/core/extensions/runner-context.js +11 -0
  214. package/dist/core/extensions/runner-context.js.map +1 -1
  215. package/dist/core/extensions/tool-events.d.ts +13 -13
  216. package/dist/core/extensions/tool-events.d.ts.map +1 -1
  217. package/dist/core/extensions/tool-events.js +3 -3
  218. package/dist/core/extensions/tool-events.js.map +1 -1
  219. package/dist/core/extensions/types.d.ts +1 -1
  220. package/dist/core/extensions/types.d.ts.map +1 -1
  221. package/dist/core/extensions/types.js +1 -1
  222. package/dist/core/extensions/types.js.map +1 -1
  223. package/dist/core/flattened-tool-arguments.d.ts +18 -0
  224. package/dist/core/flattened-tool-arguments.d.ts.map +1 -1
  225. package/dist/core/flattened-tool-arguments.js +104 -0
  226. package/dist/core/flattened-tool-arguments.js.map +1 -1
  227. package/dist/core/messages.d.ts +1 -0
  228. package/dist/core/messages.d.ts.map +1 -1
  229. package/dist/core/messages.js +46 -1
  230. package/dist/core/messages.js.map +1 -1
  231. package/dist/core/sdk-exports.d.ts +1 -1
  232. package/dist/core/sdk-exports.d.ts.map +1 -1
  233. package/dist/core/sdk-exports.js +1 -1
  234. package/dist/core/sdk-exports.js.map +1 -1
  235. package/dist/core/sdk-types.d.ts +2 -2
  236. package/dist/core/sdk-types.d.ts.map +1 -1
  237. package/dist/core/sdk-types.js.map +1 -1
  238. package/dist/core/sdk.d.ts.map +1 -1
  239. package/dist/core/sdk.js +12 -0
  240. package/dist/core/sdk.js.map +1 -1
  241. package/dist/core/session-manager-core.d.ts +15 -7
  242. package/dist/core/session-manager-core.d.ts.map +1 -1
  243. package/dist/core/session-manager-core.js +20 -9
  244. package/dist/core/session-manager-core.js.map +1 -1
  245. package/dist/core/session-manager-entries.d.ts +2 -2
  246. package/dist/core/session-manager-entries.d.ts.map +1 -1
  247. package/dist/core/session-manager-entries.js +9 -3
  248. package/dist/core/session-manager-entries.js.map +1 -1
  249. package/dist/core/session-manager-history.d.ts.map +1 -1
  250. package/dist/core/session-manager-history.js +2 -1
  251. package/dist/core/session-manager-history.js.map +1 -1
  252. package/dist/core/session-manager-list.d.ts +3 -3
  253. package/dist/core/session-manager-list.d.ts.map +1 -1
  254. package/dist/core/session-manager-list.js +27 -8
  255. package/dist/core/session-manager-list.js.map +1 -1
  256. package/dist/core/session-manager-storage.d.ts +3 -1
  257. package/dist/core/session-manager-storage.d.ts.map +1 -1
  258. package/dist/core/session-manager-storage.js +55 -12
  259. package/dist/core/session-manager-storage.js.map +1 -1
  260. package/dist/core/session-manager-tool-dependencies.d.ts +10 -0
  261. package/dist/core/session-manager-tool-dependencies.d.ts.map +1 -0
  262. package/dist/core/session-manager-tool-dependencies.js +133 -0
  263. package/dist/core/session-manager-tool-dependencies.js.map +1 -0
  264. package/dist/core/session-manager-types.d.ts +22 -0
  265. package/dist/core/session-manager-types.d.ts.map +1 -1
  266. package/dist/core/session-manager-types.js.map +1 -1
  267. package/dist/core/session-manager.d.ts +2 -2
  268. package/dist/core/session-manager.d.ts.map +1 -1
  269. package/dist/core/session-manager.js +1 -1
  270. package/dist/core/session-manager.js.map +1 -1
  271. package/dist/core/settings-manager-basic-accessors.d.ts +4 -0
  272. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  273. package/dist/core/settings-manager-basic-accessors.js +18 -0
  274. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  275. package/dist/core/settings-manager-resource-accessors.d.ts +4 -0
  276. package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
  277. package/dist/core/settings-manager-resource-accessors.js +15 -0
  278. package/dist/core/settings-manager-resource-accessors.js.map +1 -1
  279. package/dist/core/settings-types.d.ts +11 -0
  280. package/dist/core/settings-types.d.ts.map +1 -1
  281. package/dist/core/settings-types.js.map +1 -1
  282. package/dist/core/system-prompt.d.ts +1 -1
  283. package/dist/core/system-prompt.d.ts.map +1 -1
  284. package/dist/core/system-prompt.js +3 -2
  285. package/dist/core/system-prompt.js.map +1 -1
  286. package/dist/core/tools/artifact-protocol.d.ts +11 -0
  287. package/dist/core/tools/artifact-protocol.d.ts.map +1 -0
  288. package/dist/core/tools/artifact-protocol.js +76 -0
  289. package/dist/core/tools/artifact-protocol.js.map +1 -0
  290. package/dist/core/tools/artifacts.d.ts +18 -0
  291. package/dist/core/tools/artifacts.d.ts.map +1 -0
  292. package/dist/core/tools/artifacts.js +90 -0
  293. package/dist/core/tools/artifacts.js.map +1 -0
  294. package/dist/core/tools/bash-async-jobs.d.ts +20 -0
  295. package/dist/core/tools/bash-async-jobs.d.ts.map +1 -0
  296. package/dist/core/tools/bash-async-jobs.js +59 -0
  297. package/dist/core/tools/bash-async-jobs.js.map +1 -0
  298. package/dist/core/tools/bash-async-output.d.ts +10 -0
  299. package/dist/core/tools/bash-async-output.d.ts.map +1 -0
  300. package/dist/core/tools/bash-async-output.js +80 -0
  301. package/dist/core/tools/bash-async-output.js.map +1 -0
  302. package/dist/core/tools/bash-interceptor.d.ts +10 -0
  303. package/dist/core/tools/bash-interceptor.d.ts.map +1 -0
  304. package/dist/core/tools/bash-interceptor.js +39 -0
  305. package/dist/core/tools/bash-interceptor.js.map +1 -0
  306. package/dist/core/tools/bash-leading-cd.d.ts +7 -0
  307. package/dist/core/tools/bash-leading-cd.d.ts.map +1 -0
  308. package/dist/core/tools/bash-leading-cd.js +59 -0
  309. package/dist/core/tools/bash-leading-cd.js.map +1 -0
  310. package/dist/core/tools/bash-pty-native.d.ts +14 -0
  311. package/dist/core/tools/bash-pty-native.d.ts.map +1 -0
  312. package/dist/core/tools/bash-pty-native.js +71 -0
  313. package/dist/core/tools/bash-pty-native.js.map +1 -0
  314. package/dist/core/tools/bash.d.ts +28 -17
  315. package/dist/core/tools/bash.d.ts.map +1 -1
  316. package/dist/core/tools/bash.js +152 -35
  317. package/dist/core/tools/bash.js.map +1 -1
  318. package/dist/core/tools/block-resolver.d.ts +16 -0
  319. package/dist/core/tools/block-resolver.d.ts.map +1 -0
  320. package/dist/core/tools/block-resolver.js +74 -0
  321. package/dist/core/tools/block-resolver.js.map +1 -0
  322. package/dist/core/tools/conflict-registry.d.ts +16 -0
  323. package/dist/core/tools/conflict-registry.d.ts.map +1 -0
  324. package/dist/core/tools/conflict-registry.js +44 -0
  325. package/dist/core/tools/conflict-registry.js.map +1 -0
  326. package/dist/core/tools/directory-tree.d.ts +13 -0
  327. package/dist/core/tools/directory-tree.d.ts.map +1 -0
  328. package/dist/core/tools/directory-tree.js +81 -0
  329. package/dist/core/tools/directory-tree.js.map +1 -0
  330. package/dist/core/tools/edit.d.ts +4 -29
  331. package/dist/core/tools/edit.d.ts.map +1 -1
  332. package/dist/core/tools/edit.js +136 -228
  333. package/dist/core/tools/edit.js.map +1 -1
  334. package/dist/core/tools/fetch-url.d.ts +74 -0
  335. package/dist/core/tools/fetch-url.d.ts.map +1 -0
  336. package/dist/core/tools/fetch-url.js +518 -0
  337. package/dist/core/tools/fetch-url.js.map +1 -0
  338. package/dist/core/tools/find.d.ts +27 -9
  339. package/dist/core/tools/find.d.ts.map +1 -1
  340. package/dist/core/tools/find.js +400 -176
  341. package/dist/core/tools/find.js.map +1 -1
  342. package/dist/core/tools/glob-path-utils.d.ts +8 -0
  343. package/dist/core/tools/glob-path-utils.d.ts.map +1 -0
  344. package/dist/core/tools/glob-path-utils.js +26 -0
  345. package/dist/core/tools/glob-path-utils.js.map +1 -0
  346. package/dist/core/tools/grep.d.ts +12 -0
  347. package/dist/core/tools/grep.d.ts.map +1 -1
  348. package/dist/core/tools/grep.js +141 -17
  349. package/dist/core/tools/grep.js.map +1 -1
  350. package/dist/core/tools/hashline-engine/apply.d.ts +11 -0
  351. package/dist/core/tools/hashline-engine/apply.d.ts.map +1 -0
  352. package/dist/core/tools/hashline-engine/apply.js +752 -0
  353. package/dist/core/tools/hashline-engine/apply.js.map +1 -0
  354. package/dist/core/tools/hashline-engine/block.d.ts +40 -0
  355. package/dist/core/tools/hashline-engine/block.d.ts.map +1 -0
  356. package/dist/core/tools/hashline-engine/block.js +117 -0
  357. package/dist/core/tools/hashline-engine/block.js.map +1 -0
  358. package/dist/core/tools/hashline-engine/diff-preview.d.ts +15 -0
  359. package/dist/core/tools/hashline-engine/diff-preview.d.ts.map +1 -0
  360. package/dist/core/tools/hashline-engine/diff-preview.js +98 -0
  361. package/dist/core/tools/hashline-engine/diff-preview.js.map +1 -0
  362. package/dist/core/tools/hashline-engine/format.d.ts +71 -0
  363. package/dist/core/tools/hashline-engine/format.d.ts.map +1 -0
  364. package/dist/core/tools/hashline-engine/format.js +178 -0
  365. package/dist/core/tools/hashline-engine/format.js.map +1 -0
  366. package/dist/core/tools/hashline-engine/fs.d.ts +81 -0
  367. package/dist/core/tools/hashline-engine/fs.d.ts.map +1 -0
  368. package/dist/core/tools/hashline-engine/fs.js +143 -0
  369. package/dist/core/tools/hashline-engine/fs.js.map +1 -0
  370. package/dist/core/tools/hashline-engine/index.d.ts +18 -0
  371. package/dist/core/tools/hashline-engine/index.d.ts.map +1 -0
  372. package/dist/core/tools/hashline-engine/index.js +20 -0
  373. package/dist/core/tools/hashline-engine/index.js.map +1 -0
  374. package/dist/core/tools/hashline-engine/input.d.ts +101 -0
  375. package/dist/core/tools/hashline-engine/input.d.ts.map +1 -0
  376. package/dist/core/tools/hashline-engine/input.js +398 -0
  377. package/dist/core/tools/hashline-engine/input.js.map +1 -0
  378. package/dist/core/tools/hashline-engine/messages.d.ts +99 -0
  379. package/dist/core/tools/hashline-engine/messages.d.ts.map +1 -0
  380. package/dist/core/tools/hashline-engine/messages.js +144 -0
  381. package/dist/core/tools/hashline-engine/messages.js.map +1 -0
  382. package/dist/core/tools/hashline-engine/mismatch.d.ts +45 -0
  383. package/dist/core/tools/hashline-engine/mismatch.d.ts.map +1 -0
  384. package/dist/core/tools/hashline-engine/mismatch.js +90 -0
  385. package/dist/core/tools/hashline-engine/mismatch.js.map +1 -0
  386. package/dist/core/tools/hashline-engine/normalize.d.ts +21 -0
  387. package/dist/core/tools/hashline-engine/normalize.d.ts.map +1 -0
  388. package/dist/core/tools/hashline-engine/normalize.js +33 -0
  389. package/dist/core/tools/hashline-engine/normalize.js.map +1 -0
  390. package/dist/core/tools/hashline-engine/parser.d.ts +24 -0
  391. package/dist/core/tools/hashline-engine/parser.d.ts.map +1 -0
  392. package/dist/core/tools/hashline-engine/parser.js +381 -0
  393. package/dist/core/tools/hashline-engine/parser.js.map +1 -0
  394. package/dist/core/tools/hashline-engine/patcher.d.ts +118 -0
  395. package/dist/core/tools/hashline-engine/patcher.d.ts.map +1 -0
  396. package/dist/core/tools/hashline-engine/patcher.js +341 -0
  397. package/dist/core/tools/hashline-engine/patcher.js.map +1 -0
  398. package/dist/core/tools/hashline-engine/prefixes.d.ts +43 -0
  399. package/dist/core/tools/hashline-engine/prefixes.d.ts.map +1 -0
  400. package/dist/core/tools/hashline-engine/prefixes.js +135 -0
  401. package/dist/core/tools/hashline-engine/prefixes.js.map +1 -0
  402. package/dist/core/tools/hashline-engine/recovery.d.ts +41 -0
  403. package/dist/core/tools/hashline-engine/recovery.d.ts.map +1 -0
  404. package/dist/core/tools/hashline-engine/recovery.js +168 -0
  405. package/dist/core/tools/hashline-engine/recovery.js.map +1 -0
  406. package/dist/core/tools/hashline-engine/snapshots.d.ts +65 -0
  407. package/dist/core/tools/hashline-engine/snapshots.d.ts.map +1 -0
  408. package/dist/core/tools/hashline-engine/snapshots.js +108 -0
  409. package/dist/core/tools/hashline-engine/snapshots.js.map +1 -0
  410. package/dist/core/tools/hashline-engine/stream.d.ts +3 -0
  411. package/dist/core/tools/hashline-engine/stream.d.ts.map +1 -0
  412. package/dist/core/tools/hashline-engine/stream.js +111 -0
  413. package/dist/core/tools/hashline-engine/stream.js.map +1 -0
  414. package/dist/core/tools/hashline-engine/tokenizer.d.ts +69 -0
  415. package/dist/core/tools/hashline-engine/tokenizer.d.ts.map +1 -0
  416. package/dist/core/tools/hashline-engine/tokenizer.js +430 -0
  417. package/dist/core/tools/hashline-engine/tokenizer.js.map +1 -0
  418. package/dist/core/tools/hashline-engine/types.d.ts +166 -0
  419. package/dist/core/tools/hashline-engine/types.d.ts.map +1 -0
  420. package/dist/core/tools/hashline-engine/types.js +9 -0
  421. package/dist/core/tools/hashline-engine/types.js.map +1 -0
  422. package/dist/core/tools/hashline.d.ts +29 -0
  423. package/dist/core/tools/hashline.d.ts.map +1 -0
  424. package/dist/core/tools/hashline.js +110 -0
  425. package/dist/core/tools/hashline.js.map +1 -0
  426. package/dist/core/tools/index.d.ts +6 -4
  427. package/dist/core/tools/index.d.ts.map +1 -1
  428. package/dist/core/tools/index.js +52 -35
  429. package/dist/core/tools/index.js.map +1 -1
  430. package/dist/core/tools/notebook.d.ts +38 -0
  431. package/dist/core/tools/notebook.d.ts.map +1 -0
  432. package/dist/core/tools/notebook.js +125 -0
  433. package/dist/core/tools/notebook.js.map +1 -0
  434. package/dist/core/tools/read-document-extract.d.ts +9 -0
  435. package/dist/core/tools/read-document-extract.d.ts.map +1 -0
  436. package/dist/core/tools/read-document-extract.js +212 -0
  437. package/dist/core/tools/read-document-extract.js.map +1 -0
  438. package/dist/core/tools/read-selectors.d.ts +24 -0
  439. package/dist/core/tools/read-selectors.d.ts.map +1 -0
  440. package/dist/core/tools/read-selectors.js +277 -0
  441. package/dist/core/tools/read-selectors.js.map +1 -0
  442. package/dist/core/tools/read-url.d.ts +37 -0
  443. package/dist/core/tools/read-url.d.ts.map +1 -0
  444. package/dist/core/tools/read-url.js +39 -0
  445. package/dist/core/tools/read-url.js.map +1 -0
  446. package/dist/core/tools/read.d.ts +11 -11
  447. package/dist/core/tools/read.d.ts.map +1 -1
  448. package/dist/core/tools/read.js +224 -94
  449. package/dist/core/tools/read.js.map +1 -1
  450. package/dist/core/tools/resource-selectors.d.ts +44 -0
  451. package/dist/core/tools/resource-selectors.d.ts.map +1 -0
  452. package/dist/core/tools/resource-selectors.js +808 -0
  453. package/dist/core/tools/resource-selectors.js.map +1 -0
  454. package/dist/core/tools/search-details.d.ts +26 -0
  455. package/dist/core/tools/search-details.d.ts.map +1 -0
  456. package/dist/core/tools/search-details.js +24 -0
  457. package/dist/core/tools/search-details.js.map +1 -0
  458. package/dist/core/tools/search-line-ranges.d.ts +11 -0
  459. package/dist/core/tools/search-line-ranges.d.ts.map +1 -0
  460. package/dist/core/tools/search-line-ranges.js +65 -0
  461. package/dist/core/tools/search-line-ranges.js.map +1 -0
  462. package/dist/core/tools/search-native.d.ts +97 -0
  463. package/dist/core/tools/search-native.d.ts.map +1 -0
  464. package/dist/core/tools/search-native.js +27 -0
  465. package/dist/core/tools/search-native.js.map +1 -0
  466. package/dist/core/tools/search.d.ts +24 -0
  467. package/dist/core/tools/search.d.ts.map +1 -0
  468. package/dist/core/tools/search.js +573 -0
  469. package/dist/core/tools/search.js.map +1 -0
  470. package/dist/core/tools/truncate.d.ts +4 -4
  471. package/dist/core/tools/truncate.d.ts.map +1 -1
  472. package/dist/core/tools/truncate.js +3 -3
  473. package/dist/core/tools/truncate.js.map +1 -1
  474. package/dist/core/tools/url-ip-guards.d.ts +4 -0
  475. package/dist/core/tools/url-ip-guards.d.ts.map +1 -0
  476. package/dist/core/tools/url-ip-guards.js +126 -0
  477. package/dist/core/tools/url-ip-guards.js.map +1 -0
  478. package/dist/core/tools/write.d.ts +12 -2
  479. package/dist/core/tools/write.d.ts.map +1 -1
  480. package/dist/core/tools/write.js +166 -14
  481. package/dist/core/tools/write.js.map +1 -1
  482. package/dist/core/trust-manager.d.ts.map +1 -1
  483. package/dist/core/trust-manager.js +2 -3
  484. package/dist/core/trust-manager.js.map +1 -1
  485. package/dist/index-extensions.d.ts +2 -2
  486. package/dist/index-extensions.d.ts.map +1 -1
  487. package/dist/index-extensions.js +1 -1
  488. package/dist/index-extensions.js.map +1 -1
  489. package/dist/index.d.ts +3 -3
  490. package/dist/index.d.ts.map +1 -1
  491. package/dist/index.js +3 -3
  492. package/dist/index.js.map +1 -1
  493. package/dist/modes/interactive/components/chat-session-host-runtime.d.ts +1 -0
  494. package/dist/modes/interactive/components/chat-session-host-runtime.d.ts.map +1 -1
  495. package/dist/modes/interactive/components/chat-session-host-runtime.js +12 -0
  496. package/dist/modes/interactive/components/chat-session-host-runtime.js.map +1 -1
  497. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.d.ts +4 -0
  498. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.d.ts.map +1 -0
  499. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.js +131 -0
  500. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.js.map +1 -0
  501. package/dist/modes/interactive/components/chat-session-host.d.ts +2 -0
  502. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  503. package/dist/modes/interactive/components/chat-session-host.js +7 -1
  504. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  505. package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
  506. package/dist/modes/interactive/components/chat-transcript.js +15 -4
  507. package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
  508. package/dist/modes/interactive/components/custom-editor.d.ts +1 -0
  509. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  510. package/dist/modes/interactive/components/custom-editor.js +9 -2
  511. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  512. package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
  513. package/dist/modes/interactive/components/settings-selector-handlers.js +3 -0
  514. package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
  515. package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
  516. package/dist/modes/interactive/components/settings-selector-items.js +7 -0
  517. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  518. package/dist/modes/interactive/components/settings-selector-types.d.ts +2 -0
  519. package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
  520. package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
  521. package/dist/modes/interactive/components/tool-execution.d.ts +3 -0
  522. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  523. package/dist/modes/interactive/components/tool-execution.js +26 -0
  524. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  525. package/dist/modes/interactive/components/tree-selector-content.d.ts.map +1 -1
  526. package/dist/modes/interactive/components/tree-selector-content.js +0 -5
  527. package/dist/modes/interactive/components/tree-selector-content.js.map +1 -1
  528. package/dist/modes/interactive/interactive-auth-login.d.ts.map +1 -1
  529. package/dist/modes/interactive/interactive-auth-login.js +1 -0
  530. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  531. package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  532. package/dist/modes/interactive/interactive-autocomplete.js +80 -2
  533. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  534. package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
  535. package/dist/modes/interactive/interactive-hotkeys-debug.js +3 -0
  536. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  537. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  538. package/dist/modes/interactive/interactive-input-handling.js +51 -0
  539. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  540. package/dist/modes/interactive/interactive-mode-base.d.ts +5 -0
  541. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  542. package/dist/modes/interactive/interactive-mode-base.js +5 -0
  543. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  544. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  545. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  546. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  547. package/dist/modes/interactive/interactive-mode-surface.d.ts +12 -0
  548. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  549. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  550. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  551. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  552. package/dist/modes/interactive/interactive-mode.js +1 -0
  553. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  554. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  555. package/dist/modes/interactive/interactive-model-routing.js +4 -1
  556. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  557. package/dist/modes/interactive/interactive-onboarding.d.ts +11 -0
  558. package/dist/modes/interactive/interactive-onboarding.d.ts.map +1 -0
  559. package/dist/modes/interactive/interactive-onboarding.js +220 -0
  560. package/dist/modes/interactive/interactive-onboarding.js.map +1 -0
  561. package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
  562. package/dist/modes/interactive/interactive-selectors.js +4 -0
  563. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  564. package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
  565. package/dist/modes/interactive/interactive-session-routing.js +6 -0
  566. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  567. package/dist/modes/interactive/interactive-slash-commands.d.ts.map +1 -1
  568. package/dist/modes/interactive/interactive-slash-commands.js +9 -4
  569. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  570. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  571. package/dist/modes/interactive/interactive-startup.js +28 -0
  572. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  573. package/dist/utils/child-process.d.ts.map +1 -1
  574. package/dist/utils/child-process.js +21 -1
  575. package/dist/utils/child-process.js.map +1 -1
  576. package/dist/utils/markit.d.ts +8 -0
  577. package/dist/utils/markit.d.ts.map +1 -0
  578. package/dist/utils/markit.js +53 -0
  579. package/dist/utils/markit.js.map +1 -0
  580. package/dist/utils/paths.d.ts +2 -1
  581. package/dist/utils/paths.d.ts.map +1 -1
  582. package/dist/utils/paths.js +14 -1
  583. package/dist/utils/paths.js.map +1 -1
  584. package/docs/compaction.md +18 -1
  585. package/docs/containerization.md +1 -1
  586. package/docs/docs.json +1 -0
  587. package/docs/extensions.md +25 -36
  588. package/docs/models.md +1 -1
  589. package/docs/providers.md +2 -1
  590. package/docs/quickstart.md +11 -6
  591. package/docs/sdk.md +5 -5
  592. package/docs/session-format.md +6 -0
  593. package/docs/sessions.md +6 -0
  594. package/docs/settings.md +7 -0
  595. package/docs/subagents.md +3 -2
  596. package/docs/tools.md +49 -0
  597. package/docs/usage.md +3 -3
  598. package/docs/workflows.md +112 -8
  599. package/examples/extensions/subagent/README.md +5 -5
  600. package/examples/extensions/subagent/agents/planner.md +1 -1
  601. package/examples/extensions/subagent/agents/reviewer.md +1 -1
  602. package/examples/extensions/subagent/agents/scout.md +2 -2
  603. package/examples/extensions/subagent/display.ts +3 -3
  604. package/examples/sdk/05-tools.ts +3 -3
  605. package/examples/sdk/README.md +1 -1
  606. package/package.json +5 -3
@@ -8,7 +8,7 @@
8
8
  * Project-local:
9
9
  * <projectRoot>/.atomic/extensions/workflow/config.json
10
10
  * User-global:
11
- * <homeDir>/.atomic/agent/extensions/workflow/config.json
11
+ * <agentDir>/extensions/workflow/config.json
12
12
  * Invalid JSON or invalid shape → CONFIG_INVALID diagnostic (not silent success).
13
13
  * Missing file → silently skipped (not an error).
14
14
  *
@@ -17,8 +17,7 @@
17
17
  */
18
18
 
19
19
  import { join, isAbsolute } from "node:path";
20
- import { homedir } from "node:os";
21
- import { CONFIG_DIR_NAME, CONFIG_DIR_NAMES, getProjectConfigPaths } from "@bastani/atomic";
20
+ import { CONFIG_DIR_NAME, CONFIG_DIR_NAMES, getAgentDir, getAgentDirs, getProjectConfigPaths } from "@bastani/atomic";
22
21
  import type { WorkflowLifecycleNoticeKind } from "./lifecycle-notifications.js";
23
22
  import { loadConfigFile } from "./config-file-loader.js";
24
23
 
@@ -82,7 +81,7 @@ export interface ConfigLoadResult {
82
81
  */
83
82
  readonly config: WorkflowExtensionConfig | null;
84
83
  /**
85
- * Pre-merge global config (from <homeDir>/.atomic/agent/extensions/workflow/config.json).
84
+ * Pre-merge global config (from <agentDir>/extensions/workflow/config.json).
86
85
  * null when the global file is absent or invalid. Absent on results from callers
87
86
  * that constructed ConfigLoadResult before this field was added.
88
87
  */
@@ -108,10 +107,15 @@ export interface LoadWorkflowConfigOpts {
108
107
  */
109
108
  readonly projectRoot?: string;
110
109
  /**
111
- * User home directory. Defaults to os.homedir().
112
- * Global config is resolved relative to this path.
110
+ * User home directory. When set, preserves legacy test/compat resolution
111
+ * relative to <homeDir>/.atomic/agent and <homeDir>/.pi/agent.
113
112
  */
114
113
  readonly homeDir?: string;
114
+ /**
115
+ * User agent config directories in precedence order. Defaults to Atomic's
116
+ * configured agent directories, honoring ATOMIC_CODING_AGENT_DIR.
117
+ */
118
+ readonly agentDirs?: readonly string[];
115
119
  }
116
120
 
117
121
  // ---------------------------------------------------------------------------
@@ -242,10 +246,15 @@ export interface ScopedDiscoveryConfigOpts {
242
246
  */
243
247
  readonly projectRoot: string;
244
248
  /**
245
- * User home directory. Relative paths in globalConfig.workflows are
246
- * resolved relative to <homeDir>/.atomic/agent.
249
+ * User home directory. When set, relative paths in globalConfig.workflows
250
+ * resolve relative to <homeDir>/.atomic/agent.
251
+ */
252
+ readonly homeDir?: string;
253
+ /**
254
+ * User agent config directory. Defaults to Atomic's configured agent dir,
255
+ * honoring ATOMIC_CODING_AGENT_DIR.
247
256
  */
248
- readonly homeDir: string;
257
+ readonly agentDir?: string;
249
258
  }
250
259
 
251
260
  export interface ScopedDiscoveryConfig {
@@ -275,12 +284,21 @@ function resolveWorkflowPaths(
275
284
  );
276
285
  }
277
286
 
287
+ function workflowAgentDirs(opts: Pick<LoadWorkflowConfigOpts, "agentDirs" | "homeDir">): readonly string[] {
288
+ if (opts.agentDirs !== undefined) return opts.agentDirs;
289
+ if (opts.homeDir !== undefined) {
290
+ const homeDir = opts.homeDir;
291
+ return CONFIG_DIR_NAMES.map((name) => join(homeDir, name, "agent"));
292
+ }
293
+ return getAgentDirs();
294
+ }
295
+
278
296
  /**
279
297
  * Build a scope-aware DiscoveryConfig from the pre-merge global and project configs.
280
298
  *
281
299
  * Scope rules:
282
300
  * - globalConfig.workflows entries → DiscoveryConfig.globalWorkflows
283
- * Relative paths are resolved under <homeDir>/.atomic/agent.
301
+ * Relative paths are resolved under the configured Atomic agent dir.
284
302
  * - projectConfig.workflows entries → DiscoveryConfig.projectWorkflows
285
303
  * Relative paths are resolved under projectRoot.
286
304
  * - When both configs define the same workflow key, the project entry wins
@@ -294,7 +312,8 @@ export function toScopedDiscoveryConfig(
294
312
  projectConfig: WorkflowExtensionConfig | null,
295
313
  opts: ScopedDiscoveryConfigOpts,
296
314
  ): ScopedDiscoveryConfig {
297
- const globalBase = join(opts.homeDir, CONFIG_DIR_NAME, "agent");
315
+ const globalBase = opts.agentDir
316
+ ?? (opts.homeDir === undefined ? getAgentDir() : join(opts.homeDir, CONFIG_DIR_NAME, "agent"));
298
317
  const projectBase = opts.projectRoot;
299
318
 
300
319
  const result: ScopedDiscoveryConfig = {};
@@ -328,7 +347,7 @@ export function toScopedDiscoveryConfig(
328
347
  *
329
348
  * Candidate paths (in resolution order):
330
349
  * Global (lowest priority):
331
- * <homeDir>/.atomic/agent/extensions/workflow/config.json
350
+ * <agentDir>/extensions/workflow/config.json
332
351
  * Project-local (highest priority, first existing wins):
333
352
  * <projectRoot>/.atomic/extensions/workflow/config.json
334
353
  * Merge: project-local overrides global. Key-level merge for `workflows` map.
@@ -338,12 +357,13 @@ export async function loadWorkflowConfig(
338
357
  opts: LoadWorkflowConfigOpts = {},
339
358
  ): Promise<ConfigLoadResult> {
340
359
  const projectRoot = opts.projectRoot ?? process.cwd();
341
- const home = opts.homeDir ?? homedir();
342
360
 
343
361
  const diagnostics: ConfigDiagnostic[] = [];
344
362
 
345
- // Global config paths (primary Atomic first, then legacy pi)
346
- const globalCandidates = CONFIG_DIR_NAMES.map((name) => join(home, name, "agent", "extensions", "workflow", "config.json"));
363
+ // Global config paths (primary Atomic first, then legacy pi/defaults).
364
+ const globalCandidates = workflowAgentDirs(opts).map((agentDir) =>
365
+ join(agentDir, "extensions", "workflow", "config.json")
366
+ );
347
367
 
348
368
  // Project-local config paths (primary Atomic first, then legacy pi)
349
369
  const projectCandidates: string[] = getProjectConfigPaths(projectRoot, "extensions", "workflow", "config.json");
@@ -11,17 +11,17 @@
11
11
  * 1. settings-project — paths listed in config.projectWorkflows
12
12
  * 2. project-local — {cwd}/.atomic/workflows/*.{ts,js,mjs,cjs}
13
13
  * 3. settings-global — paths listed in config.globalWorkflows
14
- * 4. user-global — {homeDir}/.atomic/agent/workflows/*.{ts,js,mjs,cjs}
14
+ * 4. user-global — {agentDir}/workflows/*.{ts,js,mjs,cjs}
15
15
  * 5. package — workflow files supplied by Atomic/pi packages
16
16
  * 6. bundled — shipped workflows (skipped when includeBundled=false)
17
17
  *
18
18
  * Usage:
19
19
  * // Full discovery (all sources):
20
- * const result = await discoverWorkflows({ cwd: process.cwd(), homeDir: os.homedir() });
20
+ * const result = await discoverWorkflows({ cwd: process.cwd() });
21
21
  */
22
22
 
23
23
  import { join } from "node:path";
24
- import { CONFIG_DIR_NAMES, getProjectConfigPaths } from "@bastani/atomic";
24
+ import { CONFIG_DIR_NAMES, getAgentDirs, getProjectConfigPaths } from "@bastani/atomic";
25
25
  import type { WorkflowDefinition } from "../shared/types.js";
26
26
  import { createRegistry } from "../workflows/registry.js";
27
27
  import type { WorkflowRegistry } from "../workflows/registry.js";
@@ -38,7 +38,7 @@ import { loadFromDir, loadFromPaths, type WorkflowModuleCandidateRecord } from "
38
38
  *
39
39
  * bundled — shipped with the workflows package
40
40
  * project-local — found in {cwd}/.atomic/workflows/
41
- * user-global — found in {homeDir}/.atomic/agent/workflows/
41
+ * user-global — found in {agentDir}/workflows/
42
42
  * settings-project — listed in DiscoveryConfig.projectWorkflows
43
43
  * settings-global — listed in DiscoveryConfig.globalWorkflows
44
44
  * package — supplied by Atomic/pi package workflow resources
@@ -121,8 +121,10 @@ export interface DiscoveryConfig {
121
121
  export interface DiscoveryOptions {
122
122
  /** Working directory; used as root for project-local discovery. Default: process.cwd() */
123
123
  cwd: string;
124
- /** User's home directory; used as root for user-global discovery. Default: os.homedir() */
124
+ /** User's home directory; when set, preserves legacy test/compat user-global discovery roots. */
125
125
  homeDir: string;
126
+ /** User agent config directories in precedence order. Defaults to Atomic's configured agent directories. */
127
+ agentDirs?: readonly string[];
126
128
  /** Optional extra paths from project/global config. */
127
129
  config?: DiscoveryConfig;
128
130
  /** Workflow files supplied by installed Atomic/pi packages. */
@@ -145,6 +147,15 @@ export interface DiscoveryResult {
145
147
  // Internal helpers
146
148
  // ---------------------------------------------------------------------------
147
149
 
150
+ function workflowAgentDirs(options: Partial<DiscoveryOptions> | undefined): readonly string[] {
151
+ if (options?.agentDirs !== undefined) return options.agentDirs;
152
+ if (options?.homeDir !== undefined) {
153
+ const homeDir = options.homeDir;
154
+ return CONFIG_DIR_NAMES.map((name) => join(homeDir, name, "agent"));
155
+ }
156
+ return getAgentDirs();
157
+ }
158
+
148
159
  /**
149
160
  * Validate DiscoveryConfig shape.
150
161
  * Returns null when valid, or a description of the problem.
@@ -273,7 +284,7 @@ function applyBatchShapeOnly(
273
284
  * 1. settings-project — config.projectWorkflows paths
274
285
  * 2. project-local — {cwd}/.atomic/workflows/*.{ts,js,mjs,cjs}
275
286
  * 3. settings-global — config.globalWorkflows paths
276
- * 4. user-global — {homeDir}/.atomic/agent/workflows/*.{ts,js,mjs,cjs}
287
+ * 4. user-global — {agentDir}/workflows/*.{ts,js,mjs,cjs}
277
288
  * 5. package — package-supplied workflow files
278
289
  * 6. bundled — shipped workflows (omitted when includeBundled=false)
279
290
  */
@@ -282,6 +293,7 @@ export async function discoverWorkflows(
282
293
  ): Promise<DiscoveryResult> {
283
294
  const cwd = options?.cwd ?? process.cwd();
284
295
  const homeDir = options?.homeDir ?? (await defaultHomeDir());
296
+ const agentDirs = workflowAgentDirs(options);
285
297
  const config = options?.config;
286
298
  const packageWorkflowPaths = options?.packageWorkflowPaths;
287
299
  const includeBundled = options?.includeBundled !== false;
@@ -332,8 +344,8 @@ export async function discoverWorkflows(
332
344
  }
333
345
  }
334
346
 
335
- // 4. user-global — canonical Atomic path plus legacy pi path
336
- for (const dir of CONFIG_DIR_NAMES.map((name) => join(homeDir, name, "agent", "workflows")).reverse()) {
347
+ // 4. user-global — configured Atomic agent dir plus legacy/defaults when applicable.
348
+ for (const dir of agentDirs.map((agentDir) => join(agentDir, "workflows")).reverse()) {
337
349
  const candidates = await loadFromDir(dir, "user-global", diagnostics);
338
350
  registry = await applyBatch(candidates, registry, sources, diagnostics);
339
351
  }
@@ -1,5 +1,4 @@
1
- import { killRun } from "../runs/background/status.js";
2
- import { cancellationRegistry } from "../runs/background/cancellation-registry.js";
1
+ import { quitRun } from "../runs/background/quit.js";
3
2
  import { store } from "../shared/store.js";
4
3
  import { subscribeIntercomControl } from "../intercom/result-intercom.js";
5
4
  import { buildIntercomCallbacks } from "../intercom/intercom-routing.js";
@@ -7,9 +6,8 @@ import { installStoreWidget, installToolExecutionHooks } from "../tui/store-widg
7
6
  import { buildGraphOverlayAdapter } from "../tui/overlay-adapter.js";
8
7
  import type { GraphOverlayPort } from "../tui/overlay-adapter.js";
9
8
  import { registerInlineFormRenderer } from "../tui/inline-form-overlay.js";
10
- import { registerChatSurfaceRenderer, emitChatSurface } from "../tui/chat-surface-message.js";
9
+ import { registerChatSurfaceRenderer } from "../tui/chat-surface-message.js";
11
10
  import { deriveGraphTheme } from "../tui/graph-theme.js";
12
- import type { WorkflowPersistencePort } from "../shared/types.js";
13
11
  import { renderRunBanner, renderRunSummary, type RunEndPayload, type RunStartPayload } from "./renderers.js";
14
12
  import { buildRuntimeAdapters } from "./wiring.js";
15
13
  import type { ExtensionAPI, PiCommandContext } from "./public-types.js";
@@ -36,15 +34,11 @@ function registerWorkflowMessageRenderers(pi: ExtensionAPI): void {
36
34
 
37
35
  function buildWorkflowOverlay(
38
36
  pi: ExtensionAPI,
39
- getPersistence: () => WorkflowPersistencePort | undefined,
40
37
  ): GraphOverlayPort {
41
38
  return buildGraphOverlayAdapter(pi, store, {
42
- onKillRun: (runId) => {
43
- const run = store.runs().find((r) => r.id === runId);
44
- const result = killRun(runId, { cancellation: cancellationRegistry, persistence: getPersistence() });
45
- if (run && result.ok) {
46
- emitChatSurface(pi, { kind: "killed", run, previousStatus: result.previousStatus });
47
- }
39
+ onQuitRun: (runId) => {
40
+ quitRun(runId, { store });
41
+ pi.ui?.notify?.(`Workflow quit; resume with /workflow resume.`, "info");
48
42
  },
49
43
  });
50
44
  }
@@ -83,7 +77,7 @@ function registerIntercomControl(
83
77
  function factory(pi: ExtensionAPI): void {
84
78
  const adapters = buildRuntimeAdapters(pi);
85
79
  const runtimeState = createWorkflowExtensionRuntimeState(pi, adapters);
86
- const overlay = buildWorkflowOverlay(pi, () => runtimeState.persistenceRef.current);
80
+ const overlay = buildWorkflowOverlay(pi);
87
81
  const workflowCommands = new Map<string, WorkflowCommandHandler>();
88
82
  const storeWidgetRef: { current: (() => void) | null } = { current: null };
89
83
  const intercomControlRef: { current: (() => void) | null } = { current: null };
@@ -1,4 +1,5 @@
1
1
  import { killAllRuns } from "../runs/background/status.js";
2
+ import { quitAllRuns } from "../runs/background/quit.js";
2
3
  import { cancellationRegistry } from "../runs/background/cancellation-registry.js";
3
4
  import { stageControlRegistry } from "../runs/foreground/stage-control-registry.js";
4
5
  import { store } from "../shared/store.js";
@@ -99,7 +100,10 @@ export function registerWorkflowLifecycleHandlers(
99
100
  deps.intercomControlRef.current?.();
100
101
  deps.intercomControlRef.current = null;
101
102
  if (reason === "quit") {
102
- killAllRuns({ store, cancellation: cancellationRegistry, persistence: runtimeState.persistenceRef.current });
103
+ // CLI/orchestrator quit is a resumable process boundary, not explicit
104
+ // `/workflow kill`. Durable-progress workflows stay available through
105
+ // `/workflow resume`; stage handles are disposed after being paused.
106
+ quitAllRuns({ store, stageControlRegistry });
103
107
  stageControlRegistry.clear();
104
108
  }
105
109
  deps.storeWidgetRef.current?.();
@@ -141,6 +141,9 @@ export function createWorkflowExtensionRuntimeState(
141
141
  dispatch(args, options) { return runtimeRef.current.dispatch(args, options); },
142
142
  runDirect(args, options) { return runtimeRef.current.runDirect(args, options); },
143
143
  resumeFailedRun(sourceRunId, stageId, options) { return runtimeRef.current.resumeFailedRun(sourceRunId, stageId, options); },
144
+ resumeDurableWorkflow(workflowIdOrPrefix, options) { return runtimeRef.current.resumeDurableWorkflow(workflowIdOrPrefix, options); },
145
+ listDurableResumable(sessionDir) { return runtimeRef.current.listDurableResumable(sessionDir); },
146
+ prepareDurableResumable(workflowIdOrPrefix, sessionDir) { return runtimeRef.current.prepareDurableResumable(workflowIdOrPrefix, sessionDir); },
144
147
  };
145
148
 
146
149
  function workflowModelCatalogFromContext(ctx?: PiModelContext): WorkflowModelCatalogPort | undefined {
@@ -201,11 +204,10 @@ export function createWorkflowExtensionRuntimeState(
201
204
  }
202
205
  const configResult = await loadWorkflowConfig();
203
206
  configLoadRef.current = configResult;
204
- const { homedir } = await import("node:os");
205
207
  const hasGlobal = configResult.globalConfig != null;
206
208
  const hasProject = configResult.projectConfig != null;
207
209
  const discoveryConfig = hasGlobal || hasProject
208
- ? toScopedDiscoveryConfig(configResult.globalConfig ?? null, configResult.projectConfig ?? null, { projectRoot: process.cwd(), homeDir: homedir() })
210
+ ? toScopedDiscoveryConfig(configResult.globalConfig ?? null, configResult.projectConfig ?? null, { projectRoot: process.cwd() })
209
211
  : undefined;
210
212
  const result = await discoverWorkflows({ config: discoveryConfig, packageWorkflowPaths: await loadPackageWorkflowPaths() });
211
213
  discoveryRef.current = result;
@@ -43,6 +43,10 @@ import { runDetached } from "../runs/background/runner.js";
43
43
  import type { JobTracker } from "../runs/background/job-tracker.js";
44
44
  import { appendRunEnd } from "../shared/persistence-session-entries.js";
45
45
  import { classifyWorkflowFailure } from "../shared/workflow-failures.js";
46
+ import { resumeDurableWorkflow as resumeDurableWorkflowAdapter, prepareRuntimeDurableResumable, isBackendTerminal, type ResumeDurableDeps, type ResumeDurableResult } from "../durable/resume-runtime.js";
47
+ import { getDurableBackend, initializeDbosDurableBackendFromEnv } from "../durable/factory.js";
48
+ import { scanResumableWorkflows } from "../durable/resume-catalog.js";
49
+ import type { ResumableWorkflowEntry } from "../durable/types.js";
46
50
  import { directMode, directModelRequests, directOptions, directProgressTotal } from "./runtime-direct.js";
47
51
 
48
52
  // ---------------------------------------------------------------------------
@@ -87,11 +91,9 @@ export interface ExtensionRuntimeOpts {
87
91
  /** Resolve the host's non-default session directory for workflow stage transcripts. */
88
92
  resolveDefaultStageSessionDir?: () => string | undefined;
89
93
  }
90
-
91
94
  // ---------------------------------------------------------------------------
92
95
  // Public interface
93
96
  // ---------------------------------------------------------------------------
94
-
95
97
  export type ResumeFailedRunResult =
96
98
  | { ok: true; runId: string; sourceRunId: string; resumeFromStageId: string; message: string }
97
99
  | { ok: false; reason: "run_not_found" | "not_resumable" | "workflow_not_found" | "insufficient_state"; message: string };
@@ -114,12 +116,21 @@ export interface ExtensionRuntime {
114
116
 
115
117
  /** Start a linked continuation for a failed resumable named workflow run. */
116
118
  resumeFailedRun(sourceRunId: string, stageId?: string, options?: RuntimeDispatchOptions): ResumeFailedRunResult;
117
- }
118
119
 
120
+ /**
121
+ * Resume a durable workflow by top-level workflow id when no live run exists.
122
+ * Re-dispatches the workflow with the cached inputs and original workflow id
123
+ * so durable checkpoints replay (skipping completed side effects).
124
+ *
125
+ * cross-ref: issue #1498 — cross-session /workflow resume selector.
126
+ */
127
+ resumeDurableWorkflow(workflowIdOrPrefix: string, options?: RuntimeDispatchOptions): import("../durable/resume-runtime.js").ResumeDurableResult;
128
+ listDurableResumable(sessionDir?: string): readonly import("../durable/types.js").ResumableWorkflowEntry[];
129
+ prepareDurableResumable(workflowIdOrPrefix?: string, sessionDir?: string): Promise<readonly import("../durable/types.js").ResumableWorkflowEntry[]>;
130
+ }
119
131
  export interface RuntimeDispatchOptions {
120
132
  readonly policy?: WorkflowExecutionPolicy;
121
133
  }
122
-
123
134
  // ---------------------------------------------------------------------------
124
135
  // Factory
125
136
  // ---------------------------------------------------------------------------
@@ -150,6 +161,9 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
150
161
  const jobs = opts.jobs;
151
162
  const runtimeCwd = opts.cwd ?? process.cwd();
152
163
  const resolveDefaultStageSessionDir = opts.resolveDefaultStageSessionDir;
164
+ const dbosReady = initializeDbosDurableBackendFromEnv().catch((err) => process.emitWarning(`Atomic workflow DBOS durability unavailable; using file-backed durability: ${err instanceof Error ? err.message : String(err)}`));
165
+ const ensureDbosReady = async (): Promise<void> => { await dbosReady; };
166
+ let preparedDurableCatalog: readonly ResumableWorkflowEntry[] = [];
153
167
 
154
168
  function runOptions(args: WorkflowToolArgs, policy?: WorkflowExecutionPolicy): RunOpts {
155
169
  const argConcurrency =
@@ -182,14 +196,12 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
182
196
  cwd: runtimeCwd,
183
197
  };
184
198
  }
185
-
186
199
  function explicitIntercomDelivery(args: WorkflowToolArgs): WorkflowIntercomDelivery | undefined {
187
200
  if (args.intercom?.enabled === false) return "off";
188
201
  if (args.intercom?.delivery !== undefined) return args.intercom.delivery;
189
202
  if (args.intercom?.enabled === true) return "control-and-result";
190
203
  return undefined;
191
204
  }
192
-
193
205
  function effectiveIntercomDelivery(args: WorkflowToolArgs, mode: WorkflowDetails["mode"]): WorkflowIntercomDelivery {
194
206
  const explicit = explicitIntercomDelivery(args);
195
207
  if (explicit !== undefined) return explicit;
@@ -202,7 +214,6 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
202
214
  }
203
215
  return "off";
204
216
  }
205
-
206
217
  function intercomParentSession(args: WorkflowToolArgs): string | undefined {
207
218
  if (args.intercom?.parentSession !== undefined) return args.intercom.parentSession;
208
219
  if (typeof intercom?.parentSession === "function") return intercom.parentSession();
@@ -371,6 +382,7 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
371
382
  }
372
383
 
373
384
  async function runDirectAsync(args: WorkflowToolArgs, policy?: WorkflowExecutionPolicy): Promise<WorkflowDetails> {
385
+ await ensureDbosReady();
374
386
  const runId = crypto.randomUUID();
375
387
  const mode = directMode(args);
376
388
  const delivery = effectiveIntercomDelivery(args, mode);
@@ -423,7 +435,8 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
423
435
  return registry;
424
436
  },
425
437
 
426
- dispatch(args: WorkflowToolArgs, options?: RuntimeDispatchOptions): Promise<WorkflowToolResult> {
438
+ async dispatch(args: WorkflowToolArgs, options?: RuntimeDispatchOptions): Promise<WorkflowToolResult> {
439
+ await ensureDbosReady();
427
440
  const defaultSessionDir = resolveDefaultStageSessionDir?.();
428
441
  return dispatch(args, {
429
442
  registry,
@@ -441,7 +454,8 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
441
454
  });
442
455
  },
443
456
 
444
- runDirect(args: WorkflowToolArgs, options?: RuntimeDispatchOptions): Promise<WorkflowDetails> {
457
+ async runDirect(args: WorkflowToolArgs, options?: RuntimeDispatchOptions): Promise<WorkflowDetails> {
458
+ await ensureDbosReady();
445
459
  const policy = options?.policy ?? INTERACTIVE_WORKFLOW_POLICY;
446
460
  if (args.async === true && policy.awaitTerminalRun !== true) {
447
461
  return runDirectAsync(args, policy);
@@ -457,5 +471,30 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
457
471
  },
458
472
 
459
473
  resumeFailedRun,
474
+
475
+ resumeDurableWorkflow(workflowIdOrPrefix: string, options?: RuntimeDispatchOptions): ResumeDurableResult {
476
+ const adapterDeps: ResumeDurableDeps = {
477
+ registry,
478
+ baseRunOpts: runOptions({ workflow: "", inputs: {} }, options?.policy),
479
+ durableBackend: getDurableBackend(),
480
+ };
481
+ return resumeDurableWorkflowAdapter(workflowIdOrPrefix, adapterDeps, preparedDurableCatalog);
482
+ },
483
+ listDurableResumable(sessionDir?: string): readonly ResumableWorkflowEntry[] {
484
+ const backend = getDurableBackend();
485
+ const live = backend.listResumableWorkflows();
486
+ const dir = sessionDir ?? resolveDefaultStageSessionDir?.();
487
+ if (dir === undefined) return live;
488
+ const scanned = scanResumableWorkflows(dir);
489
+ const liveIds = new Set(live.map((e) => e.workflowId));
490
+ const compatible = scanned.filter((e) => !liveIds.has(e.workflowId) && backend.getWorkflow(e.workflowId) !== undefined && !isBackendTerminal(backend, e.workflowId));
491
+ return [...live, ...compatible];
492
+ },
493
+
494
+ async prepareDurableResumable(workflowIdOrPrefix?: string, sessionDir?: string): Promise<readonly ResumableWorkflowEntry[]> {
495
+ await ensureDbosReady();
496
+ preparedDurableCatalog = await prepareRuntimeDurableResumable(getDurableBackend, () => resolveDefaultStageSessionDir?.(), workflowIdOrPrefix, sessionDir);
497
+ return preparedDurableCatalog;
498
+ },
460
499
  };
461
500
  }
@@ -179,7 +179,7 @@ function makeWorkflowStageOrchestrationContext(meta: StageExecutionMeta): NonNul
179
179
  workflowStageName: meta.stageName,
180
180
  constraints: {
181
181
  disableWorkflowTool: true,
182
- maxSubagentDepth: 2,
182
+ maxSubagentDepth: 5,
183
183
  },
184
184
  };
185
185
  }
@@ -5,6 +5,7 @@ import { store } from "../shared/store.js";
5
5
  import { topLevelWorkflowRuns } from "../shared/run-visibility.js";
6
6
  import { renderSessionList } from "../tui/session-list.js";
7
7
  import { openKillConfirm, openSessionPicker } from "../tui/session-overlays.js";
8
+ import { openWorkflowResumeSelector } from "../tui/workflow-resume-selector.js";
8
9
  import { deriveGraphTheme } from "../tui/graph-theme.js";
9
10
  import { emitChatSurface } from "../tui/chat-surface-message.js";
10
11
  import type { GraphOverlayPort } from "../tui/overlay-adapter.js";
@@ -13,6 +14,8 @@ import type { ExtensionAPI, PiCommandContext } from "./public-types.js";
13
14
  import type { WorkflowCommandReporter } from "./workflow-command-utils.js";
14
15
  import { stripYesFlag } from "./workflow-command-utils.js";
15
16
  import { workflowPolicyFromContext } from "./workflow-policy.js";
17
+ import { formatResumableWorkflowList } from "../durable/resume-catalog.js";
18
+ import type { ResumableWorkflowEntry } from "../durable/types.js";
16
19
  import {
17
20
  formatAlreadyEndedRetainedMessage,
18
21
  overlaySurfaceFromContext,
@@ -37,6 +40,75 @@ function resolveAttachStageId(runId: string, stageTarget: string | undefined): s
37
40
  return byName?.id ?? false;
38
41
  }
39
42
 
43
+ function filterSelectorDurableEntries(
44
+ runtime: ExtensionRuntime,
45
+ entries: readonly ResumableWorkflowEntry[],
46
+ ): readonly ResumableWorkflowEntry[] {
47
+ const registry = runtime.registry as { has(name: string): boolean } | undefined;
48
+ if (registry === undefined) return entries;
49
+ return entries.filter((entry) => {
50
+ const requiresCurrentDefinition = entry.status === "running" || entry.status === "failed" || entry.status === "blocked";
51
+ return !requiresCurrentDefinition || registry.has(entry.name);
52
+ });
53
+ }
54
+
55
+
56
+ async function handleDurableResume(
57
+ target: string | undefined,
58
+ ctx: PiCommandContext,
59
+ reporter: WorkflowCommandReporter,
60
+ deps: WorkflowRunControlDeps,
61
+ ): Promise<boolean> {
62
+ const print = (msg: string): void => reporter.info(msg);
63
+ const fail = (msg: string): void => reporter.error(msg);
64
+ const runtime = deps.runtimeForContext(ctx);
65
+ const policy = workflowPolicyFromContext(ctx);
66
+ // Hydrate the durable backend from DBOS (if configured) before listing so a
67
+ // fresh process discovers workflows persisted by a prior session.
68
+ const prepared = await runtime.prepareDurableResumable(target);
69
+ const durable = filterSelectorDurableEntries(runtime, prepared);
70
+ if (target !== undefined) {
71
+ // Attempt resume by id/prefix against the durable catalog.
72
+ const result = runtime.resumeDurableWorkflow(target, { policy });
73
+ if (result.ok) {
74
+ print(result.message);
75
+ // Open/connect the overlay to the resumed run, analogous to live resume.
76
+ if (policy.allowInputPicker) deps.overlay.open(result.runId, overlaySurfaceFromContext(ctx));
77
+ return true;
78
+ }
79
+ // Not a durable workflow either — surface the catalog for discovery.
80
+ if (durable.length > 0) {
81
+ fail(`${result.message}\n\n${formatResumableWorkflowList(durable)}`);
82
+ } else {
83
+ fail(result.message);
84
+ }
85
+ return true;
86
+ }
87
+ // No target: show the durable selector when interactive, otherwise print.
88
+ if (durable.length === 0) {
89
+ fail("No resumable durable workflows found. Usage: /workflow resume <id> (or /resume for Atomic sessions).");
90
+ return true;
91
+ }
92
+ if (!policy.allowInputPicker) {
93
+ print(`${formatResumableWorkflowList(durable)}\n\nResume with: /workflow resume <id>`);
94
+ return true;
95
+ }
96
+ const picked = await openWorkflowResumeSelector(ctx.ui, [], durable);
97
+ if (picked.kind === "durable") {
98
+ const result = runtime.resumeDurableWorkflow(picked.workflowId, { policy });
99
+ if (result.ok) {
100
+ print(result.message);
101
+ if (policy.allowInputPicker) deps.overlay.open(result.runId, overlaySurfaceFromContext(ctx));
102
+ } else {
103
+ fail(result.message);
104
+ }
105
+ }
106
+ if (picked.kind !== "durable") {
107
+ print(`${formatResumableWorkflowList(durable)}\n\nResume with: /workflow resume <id>`);
108
+ }
109
+ return true;
110
+ }
111
+
40
112
  export async function handleRunControlCommand(
41
113
  action: "connect" | "interrupt" | "kill" | "attach" | "pause" | "resume",
42
114
  rest: string[],
@@ -115,7 +187,7 @@ export async function handleRunControlCommand(
115
187
  }
116
188
  if (failHeadlessAttachCommand("connect", resolved.runId)) return true;
117
189
  if (policy.allowInputPicker) deps.overlay.open(resolved.runId, overlaySurfaceFromContext(ctx));
118
- print(`Attached to ${resolved.runId.slice(0, 8)}. h/ctrl+d hide · q kill · esc close.`);
190
+ print(`Attached to ${resolved.runId.slice(0, 8)}. h/ctrl+d hide · q quit (resumable via /workflow resume) · esc close.`);
119
191
  return true;
120
192
  }
121
193
 
@@ -206,10 +278,64 @@ export async function handleRunControlCommand(
206
278
  if (action === "pause") {
207
279
  const active = topLevelWorkflowRuns(store.runs()).filter((r) => r.endedAt === undefined);
208
280
  fail(active.length === 0 ? "No active runs to pause." : `Picker requires an interactive UI surface. Active runs:\n${active.map((r) => ` ${r.id.slice(0, 8)} ${r.name}`).join("\n")}\n\nUsage: /workflow pause <runId> [stageId]`);
281
+ } else if (action === "attach") {
282
+ fail(`${renderSessionList(store.runs(), { theme, includeAll: true })}\n\nPicker requires an interactive UI surface. Pass a runId: /workflow attach <id> [stageId]`);
209
283
  } else {
210
- fail(action === "attach"
211
- ? `${renderSessionList(store.runs(), { theme, includeAll: true })}\n\nPicker requires an interactive UI surface. Pass a runId: /workflow attach <id> [stageId]`
212
- : "Usage: /workflow resume <runId> [stageId] [message…]");
284
+ // resume: show cross-session durable catalog in headless/print mode.
285
+ return await handleDurableResume(undefined, ctx, reporter, deps);
286
+ }
287
+ return true;
288
+ }
289
+ if (action === "resume") {
290
+ // Only inactive workflows belong in the resume selector. Live runs:
291
+ // show paused (quit) or recoverably-failed runs; actively-running live
292
+ // runs are hidden (resuming one that is executing would double-dispatch).
293
+ const liveRuns = topLevelWorkflowRuns(store.runs()).filter((run) =>
294
+ run.status === "paused" || (run.status === "failed" && run.resumable !== false),
295
+ );
296
+ // Durable entries: a `running` durable handle may be a crashed process
297
+ // (cross-session crash recovery), so it stays selectable UNLESS it
298
+ // matches an actively-executing live run in this session.
299
+ const activeLiveIds = new Set(
300
+ topLevelWorkflowRuns(store.runs())
301
+ .filter((run) => run.endedAt === undefined && run.status === "running" && run.exitReason !== "quit")
302
+ .map((run) => run.id),
303
+ );
304
+ const runtime = deps.runtimeForContext(ctx);
305
+ let durableEntries: readonly ResumableWorkflowEntry[] = [];
306
+ try {
307
+ const prepared = await runtime.prepareDurableResumable(undefined);
308
+ durableEntries = filterSelectorDurableEntries(runtime, prepared)
309
+ .filter((entry) => !activeLiveIds.has(entry.workflowId));
310
+ } catch (error) {
311
+ if (liveRuns.length === 0) {
312
+ const message = error instanceof Error ? error.message : String(error);
313
+ fail(`Failed to list resumable workflows: ${message}`);
314
+ return true;
315
+ }
316
+ }
317
+ const picked = await openWorkflowResumeSelector(ctx.ui, liveRuns, durableEntries);
318
+ if (picked.kind === "durable") return await handleDurableResume(picked.workflowId, ctx, reporter, deps);
319
+ if (picked.kind === "live") {
320
+ const resolved = resolveRunIdPrefix(picked.runId);
321
+ if (resolved.kind !== "exact") {
322
+ fail(`Run not found: ${picked.runId}`);
323
+ return true;
324
+ }
325
+ const run = store.runs().find((r) => r.id === resolved.runId);
326
+ const isPaused = run?.status === "paused" || (run?.stages.some((s) => s.status === "paused") ?? false);
327
+ const isResumableContinuation = run !== undefined && !isPaused && ((run.status === "failed" && run.endedAt !== undefined && run.resumable !== false) || (run.endedAt === undefined && run.resumable === true && run.failureRecoverability === "recoverable"));
328
+ if (isResumableContinuation) {
329
+ const continuation = deps.runtimeForContext(ctx).resumeFailedRun(resolved.runId, undefined, { policy });
330
+ continuation.ok ? print(continuation.message) : fail(continuation.message);
331
+ } else {
332
+ const result = resumeRun(resolved.runId, {});
333
+ if (result.ok && result.mode === "snapshot" && run?.exitReason === "quit") {
334
+ return await handleDurableResume(resolved.runId, ctx, reporter, deps);
335
+ }
336
+ if (result.ok && policy.allowInputPicker) deps.overlay.open(result.runId, overlaySurfaceFromContext(ctx));
337
+ result.ok ? print(result.message ?? `Resumed ${result.runId.slice(0, 8)}`) : fail(`Run not found: ${picked.runId}`);
338
+ }
213
339
  }
214
340
  return true;
215
341
  }
@@ -220,6 +346,11 @@ export async function handleRunControlCommand(
220
346
  } else {
221
347
  const resolved = resolveRunIdPrefix(target);
222
348
  if (resolved.kind === "not_found") {
349
+ // Not a live run — fall back to the cross-session durable resume catalog.
350
+ // cross-ref: issue #1498 — /workflow resume by top-level workflow id.
351
+ if (action === "resume") {
352
+ return await handleDurableResume(target, ctx, reporter, deps);
353
+ }
223
354
  fail(`Run not found: ${target}`);
224
355
  return true;
225
356
  }
@@ -260,6 +391,11 @@ export async function handleRunControlCommand(
260
391
  const run = store.runs().find((r) => r.id === stageRunId);
261
392
  const isPaused = run?.status === "paused" || (run?.stages.some((s) => s.status === "paused") ?? false);
262
393
  const isResumableContinuation = run !== undefined && !isPaused && ((run.status === "failed" && run.endedAt !== undefined && run.resumable !== false) || (run.endedAt === undefined && run.resumable === true && run.failureRecoverability === "recoverable"));
394
+ const isActivelyRunning = run !== undefined && run.endedAt === undefined && run.status === "running" && !isPaused && run.exitReason !== "quit";
395
+ if (isActivelyRunning && action === "resume") {
396
+ fail(`Workflow ${stageRunId.slice(0, 8)} is already running in this session. Attach with \`/workflow connect ${stageRunId.slice(0, 8)}\` instead of resuming.`);
397
+ return true;
398
+ }
263
399
  if (isResumableContinuation) {
264
400
  const continuation = deps.runtimeForContext(ctx).resumeFailedRun(stageRunId, stageId, { policy });
265
401
  continuation.ok ? print(continuation.message) : fail(continuation.message);
@@ -270,6 +406,9 @@ export async function handleRunControlCommand(
270
406
  fail(`Run not found: ${stageRunId.slice(0, 8)}`);
271
407
  return true;
272
408
  }
409
+ if (result.mode === "snapshot" && run?.exitReason === "quit" && action === "resume") {
410
+ return await handleDurableResume(stageRunId, ctx, reporter, deps);
411
+ }
273
412
  if (!isPaused) {
274
413
  if (policy.allowInputPicker) deps.overlay.open(result.runId, overlaySurfaceFromContext(ctx));
275
414
  print(result.message ?? `Snapshot available: run ${result.runId} (${result.snapshot.name}) — status: ${result.snapshot.status}, stages: ${result.snapshot.stages.length}`);