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

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 (375) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +3 -3
  3. package/dist/builtin/intercom/CHANGELOG.md +33 -0
  4. package/dist/builtin/intercom/README.md +17 -2
  5. package/dist/builtin/intercom/broker/broker.ts +670 -127
  6. package/dist/builtin/intercom/broker/client.ts +149 -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 +1406 -209
  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 +25 -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 +44 -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/docs.json +14 -2
  324. package/docs/extensions.md +9 -4
  325. package/docs/intercom.md +32 -7
  326. package/docs/keybindings.md +8 -6
  327. package/docs/models/evals.md +394 -0
  328. package/docs/models/model-selection.md +54 -27
  329. package/docs/models/pareto-efficiency.md +33 -16
  330. package/docs/models.md +37 -1
  331. package/docs/packages.md +2 -2
  332. package/docs/providers.md +44 -20
  333. package/docs/quickstart.md +8 -6
  334. package/docs/rpc.md +3 -3
  335. package/docs/sdk.md +2 -16
  336. package/docs/settings.md +19 -22
  337. package/docs/skills.md +4 -2
  338. package/docs/subagents.md +9 -3
  339. package/docs/tools/edit.md +373 -0
  340. package/docs/tools.md +3 -7
  341. package/docs/tui.md +2 -1
  342. package/docs/usage.md +3 -5
  343. package/docs/workflows/api-reference.md +1395 -0
  344. package/docs/workflows/authoring.md +678 -0
  345. package/docs/workflows/builtins.md +245 -0
  346. package/docs/workflows/operations.md +811 -0
  347. package/docs/workflows/reliable-design.md +2099 -0
  348. package/docs/workflows/verification.md +62 -0
  349. package/docs/workflows.md +15 -5183
  350. package/npm-shrinkwrap.json +584 -69
  351. package/package.json +7 -7
  352. package/dist/client/remote-session.d.ts +0 -64
  353. package/dist/client/remote-session.d.ts.map +0 -1
  354. package/dist/client/remote-session.js +0 -351
  355. package/dist/client/remote-session.js.map +0 -1
  356. package/dist/client/transcript.d.ts +0 -12
  357. package/dist/client/transcript.d.ts.map +0 -1
  358. package/dist/client/transcript.js +0 -98
  359. package/dist/client/transcript.js.map +0 -1
  360. package/dist/core/codex-fast-mode-transport.d.ts +0 -12
  361. package/dist/core/codex-fast-mode-transport.d.ts.map +0 -1
  362. package/dist/core/codex-fast-mode-transport.js.map +0 -1
  363. package/dist/core/codex-fast-mode.d.ts +0 -53
  364. package/dist/core/codex-fast-mode.d.ts.map +0 -1
  365. package/dist/core/codex-fast-mode.js +0 -249
  366. package/dist/core/codex-fast-mode.js.map +0 -1
  367. package/dist/modes/interactive/components/fast-mode-selector.d.ts +0 -27
  368. package/dist/modes/interactive/components/fast-mode-selector.d.ts.map +0 -1
  369. package/dist/modes/interactive/components/fast-mode-selector.js +0 -107
  370. package/dist/modes/interactive/components/fast-mode-selector.js.map +0 -1
  371. package/dist/server/create-harness.d.ts +0 -53
  372. package/dist/server/create-harness.d.ts.map +0 -1
  373. package/dist/server/create-harness.js +0 -360
  374. package/dist/server/create-harness.js.map +0 -1
  375. package/docs/models/artificial-analysis-index.md +0 -83
@@ -1,44 +1,504 @@
1
- const DEFAULT_TTL_MS = 10 * 60 * 1000;
2
- const DEFAULT_MAX_ENTRIES = 10_000;
1
+ import { createHmac, randomBytes } from "node:crypto";
2
+ import {
3
+ chmodSync,
4
+ closeSync,
5
+ existsSync,
6
+ mkdirSync,
7
+ openSync,
8
+ readFileSync,
9
+ writeFileSync,
10
+ } from "node:fs";
11
+ import { dirname } from "node:path";
12
+ import { DatabaseSync } from "node:sqlite";
13
+ import { DELIVERED_MESSAGE_TTL_MS } from "../retry-policy.js";
3
14
 
4
- export type DeliveredMessageMatch = "miss" | "match" | "conflict";
15
+ export const DELIVERED_MESSAGE_MAX_ENTRIES = 10_000;
16
+ /** Upper bound for persisted authority bytes (signatures are fixed-size HMAC digests). */
17
+ export const DELIVERED_MESSAGE_MAX_BYTES = 64 * 1024 * 1024;
18
+ const AUTHORITY_KEY_BYTES = 32;
19
+ const AUTHORITY_DIGEST_PATTERN = /^[a-f0-9]{64}$/u;
20
+
21
+ export type DeliveredMessageMatch = "miss" | "match" | "conflict" | "uncertain" | "invalid";
22
+ export type DeliveredMessageRecordResult = "recorded" | "match" | "conflict" | "uncertain" | "capacity" | "invalid";
23
+ export type DeliveredMessageAcceptResult = "accepted" | "conflict" | "invalid";
24
+
25
+ export interface DeliveredQuestionRoute {
26
+ readonly targetSessionId: string;
27
+ readonly senderGroupIdentity: string;
28
+ }
5
29
 
6
30
  interface DeliveredMessage {
7
- deliveredAt: number;
8
- signature: string;
31
+ state: "reserved" | "accepted";
32
+ deliveredAt: number;
33
+ signature: string;
34
+ targetIdentity?: string;
35
+ questionRoute?: DeliveredQuestionRoute;
36
+ }
37
+
38
+ interface SqliteStatement {
39
+ get(...params: Array<string | number | null>): Record<string, unknown> | undefined;
40
+ run(...params: Array<string | number | null>): { changes: number | bigint };
41
+ }
42
+
43
+ interface SqliteDatabase {
44
+ exec(sql: string): void;
45
+ prepare(sql: string): SqliteStatement;
46
+ close(): void;
47
+ }
48
+
49
+ function validStoredString(value: unknown): value is string {
50
+ return typeof value === "string" && value.length > 0;
9
51
  }
10
52
 
11
- /** Bounded successful-delivery cache used to make broker and local retries idempotent. */
53
+ function entryByteSize(messageId: string, delivered: DeliveredMessage): number {
54
+ return [
55
+ messageId,
56
+ delivered.signature,
57
+ delivered.targetIdentity,
58
+ delivered.questionRoute?.targetSessionId,
59
+ delivered.questionRoute?.senderGroupIdentity,
60
+ ].reduce((total, value) => total + (value === undefined ? 0 : Buffer.byteLength(value)), 0);
61
+ }
62
+
63
+ function parseStoredMessage(row: Record<string, unknown> | undefined): DeliveredMessage | undefined | "invalid" {
64
+ if (row === undefined) return undefined;
65
+ if (
66
+ (row.state !== "reserved" && row.state !== "accepted") ||
67
+ !validStoredString(row.signature) ||
68
+ !AUTHORITY_DIGEST_PATTERN.test(row.signature) ||
69
+ typeof row.delivered_at !== "number" ||
70
+ !Number.isSafeInteger(row.delivered_at) ||
71
+ row.delivered_at < 0 ||
72
+ (row.target_identity !== null && !validStoredString(row.target_identity))
73
+ ) {
74
+ return "invalid";
75
+ }
76
+ const questionValues = [row.question_target_session_id, row.question_sender_group_identity];
77
+ const hasQuestionRoute = questionValues.some((value) => value !== null);
78
+ if (hasQuestionRoute && !questionValues.every(validStoredString)) return "invalid";
79
+ return {
80
+ state: row.state,
81
+ deliveredAt: row.delivered_at,
82
+ signature: row.signature,
83
+ ...(typeof row.target_identity === "string" ? { targetIdentity: row.target_identity } : {}),
84
+ ...(hasQuestionRoute
85
+ ? {
86
+ questionRoute: {
87
+ targetSessionId: row.question_target_session_id as string,
88
+ senderGroupIdentity: row.question_sender_group_identity as string,
89
+ },
90
+ }
91
+ : {}),
92
+ };
93
+ }
94
+
95
+ /** Authority-key path derived without introducing another user setting. */
96
+ export function getDeliveredMessageAuthorityKeyPath(storagePath: string): string {
97
+ return storagePath.endsWith(".sqlite") ? `${storagePath.slice(0, -".sqlite".length)}.key` : `${storagePath}.key`;
98
+ }
99
+
100
+ function restrictMode(path: string, mode: number): void {
101
+ if (process.platform !== "win32") chmodSync(path, mode);
102
+ }
103
+
104
+ function restrictExistingAuthorityArtifacts(storagePath: string, keyPath: string): void {
105
+ for (const path of [storagePath, `${storagePath}-wal`, `${storagePath}-shm`, keyPath]) {
106
+ if (existsSync(path)) restrictMode(path, 0o600);
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Prepare a paired database and key. A missing half of an existing pair is not
112
+ * recreated: accepted authority may have been lost, so startup must fail closed.
113
+ */
114
+ function prepareDurableAuthority(storagePath: string): Buffer | undefined {
115
+ const directory = dirname(storagePath);
116
+ const keyPath = getDeliveredMessageAuthorityKeyPath(storagePath);
117
+ mkdirSync(directory, { recursive: true, mode: 0o700 });
118
+ restrictMode(directory, 0o700);
119
+ restrictExistingAuthorityArtifacts(storagePath, keyPath);
120
+ const databaseExists = existsSync(storagePath);
121
+ const keyExists = existsSync(keyPath);
122
+ if (databaseExists !== keyExists) return undefined;
123
+ if (!databaseExists) {
124
+ const key = randomBytes(AUTHORITY_KEY_BYTES);
125
+ writeFileSync(keyPath, key, { flag: "wx", mode: 0o600 });
126
+ const databaseDescriptor = openSync(storagePath, "wx", 0o600);
127
+ closeSync(databaseDescriptor);
128
+ restrictExistingAuthorityArtifacts(storagePath, keyPath);
129
+ return key;
130
+ }
131
+ const key = readFileSync(keyPath);
132
+ if (key.length !== AUTHORITY_KEY_BYTES) return undefined;
133
+ return key;
134
+ }
135
+
136
+ /**
137
+ * Bounded durable operation authority. The broker uses a SQLite-backed instance;
138
+ * tests may omit `storagePath` for an isolated in-memory authority. Durable
139
+ * signatures are keyed SHA-256 HMACs, so message and attachment content never
140
+ * reaches SQLite and low-entropy payloads cannot be tested without the paired
141
+ * owner-only key file. A reservation is written before forwarding and promoted
142
+ * to accepted after a confirmed write.
143
+ */
12
144
  export class DeliveredMessageCache {
13
- private readonly delivered = new Map<string, DeliveredMessage>();
14
-
15
- constructor(
16
- private readonly ttlMs = DEFAULT_TTL_MS,
17
- private readonly maxEntries = DEFAULT_MAX_ENTRIES,
18
- ) {}
19
-
20
- lookup(messageId: string, signature: string, now = Date.now()): DeliveredMessageMatch {
21
- this.prune(now);
22
- const delivered = this.delivered.get(messageId);
23
- if (!delivered || now - delivered.deliveredAt > this.ttlMs) return "miss";
24
- return delivered.signature === signature ? "match" : "conflict";
25
- }
26
-
27
- record(messageId: string, signature: string, now = Date.now()): void {
28
- this.prune(now);
29
- this.delivered.delete(messageId);
30
- this.delivered.set(messageId, { deliveredAt: now, signature });
31
- while (this.delivered.size > this.maxEntries) {
32
- const oldest = this.delivered.keys().next().value as string | undefined;
33
- if (oldest === undefined) break;
34
- this.delivered.delete(oldest);
35
- }
36
- }
37
-
38
- private prune(now: number): void {
39
- for (const [messageId, delivered] of this.delivered) {
40
- if (now - delivered.deliveredAt <= this.ttlMs) break;
41
- this.delivered.delete(messageId);
42
- }
43
- }
145
+ private readonly delivered = new Map<string, DeliveredMessage>();
146
+ private retainedBytes = 0;
147
+ private readonly database?: SqliteDatabase;
148
+ private readonly authorityKey?: Buffer;
149
+ private readonly storagePath?: string;
150
+ private storageInvalid = false;
151
+
152
+ constructor(
153
+ private readonly ttlMs = DELIVERED_MESSAGE_TTL_MS,
154
+ private readonly maxEntries = DELIVERED_MESSAGE_MAX_ENTRIES,
155
+ storagePath?: string,
156
+ private readonly maxBytes = DELIVERED_MESSAGE_MAX_BYTES,
157
+ ) {
158
+ if (storagePath === undefined) return;
159
+ this.storagePath = storagePath;
160
+ let database: SqliteDatabase | undefined;
161
+ try {
162
+ const authorityKey = prepareDurableAuthority(storagePath);
163
+ if (authorityKey === undefined) {
164
+ this.storageInvalid = true;
165
+ return;
166
+ }
167
+ this.authorityKey = authorityKey;
168
+ database = new DatabaseSync(storagePath) as unknown as SqliteDatabase;
169
+ database.exec("PRAGMA busy_timeout = 5000");
170
+ database.exec("PRAGMA journal_mode = WAL");
171
+ database.exec("PRAGMA synchronous = FULL");
172
+ database.exec("PRAGMA trusted_schema = OFF");
173
+ database.exec(`
174
+ CREATE TABLE IF NOT EXISTS delivered_messages (
175
+ state TEXT NOT NULL CHECK (state IN ('reserved', 'accepted')),
176
+ message_id TEXT PRIMARY KEY NOT NULL,
177
+ signature TEXT NOT NULL,
178
+ delivered_at INTEGER NOT NULL,
179
+ target_identity TEXT,
180
+ question_target_session_id TEXT,
181
+ question_sender_group_identity TEXT
182
+ ) STRICT;
183
+ CREATE INDEX IF NOT EXISTS delivered_messages_age
184
+ ON delivered_messages(delivered_at);
185
+ `);
186
+ database.prepare("SELECT state, signature, delivered_at, target_identity FROM delivered_messages LIMIT 0").get();
187
+ restrictExistingAuthorityArtifacts(storagePath, getDeliveredMessageAuthorityKeyPath(storagePath));
188
+ } catch {
189
+ database?.close();
190
+ try {
191
+ restrictExistingAuthorityArtifacts(storagePath, getDeliveredMessageAuthorityKeyPath(storagePath));
192
+ } catch {
193
+ // Storage is already invalid; permission correction is best-effort here.
194
+ }
195
+ this.storageInvalid = true;
196
+ return;
197
+ }
198
+ this.database = database;
199
+ }
200
+
201
+ lookup(messageId: string, signature: string, now = Date.now()): DeliveredMessageMatch {
202
+ const authority = this.signatureAuthority(signature);
203
+ return authority === undefined ? "invalid" : this.lookupEntry(messageId, authority, undefined, false, now);
204
+ }
205
+
206
+ lookupForTarget(
207
+ messageId: string,
208
+ signature: string,
209
+ targetIdentity: string,
210
+ now = Date.now(),
211
+ ): DeliveredMessageMatch {
212
+ const authority = this.signatureAuthority(signature);
213
+ return authority === undefined ? "invalid" : this.lookupEntry(messageId, authority, targetIdentity, true, now);
214
+ }
215
+
216
+ lookupQuestionTarget(
217
+ messageId: string,
218
+ signature: string,
219
+ senderGroupIdentity: string,
220
+ now = Date.now(),
221
+ ): string | undefined {
222
+ const authority = this.signatureAuthority(signature);
223
+ if (authority === undefined) return undefined;
224
+ this.prune(now);
225
+ const delivered = this.read(messageId);
226
+ if (
227
+ delivered === undefined ||
228
+ delivered === "invalid" ||
229
+ delivered.state !== "accepted" ||
230
+ now - delivered.deliveredAt > this.ttlMs ||
231
+ delivered.signature !== authority ||
232
+ delivered.questionRoute?.senderGroupIdentity !== senderGroupIdentity
233
+ ) {
234
+ return undefined;
235
+ }
236
+ return delivered.questionRoute.targetSessionId;
237
+ }
238
+
239
+ record(
240
+ messageId: string,
241
+ signature: string,
242
+ now = Date.now(),
243
+ targetIdentity?: string,
244
+ ): DeliveredMessageRecordResult {
245
+ return this.recordWithSignature(messageId, { state: "accepted", deliveredAt: now, signature, targetIdentity });
246
+ }
247
+
248
+ recordQuestion(
249
+ messageId: string,
250
+ signature: string,
251
+ questionRoute: DeliveredQuestionRoute,
252
+ now = Date.now(),
253
+ targetIdentity?: string,
254
+ ): DeliveredMessageRecordResult {
255
+ return this.recordWithSignature(messageId, {
256
+ state: "accepted",
257
+ deliveredAt: now,
258
+ signature,
259
+ targetIdentity,
260
+ questionRoute,
261
+ });
262
+ }
263
+
264
+ reserve(
265
+ messageId: string,
266
+ signature: string,
267
+ now = Date.now(),
268
+ targetIdentity?: string,
269
+ ): DeliveredMessageRecordResult {
270
+ return this.recordWithSignature(messageId, { state: "reserved", deliveredAt: now, signature, targetIdentity });
271
+ }
272
+
273
+ reserveQuestion(
274
+ messageId: string,
275
+ signature: string,
276
+ questionRoute: DeliveredQuestionRoute,
277
+ now = Date.now(),
278
+ targetIdentity?: string,
279
+ ): DeliveredMessageRecordResult {
280
+ return this.recordWithSignature(messageId, {
281
+ state: "reserved",
282
+ deliveredAt: now,
283
+ signature,
284
+ targetIdentity,
285
+ questionRoute,
286
+ });
287
+ }
288
+
289
+ accept(messageId: string, signature: string, targetIdentity?: string): DeliveredMessageAcceptResult {
290
+ const authority = this.signatureAuthority(signature);
291
+ if (authority === undefined) return "invalid";
292
+ const existing = this.read(messageId);
293
+ if (existing === undefined || existing === "invalid") return "invalid";
294
+ if (existing.signature !== authority || existing.targetIdentity !== targetIdentity) return "conflict";
295
+ if (existing.state === "accepted") return "accepted";
296
+ if (this.database === undefined) {
297
+ existing.state = "accepted";
298
+ return "accepted";
299
+ }
300
+ const updated = this.database
301
+ .prepare("UPDATE delivered_messages SET state = 'accepted' WHERE message_id = ? AND signature = ?")
302
+ .run(messageId, authority);
303
+ this.restrictArtifacts();
304
+ return Number(updated.changes) === 1 ? "accepted" : "invalid";
305
+ }
306
+
307
+ /** Remove only the exact pre-forward reservation after a proven write failure. */
308
+ forget(messageId: string, signature: string): void {
309
+ const authority = this.signatureAuthority(signature);
310
+ if (authority === undefined) return;
311
+ if (this.database === undefined) {
312
+ const delivered = this.delivered.get(messageId);
313
+ if (delivered?.signature === authority) {
314
+ this.retainedBytes -= entryByteSize(messageId, delivered);
315
+ this.delivered.delete(messageId);
316
+ }
317
+ return;
318
+ }
319
+ this.database
320
+ .prepare("DELETE FROM delivered_messages WHERE message_id = ? AND signature = ?")
321
+ .run(messageId, authority);
322
+ this.restrictArtifacts();
323
+ }
324
+
325
+ close(): void {
326
+ this.restrictArtifacts();
327
+ this.database?.close();
328
+ this.restrictArtifacts();
329
+ }
330
+
331
+ private signatureAuthority(signature: string): string | undefined {
332
+ if (this.storageInvalid || !validStoredString(signature)) return undefined;
333
+ if (this.storagePath === undefined) return signature;
334
+ if (this.authorityKey === undefined) return undefined;
335
+ return createHmac("sha256", this.authorityKey).update(signature).digest("hex");
336
+ }
337
+
338
+ private recordWithSignature(messageId: string, delivered: DeliveredMessage): DeliveredMessageRecordResult {
339
+ const authority = this.signatureAuthority(delivered.signature);
340
+ if (authority === undefined) return "invalid";
341
+ return this.recordEntry(messageId, { ...delivered, signature: authority });
342
+ }
343
+
344
+ private lookupEntry(
345
+ messageId: string,
346
+ signature: string,
347
+ targetIdentity: string | undefined,
348
+ requireTargetIdentity: boolean,
349
+ now: number,
350
+ ): DeliveredMessageMatch {
351
+ if (this.storageInvalid) return "invalid";
352
+ this.prune(now);
353
+ const delivered = this.read(messageId);
354
+ if (delivered === "invalid") return "invalid";
355
+ if (delivered === undefined || now - delivered.deliveredAt > this.ttlMs) return "miss";
356
+ if (delivered.signature !== signature) return "conflict";
357
+ if (requireTargetIdentity && delivered.targetIdentity !== targetIdentity) return "conflict";
358
+ if (delivered.state === "reserved") return "uncertain";
359
+ return "match";
360
+ }
361
+
362
+ private recordEntry(messageId: string, delivered: DeliveredMessage): DeliveredMessageRecordResult {
363
+ if (this.storageInvalid) return "invalid";
364
+ if (!validStoredString(messageId) || !validStoredString(delivered.signature)) return "invalid";
365
+ if (
366
+ !Number.isSafeInteger(delivered.deliveredAt) ||
367
+ delivered.deliveredAt < 0 ||
368
+ (delivered.targetIdentity !== undefined && !validStoredString(delivered.targetIdentity)) ||
369
+ (delivered.questionRoute !== undefined &&
370
+ (!validStoredString(delivered.questionRoute.targetSessionId) ||
371
+ !validStoredString(delivered.questionRoute.senderGroupIdentity)))
372
+ ) {
373
+ return "invalid";
374
+ }
375
+ if (entryByteSize(messageId, delivered) > this.maxBytes) return "capacity";
376
+ if (this.database === undefined) return this.recordMemory(messageId, delivered);
377
+ return this.recordDurable(messageId, delivered);
378
+ }
379
+
380
+ private recordMemory(messageId: string, delivered: DeliveredMessage): DeliveredMessageRecordResult {
381
+ this.pruneMemory(delivered.deliveredAt);
382
+ const existing = this.delivered.get(messageId);
383
+ if (existing !== undefined) return this.compare(existing, delivered);
384
+ const size = entryByteSize(messageId, delivered);
385
+ if (this.delivered.size >= this.maxEntries || this.retainedBytes + size > this.maxBytes) return "capacity";
386
+ this.delivered.set(messageId, delivered);
387
+ this.retainedBytes += size;
388
+ return "recorded";
389
+ }
390
+
391
+ private recordDurable(messageId: string, delivered: DeliveredMessage): DeliveredMessageRecordResult {
392
+ const database = this.database;
393
+ if (database === undefined) return "invalid";
394
+ database.exec("BEGIN IMMEDIATE");
395
+ try {
396
+ this.pruneDurable(delivered.deliveredAt);
397
+ const existing = this.readDurable(messageId);
398
+ if (existing !== undefined) {
399
+ database.exec("COMMIT");
400
+ return existing === "invalid" ? "invalid" : this.compare(existing, delivered);
401
+ }
402
+ const totals = database.prepare(`
403
+ SELECT COUNT(*) AS count,
404
+ COALESCE(SUM(
405
+ length(CAST(message_id AS BLOB)) + length(CAST(signature AS BLOB)) +
406
+ COALESCE(length(CAST(target_identity AS BLOB)), 0) +
407
+ COALESCE(length(CAST(question_target_session_id AS BLOB)), 0) +
408
+ COALESCE(length(CAST(question_sender_group_identity AS BLOB)), 0)
409
+ ), 0) AS bytes
410
+ FROM delivered_messages
411
+ `).get();
412
+ const count = totals?.count;
413
+ const bytes = totals?.bytes;
414
+ if (
415
+ typeof count !== "number" ||
416
+ !Number.isSafeInteger(count) ||
417
+ count < 0 ||
418
+ typeof bytes !== "number" ||
419
+ !Number.isSafeInteger(bytes) ||
420
+ bytes < 0
421
+ ) {
422
+ database.exec("COMMIT");
423
+ return "invalid";
424
+ }
425
+ if (count >= this.maxEntries || bytes + entryByteSize(messageId, delivered) > this.maxBytes) {
426
+ database.exec("COMMIT");
427
+ return "capacity";
428
+ }
429
+ database
430
+ .prepare(`
431
+ INSERT INTO delivered_messages (
432
+ message_id, state, signature, delivered_at, target_identity,
433
+ question_target_session_id, question_sender_group_identity
434
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
435
+ `)
436
+ .run(
437
+ messageId,
438
+ delivered.state,
439
+ delivered.signature,
440
+ delivered.deliveredAt,
441
+ delivered.targetIdentity ?? null,
442
+ delivered.questionRoute?.targetSessionId ?? null,
443
+ delivered.questionRoute?.senderGroupIdentity ?? null,
444
+ );
445
+ database.exec("COMMIT");
446
+ this.restrictArtifacts();
447
+ return "recorded";
448
+ } catch (error) {
449
+ try {
450
+ database.exec("ROLLBACK");
451
+ } catch {
452
+ // Preserve the original storage failure.
453
+ }
454
+ throw error;
455
+ }
456
+ }
457
+
458
+ private compare(existing: DeliveredMessage, incoming: DeliveredMessage): DeliveredMessageRecordResult {
459
+ if (existing.signature !== incoming.signature || existing.targetIdentity !== incoming.targetIdentity) {
460
+ return "conflict";
461
+ }
462
+ return existing.state === "accepted" ? "match" : "uncertain";
463
+ }
464
+
465
+ private read(messageId: string): DeliveredMessage | undefined | "invalid" {
466
+ return this.database === undefined ? this.delivered.get(messageId) : this.readDurable(messageId);
467
+ }
468
+
469
+ private readDurable(messageId: string): DeliveredMessage | undefined | "invalid" {
470
+ const row = this.database
471
+ ?.prepare(`
472
+ SELECT state, signature, delivered_at, target_identity,
473
+ question_target_session_id, question_sender_group_identity
474
+ FROM delivered_messages WHERE message_id = ?
475
+ `)
476
+ .get(messageId);
477
+ return parseStoredMessage(row);
478
+ }
479
+
480
+ private prune(now: number): void {
481
+ if (this.database === undefined) this.pruneMemory(now);
482
+ else this.pruneDurable(now);
483
+ }
484
+
485
+ private pruneMemory(now: number): void {
486
+ for (const [messageId, delivered] of this.delivered) {
487
+ if (now - delivered.deliveredAt <= this.ttlMs) continue;
488
+ this.delivered.delete(messageId);
489
+ this.retainedBytes -= entryByteSize(messageId, delivered);
490
+ }
491
+ }
492
+
493
+ private pruneDurable(now: number): void {
494
+ this.database
495
+ ?.prepare("DELETE FROM delivered_messages WHERE typeof(delivered_at) = 'integer' AND ? - delivered_at > ?")
496
+ .run(now, this.ttlMs);
497
+ this.restrictArtifacts();
498
+ }
499
+
500
+ private restrictArtifacts(): void {
501
+ if (this.storagePath === undefined || this.storageInvalid) return;
502
+ restrictExistingAuthorityArtifacts(this.storagePath, getDeliveredMessageAuthorityKeyPath(this.storagePath));
503
+ }
44
504
  }
@@ -4,12 +4,14 @@ import type { Socket } from "net";
4
4
  * Write a length-prefixed message to a socket.
5
5
  * Format: 4-byte big-endian length + JSON payload
6
6
  */
7
- export function writeMessage(socket: Socket, msg: unknown): void {
7
+ export function writeMessage(socket: Socket, msg: unknown, callback?: (error?: Error | null) => void): void {
8
8
  const json = JSON.stringify(msg);
9
9
  const payload = Buffer.from(json, "utf-8");
10
10
  const header = Buffer.alloc(4);
11
11
  header.writeUInt32BE(payload.length, 0);
12
- socket.write(Buffer.concat([header, payload]));
12
+ const frame = Buffer.concat([header, payload]);
13
+ if (callback === undefined) socket.write(frame);
14
+ else socket.write(frame, callback);
13
15
  }
14
16
 
15
17
  /**
@@ -46,6 +46,16 @@ export function getBrokerSpawnLockPath(agentDir: string = getAgentDir()): string
46
46
  return join(getIntercomDirPath(agentDir), "broker.spawn.lock");
47
47
  }
48
48
 
49
+ /** Durable accepted-operation authority shared by replacement broker processes. */
50
+ export function getBrokerDeliveredMessagesPath(agentDir: string = getAgentDir()): string {
51
+ return join(getIntercomDirPath(agentDir), "delivered-messages.sqlite");
52
+ }
53
+
54
+ /** Owner-only HMAC key paired with durable accepted-operation authority. */
55
+ export function getBrokerDeliveredMessagesKeyPath(agentDir: string = getAgentDir()): string {
56
+ return join(getIntercomDirPath(agentDir), "delivered-messages.key");
57
+ }
58
+
49
59
  /**
50
60
  * Startup/diagnostic log for the detached broker process. The parent opens this file
51
61
  * and hands the descriptor to the child as stderr, so a broker that dies before it can
@@ -12,8 +12,7 @@ export interface SendResultLike {
12
12
  delivered: boolean;
13
13
  reason?: string;
14
14
  queued?: boolean;
15
- runId?: string;
16
- stageKey?: string;
15
+ target?: string;
17
16
  position?: number;
18
17
  }
19
18