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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +3 -3
  3. package/dist/builtin/intercom/CHANGELOG.md +39 -0
  4. package/dist/builtin/intercom/README.md +22 -2
  5. package/dist/builtin/intercom/broker/broker.ts +676 -128
  6. package/dist/builtin/intercom/broker/client.ts +151 -35
  7. package/dist/builtin/intercom/broker/delivered-message-cache.ts +497 -37
  8. package/dist/builtin/intercom/broker/framing.ts +4 -2
  9. package/dist/builtin/intercom/broker/paths.ts +10 -0
  10. package/dist/builtin/intercom/broker/pending-send-registry.ts +1 -2
  11. package/dist/builtin/intercom/broker/send-handler.ts +311 -52
  12. package/dist/builtin/intercom/broker/send-signature.ts +4 -2
  13. package/dist/builtin/intercom/broker/socket-writes.ts +103 -0
  14. package/dist/builtin/intercom/broker/spawn.ts +9 -4
  15. package/dist/builtin/intercom/index.bundle.mjs +1410 -212
  16. package/dist/builtin/intercom/package.json +2 -2
  17. package/dist/builtin/intercom/recoverable-disconnect.ts +52 -0
  18. package/dist/builtin/intercom/retry-policy.ts +8 -0
  19. package/dist/builtin/intercom/skills/intercom/SKILL.md +17 -9
  20. package/dist/builtin/intercom/types.ts +27 -8
  21. package/dist/builtin/intercom/workflow-stage-path-matching.ts +90 -0
  22. package/dist/builtin/intercom/workflow-stage-target.ts +57 -0
  23. package/dist/builtin/mcp/index.bundle.mjs +427 -126
  24. package/dist/builtin/mcp/package.json +2 -2
  25. package/dist/builtin/subagents/CHANGELOG.md +19 -0
  26. package/dist/builtin/subagents/README.md +3 -3
  27. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  28. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  29. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  30. package/dist/builtin/subagents/agents/codebase-online-researcher.md +11 -11
  31. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  32. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  33. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  34. package/dist/builtin/subagents/agents/debugger.md +3 -3
  35. package/dist/builtin/subagents/agents/worker.md +2 -2
  36. package/dist/builtin/subagents/package.json +3 -3
  37. package/dist/builtin/subagents/skills/qlty/SKILL.md +29 -101
  38. package/dist/builtin/subagents/skills/qlty/references/manual-configuration.md +52 -0
  39. package/dist/builtin/subagents/skills/subagent/SKILL.md +11 -11
  40. package/dist/builtin/subagents/src/extension/index.bundle.mjs +49 -132
  41. package/dist/builtin/web-access/package.json +2 -2
  42. package/dist/builtin/workflows/CHANGELOG.md +46 -0
  43. package/dist/builtin/workflows/README.md +7 -7
  44. package/dist/builtin/workflows/builtin/adversarial-verification.js +2 -2
  45. package/dist/builtin/workflows/builtin/{chunk-szz1ajz9.js → chunk-42s7sw0b.js} +9 -2
  46. package/dist/builtin/workflows/builtin/{chunk-2dqb5s2q.js → chunk-79fjkcvh.js} +1 -1
  47. package/dist/builtin/workflows/builtin/{chunk-n58a7v26.js → chunk-b0v2xab1.js} +181 -10
  48. package/dist/builtin/workflows/builtin/{chunk-fghhy2a5.js → chunk-ed4jfn5t.js} +23 -5
  49. package/dist/builtin/workflows/builtin/{chunk-h3r2vkzc.js → chunk-hqpe2cyx.js} +60 -21
  50. package/dist/builtin/workflows/builtin/{chunk-hzzn6adg.js → chunk-k3w87x8y.js} +1 -1
  51. package/dist/builtin/workflows/builtin/{chunk-82ha8p41.js → chunk-n8h4yyew.js} +1 -1
  52. package/dist/builtin/workflows/builtin/{chunk-qwzvgxnq.js → chunk-reqr3sr3.js} +1 -1
  53. package/dist/builtin/workflows/builtin/{chunk-c53y8bdh.js → chunk-wgccch41.js} +1 -1
  54. package/dist/builtin/workflows/builtin/{chunk-0x6e303p.js → chunk-zbekjqew.js} +20 -7
  55. package/dist/builtin/workflows/builtin/{chunk-29wrp38a.js → chunk-ze5x3d1r.js} +1 -1
  56. package/dist/builtin/workflows/builtin/classify-and-act.js +2 -2
  57. package/dist/builtin/workflows/builtin/fan-out-and-synthesize.js +2 -2
  58. package/dist/builtin/workflows/builtin/generate-and-filter.js +2 -2
  59. package/dist/builtin/workflows/builtin/goal.js +3 -3
  60. package/dist/builtin/workflows/builtin/index.js +11 -11
  61. package/dist/builtin/workflows/builtin/loop-until-done.js +2 -2
  62. package/dist/builtin/workflows/builtin/open-claude-design.js +2 -2
  63. package/dist/builtin/workflows/builtin/ralph.js +3 -3
  64. package/dist/builtin/workflows/builtin/steering-context.js +1 -1
  65. package/dist/builtin/workflows/builtin/tournament.js +2 -2
  66. package/dist/builtin/workflows/package.json +2 -2
  67. package/dist/builtin/workflows/skills/prompt-engineer/SKILL.md +39 -52
  68. package/dist/builtin/workflows/skills/prompt-engineer/references/advanced_patterns.md +9 -37
  69. package/dist/builtin/workflows/skills/prompt-engineer/references/claude_fable_5.md +49 -0
  70. package/dist/builtin/workflows/skills/prompt-engineer/references/claude_fable_5_1.md +57 -0
  71. package/dist/builtin/workflows/skills/prompt-engineer/references/claude_opus_4_8.md +57 -0
  72. package/dist/builtin/workflows/skills/prompt-engineer/references/claude_opus_5.md +47 -0
  73. package/dist/builtin/workflows/skills/prompt-engineer/references/claude_sonnet_5.md +57 -0
  74. package/dist/builtin/workflows/skills/prompt-engineer/references/gpt_5_5.md +60 -0
  75. package/dist/builtin/workflows/skills/prompt-engineer/references/gpt_5_6.md +58 -0
  76. package/dist/builtin/workflows/skills/prompt-engineer/references/gpt_6_astra.md +58 -0
  77. package/dist/builtin/workflows/skills/prompt-engineer/references/quality_improvement.md +18 -4
  78. package/dist/builtin/workflows/src/extension/index.bundle.mjs +3194 -737
  79. package/dist/builtin/workflows/src/index.js +899 -436
  80. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +0 -10
  81. package/dist/cli/list-models.d.ts.map +1 -1
  82. package/dist/cli/list-models.js +4 -0
  83. package/dist/cli/list-models.js.map +1 -1
  84. package/dist/client/index.d.ts +1 -2
  85. package/dist/client/index.d.ts.map +1 -1
  86. package/dist/client/index.js +1 -2
  87. package/dist/client/index.js.map +1 -1
  88. package/dist/config.d.ts +0 -9
  89. package/dist/config.d.ts.map +1 -1
  90. package/dist/config.js +0 -45
  91. package/dist/config.js.map +1 -1
  92. package/dist/core/agent-session-compaction.d.ts.map +1 -1
  93. package/dist/core/agent-session-compaction.js +8 -6
  94. package/dist/core/agent-session-compaction.js.map +1 -1
  95. package/dist/core/agent-session-methods.d.ts +1 -0
  96. package/dist/core/agent-session-methods.d.ts.map +1 -1
  97. package/dist/core/agent-session-methods.js.map +1 -1
  98. package/dist/core/agent-session-models.d.ts.map +1 -1
  99. package/dist/core/agent-session-models.js +3 -4
  100. package/dist/core/agent-session-models.js.map +1 -1
  101. package/dist/core/agent-session-queue-pause.d.ts.map +1 -1
  102. package/dist/core/agent-session-queue-pause.js +6 -0
  103. package/dist/core/agent-session-queue-pause.js.map +1 -1
  104. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  105. package/dist/core/agent-session-runtime.js +13 -5
  106. package/dist/core/agent-session-runtime.js.map +1 -1
  107. package/dist/core/agent-session-tool-hooks.js +1 -1
  108. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  109. package/dist/core/agent-session-tree.d.ts.map +1 -1
  110. package/dist/core/agent-session-tree.js +8 -0
  111. package/dist/core/agent-session-tree.js.map +1 -1
  112. package/dist/core/agent-session.d.ts +2 -0
  113. package/dist/core/agent-session.d.ts.map +1 -1
  114. package/dist/core/agent-session.js +2 -0
  115. package/dist/core/agent-session.js.map +1 -1
  116. package/dist/core/compaction/branch-summarization.d.ts +2 -2
  117. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  118. package/dist/core/compaction/branch-summarization.js +4 -4
  119. package/dist/core/compaction/branch-summarization.js.map +1 -1
  120. package/dist/core/extensions/api-types.d.ts +8 -2
  121. package/dist/core/extensions/api-types.d.ts.map +1 -1
  122. package/dist/core/extensions/api-types.js.map +1 -1
  123. package/dist/core/extensions/context-types.d.ts +12 -0
  124. package/dist/core/extensions/context-types.d.ts.map +1 -1
  125. package/dist/core/extensions/context-types.js.map +1 -1
  126. package/dist/core/extensions/runner-shortcuts.d.ts.map +1 -1
  127. package/dist/core/extensions/runner-shortcuts.js +0 -1
  128. package/dist/core/extensions/runner-shortcuts.js.map +1 -1
  129. package/dist/core/fast-model-routing-transport.d.ts +12 -0
  130. package/dist/core/fast-model-routing-transport.d.ts.map +1 -0
  131. package/dist/core/{codex-fast-mode-transport.js → fast-model-routing-transport.js} +29 -29
  132. package/dist/core/fast-model-routing-transport.js.map +1 -0
  133. package/dist/core/fast-model-routing.d.ts +57 -0
  134. package/dist/core/fast-model-routing.d.ts.map +1 -0
  135. package/dist/core/fast-model-routing.js +201 -0
  136. package/dist/core/fast-model-routing.js.map +1 -0
  137. package/dist/core/fast-model-variants.d.ts +98 -0
  138. package/dist/core/fast-model-variants.d.ts.map +1 -0
  139. package/dist/core/fast-model-variants.js +148 -0
  140. package/dist/core/fast-model-variants.js.map +1 -0
  141. package/dist/core/http-dispatcher.d.ts.map +1 -1
  142. package/dist/core/http-dispatcher.js +4 -2
  143. package/dist/core/http-dispatcher.js.map +1 -1
  144. package/dist/core/keybindings.d.ts +0 -10
  145. package/dist/core/keybindings.d.ts.map +1 -1
  146. package/dist/core/keybindings.js +0 -8
  147. package/dist/core/keybindings.js.map +1 -1
  148. package/dist/core/messages.d.ts +1 -1
  149. package/dist/core/messages.d.ts.map +1 -1
  150. package/dist/core/messages.js.map +1 -1
  151. package/dist/core/model-config.d.ts +15 -0
  152. package/dist/core/model-config.d.ts.map +1 -1
  153. package/dist/core/model-config.js +3 -0
  154. package/dist/core/model-config.js.map +1 -1
  155. package/dist/core/model-resolver-initial.js +1 -1
  156. package/dist/core/model-resolver-initial.js.map +1 -1
  157. package/dist/core/model-runtime-streaming.d.ts +14 -1
  158. package/dist/core/model-runtime-streaming.d.ts.map +1 -1
  159. package/dist/core/model-runtime-streaming.js +25 -3
  160. package/dist/core/model-runtime-streaming.js.map +1 -1
  161. package/dist/core/model-runtime.d.ts +39 -2
  162. package/dist/core/model-runtime.d.ts.map +1 -1
  163. package/dist/core/model-runtime.js +91 -7
  164. package/dist/core/model-runtime.js.map +1 -1
  165. package/dist/core/provider-composer-internal.d.ts.map +1 -1
  166. package/dist/core/provider-composer-internal.js +8 -2
  167. package/dist/core/provider-composer-internal.js.map +1 -1
  168. package/dist/core/sdk.d.ts.map +1 -1
  169. package/dist/core/sdk.js +18 -18
  170. package/dist/core/sdk.js.map +1 -1
  171. package/dist/core/session-manager-archive.d.ts.map +1 -1
  172. package/dist/core/session-manager-archive.js +25 -2
  173. package/dist/core/session-manager-archive.js.map +1 -1
  174. package/dist/core/settings-manager-core.d.ts +0 -2
  175. package/dist/core/settings-manager-core.d.ts.map +1 -1
  176. package/dist/core/settings-manager-core.js +2 -9
  177. package/dist/core/settings-manager-core.js.map +1 -1
  178. package/dist/core/settings-manager-internals.d.ts +0 -1
  179. package/dist/core/settings-manager-internals.d.ts.map +1 -1
  180. package/dist/core/settings-manager-internals.js.map +1 -1
  181. package/dist/core/settings-manager-ui-accessors.d.ts +0 -8
  182. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  183. package/dist/core/settings-manager-ui-accessors.js +0 -53
  184. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  185. package/dist/core/settings-manager.d.ts +1 -1
  186. package/dist/core/settings-manager.d.ts.map +1 -1
  187. package/dist/core/settings-manager.js.map +1 -1
  188. package/dist/core/settings-types.d.ts +0 -5
  189. package/dist/core/settings-types.d.ts.map +1 -1
  190. package/dist/core/settings-types.js.map +1 -1
  191. package/dist/core/skills.d.ts +1 -1
  192. package/dist/core/skills.d.ts.map +1 -1
  193. package/dist/core/skills.js +4 -2
  194. package/dist/core/skills.js.map +1 -1
  195. package/dist/core/slash-commands.d.ts.map +1 -1
  196. package/dist/core/slash-commands.js +0 -1
  197. package/dist/core/slash-commands.js.map +1 -1
  198. package/dist/core/system-prompt.js +7 -7
  199. package/dist/core/system-prompt.js.map +1 -1
  200. package/dist/core/tools/edit.d.ts +1 -1
  201. package/dist/core/tools/edit.d.ts.map +1 -1
  202. package/dist/core/tools/edit.js +128 -3
  203. package/dist/core/tools/edit.js.map +1 -1
  204. package/dist/core/tools/hashline.d.ts +2 -2
  205. package/dist/core/tools/hashline.d.ts.map +1 -1
  206. package/dist/core/tools/hashline.js +40 -10
  207. package/dist/core/tools/hashline.js.map +1 -1
  208. package/dist/core/tools/write.d.ts.map +1 -1
  209. package/dist/core/tools/write.js +8 -8
  210. package/dist/core/tools/write.js.map +1 -1
  211. package/dist/core/workflow-stage-admission.d.ts +6 -0
  212. package/dist/core/workflow-stage-admission.d.ts.map +1 -1
  213. package/dist/core/workflow-stage-admission.js +14 -0
  214. package/dist/core/workflow-stage-admission.js.map +1 -1
  215. package/dist/index-extensions.d.ts +1 -1
  216. package/dist/index-extensions.d.ts.map +1 -1
  217. package/dist/index-extensions.js.map +1 -1
  218. package/dist/index.d.ts +5 -5
  219. package/dist/index.d.ts.map +1 -1
  220. package/dist/index.js +4 -5
  221. package/dist/index.js.map +1 -1
  222. package/dist/modes/interactive/components/atomic-working-status.d.ts +4 -0
  223. package/dist/modes/interactive/components/atomic-working-status.d.ts.map +1 -1
  224. package/dist/modes/interactive/components/atomic-working-status.js +26 -1
  225. package/dist/modes/interactive/components/atomic-working-status.js.map +1 -1
  226. package/dist/modes/interactive/components/custom-editor.d.ts +7 -0
  227. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  228. package/dist/modes/interactive/components/custom-editor.js +43 -0
  229. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  230. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  231. package/dist/modes/interactive/components/footer.js +0 -6
  232. package/dist/modes/interactive/components/footer.js.map +1 -1
  233. package/dist/modes/interactive/components/index.d.ts +1 -2
  234. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  235. package/dist/modes/interactive/components/index.js +0 -1
  236. package/dist/modes/interactive/components/index.js.map +1 -1
  237. package/dist/modes/interactive/components/model-selector.d.ts +1 -1
  238. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  239. package/dist/modes/interactive/components/model-selector.js +6 -11
  240. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  241. package/dist/modes/interactive/components/scoped-models-selector.d.ts +2 -5
  242. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  243. package/dist/modes/interactive/components/scoped-models-selector.js +3 -19
  244. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  245. package/dist/modes/interactive/components/settings-selector-items.js +1 -1
  246. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  247. package/dist/modes/interactive/components/thinking-selector.d.ts +1 -2
  248. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  249. package/dist/modes/interactive/components/thinking-selector.js +4 -11
  250. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  251. package/dist/modes/interactive/components/transcript-follow-indicator.js +3 -3
  252. package/dist/modes/interactive/components/transcript-follow-indicator.js.map +1 -1
  253. package/dist/modes/interactive/interactive-agent-events.js +8 -8
  254. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  255. package/dist/modes/interactive/interactive-autocomplete.js +5 -16
  256. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  257. package/dist/modes/interactive/interactive-bash-compact.js +2 -9
  258. package/dist/modes/interactive/interactive-bash-compact.js.map +1 -1
  259. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  260. package/dist/modes/interactive/interactive-deferred-startup.js +3 -0
  261. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  262. package/dist/modes/interactive/interactive-editor-actions.js +2 -2
  263. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  264. package/dist/modes/interactive/interactive-extension-custom-ui.js +1 -0
  265. package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
  266. package/dist/modes/interactive/interactive-extension-dialogs.js +7 -0
  267. package/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  268. package/dist/modes/interactive/interactive-extension-runtime.js +20 -10
  269. package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
  270. package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -5
  271. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  272. package/dist/modes/interactive/interactive-initial-session-binding.d.ts.map +1 -1
  273. package/dist/modes/interactive/interactive-initial-session-binding.js +3 -0
  274. package/dist/modes/interactive/interactive-initial-session-binding.js.map +1 -1
  275. package/dist/modes/interactive/interactive-input-handling.js +0 -8
  276. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  277. package/dist/modes/interactive/interactive-mode-base.d.ts +5 -1
  278. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  279. package/dist/modes/interactive/interactive-mode-base.js +15 -9
  280. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  281. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -3
  282. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  283. package/dist/modes/interactive/interactive-mode-deps.js +1 -3
  284. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  285. package/dist/modes/interactive/interactive-mode-surface.d.ts +9 -12
  286. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  287. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  288. package/dist/modes/interactive/interactive-model-routing.js +10 -13
  289. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  290. package/dist/modes/interactive/interactive-render-chat.js +29 -0
  291. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  292. package/dist/modes/interactive/interactive-selectors.js +2 -32
  293. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  294. package/dist/modes/interactive/interactive-session-routing.js +1 -5
  295. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  296. package/dist/modes/interactive/interactive-session-runtime.js +1 -5
  297. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  298. package/dist/modes/interactive/interactive-slash-commands.js +6 -13
  299. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  300. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  301. package/dist/modes/interactive/interactive-startup.js +19 -13
  302. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  303. package/dist/modes/interactive/interactive-tui.d.ts.map +1 -1
  304. package/dist/modes/interactive/interactive-tui.js +27 -3
  305. package/dist/modes/interactive/interactive-tui.js.map +1 -1
  306. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
  307. package/dist/modes/interactive-engine/engine-custom-ui.js +1 -0
  308. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
  309. package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
  310. package/dist/modes/interactive-engine/isolated-runtime.js +4 -1
  311. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
  312. package/dist/utils/child-process.d.ts.map +1 -1
  313. package/dist/utils/child-process.js +13 -6
  314. package/dist/utils/child-process.js.map +1 -1
  315. package/dist/utils/exif-orientation.d.ts.map +1 -1
  316. package/dist/utils/exif-orientation.js +2 -3
  317. package/dist/utils/exif-orientation.js.map +1 -1
  318. package/dist/utils/tools-manager.d.ts +1 -0
  319. package/dist/utils/tools-manager.d.ts.map +1 -1
  320. package/dist/utils/tools-manager.js +33 -18
  321. package/dist/utils/tools-manager.js.map +1 -1
  322. package/docs/custom-provider.md +2 -0
  323. package/docs/development.md +17 -0
  324. package/docs/docs.json +14 -2
  325. package/docs/extensions.md +9 -4
  326. package/docs/intercom.md +41 -7
  327. package/docs/keybindings.md +8 -6
  328. package/docs/models/evals.md +394 -0
  329. package/docs/models/model-selection.md +54 -27
  330. package/docs/models/pareto-efficiency.md +33 -16
  331. package/docs/models.md +37 -1
  332. package/docs/packages.md +2 -2
  333. package/docs/providers.md +44 -20
  334. package/docs/quickstart.md +8 -6
  335. package/docs/rpc.md +3 -3
  336. package/docs/sdk.md +2 -16
  337. package/docs/settings.md +19 -22
  338. package/docs/skills.md +4 -2
  339. package/docs/subagents.md +9 -3
  340. package/docs/tools/edit.md +373 -0
  341. package/docs/tools.md +3 -7
  342. package/docs/tui.md +2 -1
  343. package/docs/usage.md +3 -5
  344. package/docs/workflows/api-reference.md +1395 -0
  345. package/docs/workflows/authoring.md +678 -0
  346. package/docs/workflows/builtins.md +245 -0
  347. package/docs/workflows/operations.md +811 -0
  348. package/docs/workflows/reliable-design.md +2099 -0
  349. package/docs/workflows/verification.md +62 -0
  350. package/docs/workflows.md +15 -5183
  351. package/npm-shrinkwrap.json +584 -69
  352. package/package.json +7 -7
  353. package/dist/client/remote-session.d.ts +0 -64
  354. package/dist/client/remote-session.d.ts.map +0 -1
  355. package/dist/client/remote-session.js +0 -351
  356. package/dist/client/remote-session.js.map +0 -1
  357. package/dist/client/transcript.d.ts +0 -12
  358. package/dist/client/transcript.d.ts.map +0 -1
  359. package/dist/client/transcript.js +0 -98
  360. package/dist/client/transcript.js.map +0 -1
  361. package/dist/core/codex-fast-mode-transport.d.ts +0 -12
  362. package/dist/core/codex-fast-mode-transport.d.ts.map +0 -1
  363. package/dist/core/codex-fast-mode-transport.js.map +0 -1
  364. package/dist/core/codex-fast-mode.d.ts +0 -53
  365. package/dist/core/codex-fast-mode.d.ts.map +0 -1
  366. package/dist/core/codex-fast-mode.js +0 -249
  367. package/dist/core/codex-fast-mode.js.map +0 -1
  368. package/dist/modes/interactive/components/fast-mode-selector.d.ts +0 -27
  369. package/dist/modes/interactive/components/fast-mode-selector.d.ts.map +0 -1
  370. package/dist/modes/interactive/components/fast-mode-selector.js +0 -107
  371. package/dist/modes/interactive/components/fast-mode-selector.js.map +0 -1
  372. package/dist/server/create-harness.d.ts +0 -53
  373. package/dist/server/create-harness.d.ts.map +0 -1
  374. package/dist/server/create-harness.js +0 -360
  375. package/dist/server/create-harness.js.map +0 -1
  376. package/docs/models/artificial-analysis-index.md +0 -83
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/intercom",
3
- "version": "0.9.18-alpha.5",
3
+ "version": "0.9.18-alpha.7",
4
4
  "private": true,
5
5
  "description": "Atomic extension providing a private coordination channel between parent and child agent sessions. Fork of: https://github.com/nicobailon/pi-intercom",
6
6
  "contributors": [
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@bastani/atomic": "*",
47
- "@earendil-works/pi-tui": "^0.84.4"
47
+ "@earendil-works/pi-tui": "^0.85.1"
48
48
  },
49
49
  "peerDependenciesMeta": {
50
50
  "@bastani/atomic": {
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Classification for a *recoverable* Intercom broker disconnect.
3
+ *
4
+ * The client socket is gone, but the lightweight extension wrapper owns
5
+ * recovery: a failed lazy-initialization attempt is discarded, and the next
6
+ * call re-imports the heavy module and reconnects. Work the user did not ask
7
+ * for — session lifecycle events and background event relays — must therefore
8
+ * not render such a disconnect as a failure while that retry is still ahead.
9
+ * Explicit, user-initiated operations keep rejecting visibly.
10
+ *
11
+ * Classification is by construction, never by message text. Only errors this
12
+ * module creates carry the marker, so an identically worded error raised
13
+ * anywhere else — and every protocol, authentication, configuration, or
14
+ * non-recoverable initialization failure — stays actionable.
15
+ */
16
+
17
+ /** Model-visible recovery direction for a stale broker socket. */
18
+ export const RECOVERABLE_DISCONNECT_MESSAGE =
19
+ "Client disconnected. Retry the same Intercom call up to three times to reconnect.";
20
+
21
+ /**
22
+ * Bound on the `cause` chain walk. Intercom wraps failures with `cause` on the
23
+ * relay and reply paths (`subagent-relay.ts` and `index-heavy.ts` both do), so
24
+ * a recoverable disconnect can arrive nested; the bound keeps a cyclic or
25
+ * adversarially deep chain from turning classification into a hang.
26
+ */
27
+ const MAX_CAUSE_DEPTH = 8;
28
+
29
+ interface RecoverableDisconnectMarker {
30
+ readonly intercomRecoverableDisconnect?: boolean;
31
+ }
32
+
33
+ /** Raised when an established broker socket is gone and lazy re-initialization can retry. */
34
+ export class IntercomClientDisconnectedError extends Error implements RecoverableDisconnectMarker {
35
+ readonly intercomRecoverableDisconnect = true;
36
+
37
+ constructor(options?: ErrorOptions) {
38
+ super(RECOVERABLE_DISCONNECT_MESSAGE, options);
39
+ this.name = "IntercomClientDisconnectedError";
40
+ }
41
+ }
42
+
43
+ /** True only for an `IntercomClientDisconnectedError`, directly or as a bounded `cause` ancestor. */
44
+ export function isRecoverableIntercomDisconnect(error: unknown): boolean {
45
+ let current: unknown = error;
46
+ for (let depth = 0; depth <= MAX_CAUSE_DEPTH; depth += 1) {
47
+ if (!(current instanceof Error)) return false;
48
+ if (current instanceof IntercomClientDisconnectedError) return true;
49
+ current = current.cause;
50
+ }
51
+ return false;
52
+ }
@@ -0,0 +1,8 @@
1
+ /** Existing maximum wait for an `ask` reply. */
2
+ export const ASK_REPLY_TIMEOUT_MS = 10 * 60 * 1000;
3
+ /** Bounded opportunity to repeat a typed recoverable-disconnect result after the ask wait. */
4
+ export const RETRY_IDENTITY_RETRY_OPPORTUNITY_MS = 60 * 1000;
5
+ /** An operation identity covers the full ask wait plus one explicit retry opportunity. */
6
+ export const RETRY_IDENTITY_TTL_MS = ASK_REPLY_TIMEOUT_MS + RETRY_IDENTITY_RETRY_OPPORTUNITY_MS;
7
+ /** Broker authority outlives client-held identities so a boundary retry cannot lose acceptance proof in transit. */
8
+ export const DELIVERED_MESSAGE_TTL_MS = RETRY_IDENTITY_TTL_MS + RETRY_IDENTITY_RETRY_OPPORTUNITY_MS;
@@ -75,24 +75,24 @@ intercom({ action: "list" })
75
75
  intercom({ action: "ask", to: "6332faab-1111-4222-8333-123456789abc", message: "Which option should I use?" })
76
76
  ```
77
77
 
78
- Live sessions accept an exact full Intercom session ID or exact case-insensitive name. For workflow stages, first use `intercom({ action: "list" })`: materialized stages appear as `PENDING` or `RUNNING` with canonical `<runId>:<stageId>` targets and actual groups. The invocation context can control owned isolated subgroups by exact target, while sibling subgroups and other runs remain isolated. Use queued `send` for `PENDING`; `ask` is supported only for `RUNNING`, where an exact correlated reply returns to the invocation asker.
78
+ Live sessions accept an exact full Intercom session ID or exact case-insensitive name. For workflow stages, first join `workflow:<rootRunId>` and use `intercom({ action: "list" })`: materialized stages appear as `PENDING` or `RUNNING` with canonical `workflow:<rootRunId>/<segment>[/<segment>...]` targets and actual groups, followed by possible future targets with queued counts. The invocation context can control owned isolated subgroups by exact target, while sibling subgroups and other runs remain isolated. Use queued `send` for `PENDING` or future targets; `ask` is supported only for `RUNNING`, where an exact correlated reply returns to the invocation asker.
79
79
 
80
80
  ### Deliver to workflow stages that have not started
81
81
 
82
- Send material updates through Intercom to every affected workflow stage, including stages that have not started. Atomic queues messages for known pending stages and delivers them when their sessions initialize:
83
-
84
- Before steering a stage, join its invocation group. Use the Intercom `groups` action to discover it. Workflow invocation groups are named `workflow:<rootRunId>`.
82
+ Send material updates through Intercom to every affected workflow stage, including stages that have not started. Before steering, join the invocation group `workflow:<rootRunId>` (discover it with the Intercom `groups` action), then use `intercom list` there to see live, pending, and possible future targets.
85
83
 
86
84
  ```typescript
87
85
  intercom({
88
86
  action: "send",
89
- to: "<runId>:reviewer",
87
+ to: "workflow:<rootRunId>/reviewer",
90
88
  message: "Scope changed: preserve raw amendment text in the verification oracle."
91
89
  })
92
90
  // → queued, distinct from live-session delivered, with the FIFO position
93
91
  ```
94
92
 
95
- The stage receives the ordinary inbound Intercom message before its first model turn under **Messages received before you started**, with real sender identity and a `Sent:` timestamp. Only same-workflow-group sessions may queue messages. Each exact run/stage key holds at most 50 queued messages; the next send is refused rather than evicting one. Resume/replay, broker restart, and stage-attempt restart preserve exactly-once delivery. If the stage is skipped, cancelled, or becomes terminal before its session initializes, the message becomes undeliverable and acknowledgment-requesting senders receive a correlated failure. Do not use `ask`: Atomic returns `pending_stage_ask_unsupported` and recommends ordinary `send` instead of holding an unbounded waiter.
93
+ Each path segment may be a stage name, a run id, or a glob: `*` matches one segment and may be embedded (`reviewer-*`), while `**` matches any depth. When shared scope or acceptance criteria change, broadcast one authoritative update to `workflow:<rootRunId>/**` (or a narrower pattern) rather than enumerating stages. The broadcast reaches every live stage immediately and remains sticky for every future matching stage, including nested children, until the root run terminates. Other name or pattern sends have the same every-future-match behavior.
94
+
95
+ A syntactically valid target outside the persisted possible-stage set is accepted speculatively: the queued acknowledgment includes `notInKnownSet`. At terminal settlement, an entry that never delivered produces the correlated undeliverable notification; an entry delivered at least once does not. A stage receives queued messages through the ordinary inbound path before its first model turn under **Messages received before you started**, with real sender identity and a `Sent:` timestamp. Only same-workflow-group sessions may queue messages. Each target holds at most 50 queued messages; the next send is refused rather than evicting one. Resume/replay, broker restart, and stage-attempt restart preserve exactly-once delivery per message and materialized stage. Use `ask` only for a live target: pending, future, and pattern asks return `pending_stage_ask_unsupported`.
96
96
 
97
97
  ### Runtime named groups
98
98
 
@@ -242,7 +242,7 @@ Use constructive quorum when several fresh-context reviewers judge the same arti
242
242
  3. Change a verdict only through evidence, never deference. Each reviewer emits its own final structured verdict and records whether the round changed it and which evidence caused the change.
243
243
  4. Let the deterministic reducer count final votes; this pattern does not change quorum counts or the `stop_review_loop` contract.
244
244
 
245
- In Atomic workflows, each invocation has its own Intercom group, and parallel stages and delegated subagents inherit it when Intercom is available. Sibling reviewers can therefore coordinate without custom group wiring. See the [constructive quorum workflow pattern](../../../coding-agent/docs/workflows.md#common-workflow-patterns).
245
+ In Atomic workflows, each invocation has its own Intercom group, and parallel stages and delegated subagents inherit it when Intercom is available. Sibling reviewers can therefore coordinate without custom group wiring. See the [constructive quorum workflow pattern](../../../coding-agent/docs/workflows/reliable-design.md#common-workflow-patterns).
246
246
 
247
247
  ## Key Differences
248
248
 
@@ -251,7 +251,7 @@ In Atomic workflows, each invocation has its own Intercom group, and parallel st
251
251
  | `join` | Adds or creates a named membership in place | Sessions need another shared routing group |
252
252
  | `leave` | Removes one named membership, or resets to home when omitted | Stop sharing one group or restore startup membership |
253
253
  | `groups` | Lists every available group with counts and membership markers | Discover a group instead of guessing its name |
254
- | `send` | Fire-and-forget to a live session, or durable `queued` delivery to `<runId>:<stageKey>` before a workflow stage starts | You don't need a response |
254
+ | `send` | Fire-and-forget to a live session, or durable sticky delivery to `workflow:<rootRunId>/<segment>[/<segment>...]`; globs and `**` broadcasts cover live and future matches | You don't need a response |
255
255
  | `ask` | Blocks until a live recipient replies (10 min timeout); refused for an unstarted stage | You need an answer to continue |
256
256
  | `reply` | Responds to the active or pending inbound ask; `to` accepts an exact full session ID or exact session name | You were asked something and need to answer naturally |
257
257
  | `pending` | Lists unresolved inbound asks | You need to see who is waiting before replying |
@@ -493,7 +493,15 @@ if (!result.delivered) {
493
493
 
494
494
  ### Connection lost
495
495
 
496
- Sessions automatically reconnect if the broker restarts. If persistently disconnected:
496
+ Sessions automatically reconnect if the broker restarts. If an explicit `send`, `ask`, or `reply` fails with the typed `Client disconnected` error, copy the opaque `retryToken` from the tool result and repeat the exact action and arguments with it. Make at most three claimed attempts. Never attach that token to a different action, target, message, attachment sequence, attachment presence (`attachments` omitted is not explicit `[]`), or reply thread, and omit it for every fresh operation—even a deliberately byte-identical one. Invalid, expired, foreign-session, mismatched, concurrent, exhausted, and settled claims fail without sending.
497
+
498
+ The token keeps the original message ID and deadline (11 minutes from the initial attempt: the 10-minute ask window plus one minute). A claimed retry that returns `delivered: false`, `Session not found`, durable-authority uncertainty/capacity refusal, or another typed disconnect returns the same token for the next bounded claim; each claim consumes one attempt and never extends the deadline. Delivered or queued success settles it. Initial tokenless nondelivery and unrelated/non-recoverable failures do not create retry state.
499
+
500
+ Broker acceptance is retained for 12 minutes, so acknowledgement loss does not duplicate delivery and a deduplicated ask remains replyable. Implicit public reply prefers the recorded exact sender ID while live and falls back to authorized reconnect resolution only after departure. A retained implicit reply keeps its original sender/question snapshot, so later inbound asks cannot redirect its token claim. Durable SQLite stores fixed keyed HMAC digests rather than message/attachment text; its paired key and database artifacts are owner-only on POSIX. Missing, malformed, uncertain, or capacity-bound authority fails closed rather than risking a duplicate.
501
+
502
+ Retry safety is bounded: fresh client operations reserve one of 1,000 identity slots before confirmation, target resolution, or send, while valid existing claims remain usable at capacity. The broker and local result relay allow 10,000 live delivery records; the broker also bounds digest/routing authority to 64 MiB. At a limit Intercom refuses new work before its delivery side effect rather than evicting a still-valid identity.
503
+
504
+ If the session remains disconnected after those retries:
497
505
 
498
506
  ```typescript
499
507
  intercom({ action: "status" })
@@ -25,10 +25,26 @@ export interface WorkflowStageRosterEntry {
25
25
  readonly sessionId?: string;
26
26
  }
27
27
 
28
+ export interface WorkflowPossibleStageAnnouncement {
29
+ /** Canonical depth-faithful path target, e.g. `workflow:<rootRunId>/orchestrator-*`. */
30
+ readonly target: string;
31
+ /** Current number of queued sticky entries matching this target. */
32
+ readonly queuedCount: number;
33
+ }
34
+
35
+ export interface WorkflowFutureStageRosterEntry {
36
+ readonly kind: "workflow-future-stage";
37
+ readonly runId: string;
38
+ readonly target: string;
39
+ readonly queuedCount: number;
40
+ readonly group: string;
41
+ }
42
+
28
43
  export interface SessionDirectory {
29
44
  readonly sessions: SessionInfo[];
30
- readonly workflowStages: WorkflowStageRosterEntry[];
31
- }
45
+ readonly workflowStages: WorkflowStageRosterEntry[];
46
+ readonly workflowFutureStages: WorkflowFutureStageRosterEntry[];
47
+ }
32
48
 
33
49
  export interface WorkflowStageRosterAnnouncement {
34
50
  readonly stageId: string;
@@ -84,6 +100,8 @@ export type ClientMessage =
84
100
  session: Omit<SessionInfo, "id">;
85
101
  /** Internal host-owned identity retained across broker reconnects. */
86
102
  returnAddress?: string;
103
+ /** Immutable session origin; separate from mutable group memberships. Legacy clients use session.group. */
104
+ registrationGroup?: string;
87
105
  supervisor?: SupervisorRegistration;
88
106
  supervisorOwnerToken?: string;
89
107
  }
@@ -93,7 +111,7 @@ export type ClientMessage =
93
111
  | { type: "join_group"; requestId: string; group: string }
94
112
  | { type: "leave_group"; requestId: string; group?: string }
95
113
  | { type: "authorize_supervisor"; requestId: string; childName: string; capability?: string }
96
- | { type: "send" | "supervisor_send"; to: string; message: Message; attemptId?: string }
114
+ | { type: "send" | "supervisor_send"; to: string; logicalTarget?: string; requirePendingReply?: true; message: Message; attemptId?: string }
97
115
  | {
98
116
  type: "send_pending_stage_notification";
99
117
  runId: string;
@@ -105,7 +123,7 @@ export type ClientMessage =
105
123
  attemptId?: string;
106
124
  }
107
125
  | { type: "pending_stage_notification_result"; requestId: string; delivered: boolean }
108
- | { type: "register_pending_stage_route"; runId: string; group: string; capability: string; stages?: WorkflowStageRosterAnnouncement[] }
126
+ | { type: "register_pending_stage_route"; runId: string; group: string; capability: string; stages?: WorkflowStageRosterAnnouncement[]; possibleStages?: WorkflowPossibleStageAnnouncement[] }
109
127
  | {
110
128
  type: "register_live_workflow_stage_route";
111
129
  requestId: string;
@@ -118,6 +136,7 @@ export type ClientMessage =
118
136
  requestId: string;
119
137
  outcome: "queued" | "delivered" | "forward" | "refused";
120
138
  position?: number;
139
+ target?: string;
121
140
  reason?: string;
122
141
  reasonCode?: "message_id_conflict";
123
142
  }
@@ -135,7 +154,7 @@ export type ClientMessage =
135
154
  export type BrokerMessage =
136
155
  | { type: "registered"; sessionId: string; supervisorSessionId?: string }
137
156
  | { type: "registration_failed"; reason: string }
138
- | { type: "sessions"; requestId: string; sessions: SessionInfo[]; workflowStages?: WorkflowStageRosterEntry[] }
157
+ | { type: "sessions"; requestId: string; sessions: SessionInfo[]; workflowStages?: WorkflowStageRosterEntry[]; workflowFutureStages?: WorkflowFutureStageRosterEntry[] }
139
158
  | { type: "groups"; requestId: string; groups: GroupSummary[] }
140
159
  | { type: "membership_ack"; requestId: string; groups: string[] }
141
160
  | { type: "supervisor_authorized"; requestId: string; capability: string; supervisorSessionId: string; childName: string }
@@ -148,7 +167,7 @@ export type BrokerMessage =
148
167
  senderRegistrationName?: string;
149
168
  senderReturnAddress?: string;
150
169
  runId: string;
151
- stageKey: string;
170
+ target: string;
152
171
  message: Message;
153
172
  live?: boolean;
154
173
  }
@@ -161,5 +180,5 @@ export type BrokerMessage =
161
180
  | { type: "presence_failed"; requestId: string; reason: string }
162
181
  | { type: "error"; error: string }
163
182
  | { type: "delivered"; messageId: string; attemptId?: string }
164
- | { type: "queued"; messageId: string; attemptId?: string; runId: string; stageKey: string; position: number }
165
- | { type: "delivery_failed"; messageId: string; reason: string; reasonCode?: "message_id_conflict"; attemptId?: string };
183
+ | { type: "queued"; messageId: string; attemptId?: string; target: string; position: number }
184
+ | { type: "delivery_failed"; messageId: string; reason: string; reasonCode?: "message_id_conflict" | "session_not_found"; attemptId?: string };
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Shared glob semantics for workflow stage path targets (slice 3, D2/D5/D6).
3
+ *
4
+ * This module is mirrored verbatim in
5
+ * `packages/workflows/src/shared/workflow-stage-path-matching.ts` (the broker must stay
6
+ * loadable with only Node built-ins and Intercom-local modules, and amendment A1 forbids
7
+ * cross-package imports). A parity test runs both implementations over one fixture table
8
+ * and asserts identical results; keep the two files byte-identical in behavior.
9
+ */
10
+
11
+ /** Glob-match `candidateSegments` against `patternSegments`. */
12
+ export function matchStagePathSegments(
13
+ patternSegments: readonly string[],
14
+ candidateSegments: readonly string[],
15
+ ): boolean {
16
+ return matchSegmentsFrom(patternSegments, 0, candidateSegments, 0);
17
+ }
18
+
19
+ /** Split an unprefixed stage path into its `/` segments. */
20
+ export function splitStagePathSegments(path: string): string[] {
21
+ return path.split("/");
22
+ }
23
+
24
+ /** D4 membership (advisory, bidirectional) of a target path inside the persisted possible-stage set. */
25
+ export function targetSegmentsInPossibleStages(
26
+ targetSegments: readonly string[],
27
+ possibleStages: readonly string[],
28
+ ): boolean {
29
+ return possibleStages.some((entry) => {
30
+ const entrySegments = splitStagePathSegments(entry);
31
+ return (
32
+ matchStagePathSegments(entrySegments, targetSegments) ||
33
+ matchStagePathSegments(targetSegments, entrySegments)
34
+ );
35
+ });
36
+ }
37
+
38
+ function matchSegmentsFrom(
39
+ pattern: readonly string[],
40
+ patternIndex: number,
41
+ candidate: readonly string[],
42
+ candidateIndex: number,
43
+ ): boolean {
44
+ let p = patternIndex;
45
+ let c = candidateIndex;
46
+ while (p < pattern.length) {
47
+ const segment = pattern[p]!;
48
+ if (segment === "**") {
49
+ for (let skip = c; skip <= candidate.length; skip += 1) {
50
+ if (matchSegmentsFrom(pattern, p + 1, candidate, skip)) return true;
51
+ }
52
+ return false;
53
+ }
54
+ if (c >= candidate.length) return false;
55
+ if (!matchSegmentGlob(segment, candidate[c]!)) return false;
56
+ p += 1;
57
+ c += 1;
58
+ }
59
+ return c === candidate.length;
60
+ }
61
+
62
+ function matchSegmentGlob(pattern: string, value: string): boolean {
63
+ if (!pattern.includes("*")) return pattern === value;
64
+ let p = 0;
65
+ let v = 0;
66
+ let star = -1;
67
+ let mark = -1;
68
+ while (v < value.length) {
69
+ if (p < pattern.length && pattern[p] === "*") {
70
+ star = p;
71
+ mark = v;
72
+ p += 1;
73
+ continue;
74
+ }
75
+ if (p < pattern.length && pattern[p] === value[v]) {
76
+ p += 1;
77
+ v += 1;
78
+ continue;
79
+ }
80
+ if (star >= 0) {
81
+ p = star + 1;
82
+ mark += 1;
83
+ v = mark;
84
+ continue;
85
+ }
86
+ return false;
87
+ }
88
+ while (p < pattern.length && pattern[p] === "*") p += 1;
89
+ return p === pattern.length;
90
+ }
@@ -0,0 +1,57 @@
1
+ const WORKFLOW_RUN_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
2
+ const WORKFLOW_TARGET_PREFIX = "workflow:";
3
+
4
+ export type WorkflowStageTargetKind = "path" | "pattern" | "deep-pattern";
5
+
6
+ export interface WorkflowStageTarget {
7
+ readonly rootRunId: string;
8
+ readonly segments: string[];
9
+ readonly kind: WorkflowStageTargetKind;
10
+ }
11
+
12
+ export interface LegacyWorkflowStageTarget {
13
+ readonly runId: string;
14
+ readonly stageKey: string;
15
+ }
16
+
17
+ /** Parse the canonical root-anchored workflow-stage target grammar. */
18
+ export function parseWorkflowStageTarget(target: string): WorkflowStageTarget | undefined {
19
+ if (!target.startsWith(WORKFLOW_TARGET_PREFIX)) return undefined;
20
+ const slash = target.indexOf("/", WORKFLOW_TARGET_PREFIX.length);
21
+ if (slash < 0) return undefined;
22
+ const rootRunId = target.slice(WORKFLOW_TARGET_PREFIX.length, slash);
23
+ if (!WORKFLOW_RUN_ID_PATTERN.test(rootRunId)) return undefined;
24
+ const segments = target.slice(slash + 1).split("/");
25
+ if (segments.length === 0 || segments.some((segment) => segment.length === 0)) return undefined;
26
+ const kind = segments.includes("**")
27
+ ? "deep-pattern"
28
+ : segments.some((segment) => segment.includes("*"))
29
+ ? "pattern"
30
+ : "path";
31
+ return { rootRunId, segments, kind };
32
+ }
33
+
34
+ /** Detect the removed pre-D8 `<runId>:<stageKey>` grammar for migration errors only. */
35
+ export function parseLegacyWorkflowStageTarget(target: string): LegacyWorkflowStageTarget | undefined {
36
+ const separator = target.indexOf(":");
37
+ if (separator < 0) return undefined;
38
+ const runId = target.slice(0, separator);
39
+ const stageKey = target.slice(separator + 1);
40
+ return WORKFLOW_RUN_ID_PATTERN.test(runId) && stageKey.length > 0 ? { runId, stageKey } : undefined;
41
+ }
42
+
43
+ export function formatWorkflowStageTarget(rootRunId: string, ...segments: readonly string[]): string {
44
+ return `${WORKFLOW_TARGET_PREFIX}${rootRunId}/${segments.join("/")}`;
45
+ }
46
+
47
+ export function withWorkflowStageTargetFinalSegment(target: string, segment: string): string | undefined {
48
+ const parsed = parseWorkflowStageTarget(target);
49
+ if (parsed === undefined || segment.length === 0 || segment.includes("/")) return undefined;
50
+ return formatWorkflowStageTarget(parsed.rootRunId, ...parsed.segments.slice(0, -1), segment);
51
+ }
52
+
53
+ export function legacyWorkflowStageTargetMigrationHint(canonicalTarget?: string): string {
54
+ const base =
55
+ "Legacy workflow-stage targets in the `<runId>:<stageKey>` form are no longer supported. Use the canonical `workflow:<rootRunId>/<segment>` path form.";
56
+ return canonicalTarget === undefined ? base : `${base} Use \`${canonicalTarget}\` for this stage.`;
57
+ }