maestro-flow 0.3.1 → 0.3.3

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 (574) hide show
  1. package/.claude/CLAUDE.md +2 -2
  2. package/.claude/agents/cli-explore-agent.md +1 -1
  3. package/.claude/agents/team-worker.md +237 -237
  4. package/.claude/commands/maestro-coordinate.md +65 -65
  5. package/.claude/commands/maestro-link-coordinate.md +71 -71
  6. package/.claude/commands/maestro-overlay.md +178 -122
  7. package/.claude/commands/manage-issue-execute.md +73 -73
  8. package/.claude/skills/team-coordinate/SKILL.md +266 -266
  9. package/.claude/skills/team-lifecycle-v4/SKILL.md +209 -209
  10. package/.claude/skills/team-lifecycle-v4/roles/analyst/role.md +94 -94
  11. package/.claude/skills/team-lifecycle-v4/roles/executor/commands/implement.md +62 -62
  12. package/.claude/skills/team-lifecycle-v4/roles/planner/role.md +85 -85
  13. package/.claude/skills/team-lifecycle-v4/roles/writer/role.md +95 -95
  14. package/.claude/skills/team-quality-assurance/SKILL.md +147 -147
  15. package/.claude/skills/team-quality-assurance/roles/scout/role.md +75 -75
  16. package/.claude/skills/team-review/SKILL.md +147 -147
  17. package/.claude/skills/team-review/roles/reviewer/role.md +68 -68
  18. package/.claude/skills/team-review/roles/scanner/role.md +79 -79
  19. package/.claude/skills/team-tech-debt/SKILL.md +128 -128
  20. package/.claude/skills/team-tech-debt/roles/executor/role.md +76 -76
  21. package/.claude/skills/team-tech-debt/roles/scanner/role.md +90 -90
  22. package/.claude/skills/team-tech-debt/roles/validator/role.md +78 -78
  23. package/.claude/skills/team-testing/SKILL.md +143 -143
  24. package/.claude/skills/team-testing/roles/executor/role.md +99 -99
  25. package/.claude/skills/team-testing/roles/generator/role.md +98 -98
  26. package/.codex/skills/maestro-coordinate/SKILL.md +4 -5
  27. package/.codex/skills/manage-issue-analyze/SKILL.md +3 -3
  28. package/.codex/skills/manage-issue-execute/SKILL.md +4 -4
  29. package/.codex/skills/manage-issue-plan/SKILL.md +2 -2
  30. package/.codex/skills/team-coordinate/SKILL.md +7 -7
  31. package/.codex/skills/team-coordinate/roles/coordinator/role.md +1 -1
  32. package/.codex/skills/team-lifecycle-v4/SKILL.md +2 -2
  33. package/.codex/skills/team-lifecycle-v4/instructions/agent-instruction.md +2 -2
  34. package/.codex/skills/team-lifecycle-v4/roles/analyst/role.md +2 -2
  35. package/.codex/skills/team-lifecycle-v4/roles/coordinator/role.md +2 -2
  36. package/.codex/skills/team-lifecycle-v4/roles/executor/commands/implement.md +1 -1
  37. package/.codex/skills/team-lifecycle-v4/roles/planner/role.md +2 -2
  38. package/.codex/skills/team-lifecycle-v4/roles/writer/role.md +1 -1
  39. package/.codex/skills/team-quality-assurance/SKILL.md +2 -2
  40. package/.codex/skills/team-quality-assurance/roles/coordinator/role.md +2 -2
  41. package/.codex/skills/team-quality-assurance/roles/scout/role.md +2 -2
  42. package/.codex/skills/team-review/SKILL.md +2 -2
  43. package/.codex/skills/team-review/roles/coordinator/role.md +2 -2
  44. package/.codex/skills/team-review/roles/reviewer/role.md +1 -1
  45. package/.codex/skills/team-review/roles/scanner/role.md +1 -1
  46. package/.codex/skills/team-tech-debt/SKILL.md +2 -2
  47. package/.codex/skills/team-tech-debt/roles/coordinator/role.md +1 -1
  48. package/.codex/skills/team-tech-debt/roles/executor/role.md +1 -1
  49. package/.codex/skills/team-tech-debt/roles/scanner/role.md +1 -1
  50. package/.codex/skills/team-tech-debt/roles/validator/role.md +1 -1
  51. package/.codex/skills/team-testing/SKILL.md +2 -2
  52. package/.codex/skills/team-testing/roles/coordinator/role.md +2 -2
  53. package/.codex/skills/team-testing/roles/executor/role.md +1 -1
  54. package/.codex/skills/team-testing/roles/generator/role.md +1 -1
  55. package/README.md +31 -2
  56. package/README.zh-CN.md +23 -1
  57. package/dist/src/agents/cli-agent-runner.d.ts.map +1 -1
  58. package/dist/src/agents/cli-agent-runner.js +6 -15
  59. package/dist/src/agents/cli-agent-runner.js.map +1 -1
  60. package/dist/src/commands/delegate.d.ts.map +1 -1
  61. package/dist/src/commands/delegate.js +77 -1
  62. package/dist/src/commands/delegate.js.map +1 -1
  63. package/dist/src/commands/hooks.d.ts +15 -0
  64. package/dist/src/commands/hooks.d.ts.map +1 -1
  65. package/dist/src/commands/hooks.js +29 -2
  66. package/dist/src/commands/hooks.js.map +1 -1
  67. package/dist/src/commands/install-backend.d.ts +15 -0
  68. package/dist/src/commands/install-backend.d.ts.map +1 -1
  69. package/dist/src/commands/install-backend.js +67 -0
  70. package/dist/src/commands/install-backend.js.map +1 -1
  71. package/dist/src/commands/install-ui/BackupConfig.d.ts +6 -4
  72. package/dist/src/commands/install-ui/BackupConfig.d.ts.map +1 -1
  73. package/dist/src/commands/install-ui/BackupConfig.js +39 -12
  74. package/dist/src/commands/install-ui/BackupConfig.js.map +1 -1
  75. package/dist/src/commands/install-ui/ConfigPanel.d.ts.map +1 -1
  76. package/dist/src/commands/install-ui/ConfigPanel.js +1 -1
  77. package/dist/src/commands/install-ui/ConfigPanel.js.map +1 -1
  78. package/dist/src/commands/install-ui/InstallConfirm.d.ts +3 -0
  79. package/dist/src/commands/install-ui/InstallConfirm.d.ts.map +1 -1
  80. package/dist/src/commands/install-ui/InstallConfirm.js +5 -1
  81. package/dist/src/commands/install-ui/InstallConfirm.js.map +1 -1
  82. package/dist/src/commands/install-ui/InstallExecution.d.ts +2 -0
  83. package/dist/src/commands/install-ui/InstallExecution.d.ts.map +1 -1
  84. package/dist/src/commands/install-ui/InstallExecution.js +30 -5
  85. package/dist/src/commands/install-ui/InstallExecution.js.map +1 -1
  86. package/dist/src/commands/install-ui/InstallFlow.d.ts +1 -1
  87. package/dist/src/commands/install-ui/InstallFlow.d.ts.map +1 -1
  88. package/dist/src/commands/install-ui/InstallFlow.js +31 -6
  89. package/dist/src/commands/install-ui/InstallFlow.js.map +1 -1
  90. package/dist/src/commands/install-ui/InstallHub.d.ts +5 -0
  91. package/dist/src/commands/install-ui/InstallHub.d.ts.map +1 -1
  92. package/dist/src/commands/install-ui/InstallHub.js +24 -0
  93. package/dist/src/commands/install-ui/InstallHub.js.map +1 -1
  94. package/dist/src/commands/install-ui/InstallResult.d.ts.map +1 -1
  95. package/dist/src/commands/install-ui/InstallResult.js +1 -1
  96. package/dist/src/commands/install-ui/InstallResult.js.map +1 -1
  97. package/dist/src/commands/install-ui/StatuslineConfig.d.ts +9 -0
  98. package/dist/src/commands/install-ui/StatuslineConfig.d.ts.map +1 -0
  99. package/dist/src/commands/install-ui/StatuslineConfig.js +13 -0
  100. package/dist/src/commands/install-ui/StatuslineConfig.js.map +1 -0
  101. package/dist/src/commands/install-ui/index.d.ts +1 -1
  102. package/dist/src/commands/install-ui/index.d.ts.map +1 -1
  103. package/dist/src/commands/install-ui/types.d.ts +6 -0
  104. package/dist/src/commands/install-ui/types.d.ts.map +1 -1
  105. package/dist/src/commands/install-ui/types.js +3 -0
  106. package/dist/src/commands/install-ui/types.js.map +1 -1
  107. package/dist/src/commands/install.d.ts.map +1 -1
  108. package/dist/src/commands/install.js +6 -1
  109. package/dist/src/commands/install.js.map +1 -1
  110. package/dist/src/commands/launcher.js +1 -1
  111. package/dist/src/commands/launcher.js.map +1 -1
  112. package/dist/src/commands/overlay-ui/OverlayList.d.ts +35 -0
  113. package/dist/src/commands/overlay-ui/OverlayList.d.ts.map +1 -0
  114. package/dist/src/commands/overlay-ui/OverlayList.js +143 -0
  115. package/dist/src/commands/overlay-ui/OverlayList.js.map +1 -0
  116. package/dist/src/commands/overlay-ui/index.d.ts +2 -0
  117. package/dist/src/commands/overlay-ui/index.d.ts.map +1 -0
  118. package/dist/src/commands/overlay-ui/index.js +188 -0
  119. package/dist/src/commands/overlay-ui/index.js.map +1 -0
  120. package/dist/src/commands/overlay.d.ts.map +1 -1
  121. package/dist/src/commands/overlay.js +124 -60
  122. package/dist/src/commands/overlay.js.map +1 -1
  123. package/dist/src/commands/team.d.ts +10 -0
  124. package/dist/src/commands/team.d.ts.map +1 -1
  125. package/dist/src/commands/team.js +436 -42
  126. package/dist/src/commands/team.js.map +1 -1
  127. package/dist/src/core/manifest.d.ts.map +1 -1
  128. package/dist/src/core/manifest.js +58 -0
  129. package/dist/src/core/manifest.js.map +1 -1
  130. package/dist/src/core/overlay/applier.d.ts +36 -1
  131. package/dist/src/core/overlay/applier.d.ts.map +1 -1
  132. package/dist/src/core/overlay/applier.js +109 -1
  133. package/dist/src/core/overlay/applier.js.map +1 -1
  134. package/dist/src/hooks/delegate-monitor.js +1 -1
  135. package/dist/src/hooks/delegate-monitor.js.map +1 -1
  136. package/dist/src/hooks/plugins/spec-injection-plugin.d.ts.map +1 -1
  137. package/dist/src/hooks/plugins/spec-injection-plugin.js +17 -1
  138. package/dist/src/hooks/plugins/spec-injection-plugin.js.map +1 -1
  139. package/dist/src/hooks/spec-injector.d.ts +2 -1
  140. package/dist/src/hooks/spec-injector.d.ts.map +1 -1
  141. package/dist/src/hooks/spec-injector.js +19 -2
  142. package/dist/src/hooks/spec-injector.js.map +1 -1
  143. package/dist/src/hooks/team-monitor.d.ts.map +1 -1
  144. package/dist/src/hooks/team-monitor.js +17 -0
  145. package/dist/src/hooks/team-monitor.js.map +1 -1
  146. package/dist/src/i18n/locales/en.d.ts.map +1 -1
  147. package/dist/src/i18n/locales/en.js +25 -1
  148. package/dist/src/i18n/locales/en.js.map +1 -1
  149. package/dist/src/i18n/locales/zh.d.ts.map +1 -1
  150. package/dist/src/i18n/locales/zh.js +25 -1
  151. package/dist/src/i18n/locales/zh.js.map +1 -1
  152. package/dist/src/i18n/types.d.ts +22 -0
  153. package/dist/src/i18n/types.d.ts.map +1 -1
  154. package/dist/src/mcp/delegate-channel-relay.d.ts.map +1 -1
  155. package/dist/src/mcp/delegate-channel-relay.js +2 -7
  156. package/dist/src/mcp/delegate-channel-relay.js.map +1 -1
  157. package/dist/src/tools/namespace-guard.d.ts +37 -0
  158. package/dist/src/tools/namespace-guard.d.ts.map +1 -0
  159. package/dist/src/tools/namespace-guard.js +126 -0
  160. package/dist/src/tools/namespace-guard.js.map +1 -0
  161. package/dist/src/tools/spec-loader.d.ts +17 -1
  162. package/dist/src/tools/spec-loader.d.ts.map +1 -1
  163. package/dist/src/tools/spec-loader.js +71 -13
  164. package/dist/src/tools/spec-loader.js.map +1 -1
  165. package/dist/src/tools/team-members.d.ts +16 -0
  166. package/dist/src/tools/team-members.d.ts.map +1 -1
  167. package/dist/src/tools/team-members.js +31 -0
  168. package/dist/src/tools/team-members.js.map +1 -1
  169. package/package.json +1 -1
  170. package/workflows/delegate-usage.md +330 -0
  171. package/dist/agents/cli-agent-runner.d.ts +0 -131
  172. package/dist/agents/cli-agent-runner.d.ts.map +0 -1
  173. package/dist/agents/cli-agent-runner.js +0 -688
  174. package/dist/agents/cli-agent-runner.js.map +0 -1
  175. package/dist/agents/cli-history-store.d.ts +0 -63
  176. package/dist/agents/cli-history-store.d.ts.map +0 -1
  177. package/dist/agents/cli-history-store.js +0 -242
  178. package/dist/agents/cli-history-store.js.map +0 -1
  179. package/dist/agents/dashboard-bridge.d.ts +0 -39
  180. package/dist/agents/dashboard-bridge.d.ts.map +0 -1
  181. package/dist/agents/dashboard-bridge.js +0 -76
  182. package/dist/agents/dashboard-bridge.js.map +0 -1
  183. package/dist/agents/parallel-cli-runner.d.ts +0 -46
  184. package/dist/agents/parallel-cli-runner.d.ts.map +0 -1
  185. package/dist/agents/parallel-cli-runner.js +0 -277
  186. package/dist/agents/parallel-cli-runner.js.map +0 -1
  187. package/dist/agents/terminal-adapter.d.ts +0 -94
  188. package/dist/agents/terminal-adapter.d.ts.map +0 -1
  189. package/dist/agents/terminal-adapter.js +0 -132
  190. package/dist/agents/terminal-adapter.js.map +0 -1
  191. package/dist/agents/terminal-backend.d.ts +0 -53
  192. package/dist/agents/terminal-backend.d.ts.map +0 -1
  193. package/dist/agents/terminal-backend.js +0 -286
  194. package/dist/agents/terminal-backend.js.map +0 -1
  195. package/dist/async/delegate-broker-client.d.ts +0 -22
  196. package/dist/async/delegate-broker-client.d.ts.map +0 -1
  197. package/dist/async/delegate-broker-client.js +0 -47
  198. package/dist/async/delegate-broker-client.js.map +0 -1
  199. package/dist/async/delegate-broker.d.ts +0 -180
  200. package/dist/async/delegate-broker.d.ts.map +0 -1
  201. package/dist/async/delegate-broker.js +0 -1040
  202. package/dist/async/delegate-broker.js.map +0 -1
  203. package/dist/async/delegate-control.d.ts +0 -37
  204. package/dist/async/delegate-control.d.ts.map +0 -1
  205. package/dist/async/delegate-control.js +0 -155
  206. package/dist/async/delegate-control.js.map +0 -1
  207. package/dist/async/index.d.ts +0 -3
  208. package/dist/async/index.d.ts.map +0 -1
  209. package/dist/async/index.js +0 -3
  210. package/dist/async/index.js.map +0 -1
  211. package/dist/cli.d.ts +0 -2
  212. package/dist/cli.d.ts.map +0 -1
  213. package/dist/cli.js +0 -40
  214. package/dist/cli.js.map +0 -1
  215. package/dist/commands/cli.d.ts +0 -3
  216. package/dist/commands/cli.d.ts.map +0 -1
  217. package/dist/commands/cli.js +0 -262
  218. package/dist/commands/cli.js.map +0 -1
  219. package/dist/commands/coordinate.d.ts +0 -3
  220. package/dist/commands/coordinate.d.ts.map +0 -1
  221. package/dist/commands/coordinate.js +0 -275
  222. package/dist/commands/coordinate.js.map +0 -1
  223. package/dist/commands/delegate.d.ts +0 -37
  224. package/dist/commands/delegate.d.ts.map +0 -1
  225. package/dist/commands/delegate.js +0 -470
  226. package/dist/commands/delegate.js.map +0 -1
  227. package/dist/commands/ext.d.ts +0 -3
  228. package/dist/commands/ext.d.ts.map +0 -1
  229. package/dist/commands/ext.js +0 -28
  230. package/dist/commands/ext.js.map +0 -1
  231. package/dist/commands/hooks.d.ts +0 -3
  232. package/dist/commands/hooks.d.ts.map +0 -1
  233. package/dist/commands/hooks.js +0 -126
  234. package/dist/commands/hooks.js.map +0 -1
  235. package/dist/commands/install.d.ts +0 -3
  236. package/dist/commands/install.d.ts.map +0 -1
  237. package/dist/commands/install.js +0 -621
  238. package/dist/commands/install.js.map +0 -1
  239. package/dist/commands/launcher.d.ts +0 -3
  240. package/dist/commands/launcher.d.ts.map +0 -1
  241. package/dist/commands/launcher.js +0 -635
  242. package/dist/commands/launcher.js.map +0 -1
  243. package/dist/commands/link-coordinate.d.ts +0 -3
  244. package/dist/commands/link-coordinate.d.ts.map +0 -1
  245. package/dist/commands/link-coordinate.js +0 -225
  246. package/dist/commands/link-coordinate.js.map +0 -1
  247. package/dist/commands/msg.d.ts +0 -3
  248. package/dist/commands/msg.d.ts.map +0 -1
  249. package/dist/commands/msg.js +0 -110
  250. package/dist/commands/msg.js.map +0 -1
  251. package/dist/commands/overlay.d.ts +0 -3
  252. package/dist/commands/overlay.d.ts.map +0 -1
  253. package/dist/commands/overlay.js +0 -243
  254. package/dist/commands/overlay.js.map +0 -1
  255. package/dist/commands/run.d.ts +0 -3
  256. package/dist/commands/run.d.ts.map +0 -1
  257. package/dist/commands/run.js +0 -15
  258. package/dist/commands/run.js.map +0 -1
  259. package/dist/commands/serve.d.ts +0 -3
  260. package/dist/commands/serve.d.ts.map +0 -1
  261. package/dist/commands/serve.js +0 -16
  262. package/dist/commands/serve.js.map +0 -1
  263. package/dist/commands/spec.d.ts +0 -8
  264. package/dist/commands/spec.d.ts.map +0 -1
  265. package/dist/commands/spec.js +0 -147
  266. package/dist/commands/spec.js.map +0 -1
  267. package/dist/commands/stop.d.ts +0 -3
  268. package/dist/commands/stop.d.ts.map +0 -1
  269. package/dist/commands/stop.js +0 -218
  270. package/dist/commands/stop.js.map +0 -1
  271. package/dist/commands/tool.d.ts +0 -3
  272. package/dist/commands/tool.d.ts.map +0 -1
  273. package/dist/commands/tool.js +0 -29
  274. package/dist/commands/tool.js.map +0 -1
  275. package/dist/commands/uninstall.d.ts +0 -3
  276. package/dist/commands/uninstall.d.ts.map +0 -1
  277. package/dist/commands/uninstall.js +0 -77
  278. package/dist/commands/uninstall.js.map +0 -1
  279. package/dist/commands/view.d.ts +0 -3
  280. package/dist/commands/view.d.ts.map +0 -1
  281. package/dist/commands/view.js +0 -337
  282. package/dist/commands/view.js.map +0 -1
  283. package/dist/config/cli-tools-config.d.ts +0 -26
  284. package/dist/config/cli-tools-config.d.ts.map +0 -1
  285. package/dist/config/cli-tools-config.js +0 -49
  286. package/dist/config/cli-tools-config.js.map +0 -1
  287. package/dist/config/cli-tools-config.test.d.ts +0 -2
  288. package/dist/config/cli-tools-config.test.d.ts.map +0 -1
  289. package/dist/config/cli-tools-config.test.js +0 -59
  290. package/dist/config/cli-tools-config.test.js.map +0 -1
  291. package/dist/config/index.d.ts +0 -4
  292. package/dist/config/index.d.ts.map +0 -1
  293. package/dist/config/index.js +0 -27
  294. package/dist/config/index.js.map +0 -1
  295. package/dist/config/paths.d.ts +0 -15
  296. package/dist/config/paths.d.ts.map +0 -1
  297. package/dist/config/paths.js +0 -27
  298. package/dist/config/paths.js.map +0 -1
  299. package/dist/config/template-discovery.d.ts +0 -32
  300. package/dist/config/template-discovery.d.ts.map +0 -1
  301. package/dist/config/template-discovery.js +0 -128
  302. package/dist/config/template-discovery.js.map +0 -1
  303. package/dist/coordinator/cli-executor.d.ts +0 -22
  304. package/dist/coordinator/cli-executor.d.ts.map +0 -1
  305. package/dist/coordinator/cli-executor.js +0 -49
  306. package/dist/coordinator/cli-executor.js.map +0 -1
  307. package/dist/coordinator/expr-evaluator.d.ts +0 -11
  308. package/dist/coordinator/expr-evaluator.d.ts.map +0 -1
  309. package/dist/coordinator/expr-evaluator.js +0 -351
  310. package/dist/coordinator/expr-evaluator.js.map +0 -1
  311. package/dist/coordinator/graph-loader.d.ts +0 -16
  312. package/dist/coordinator/graph-loader.d.ts.map +0 -1
  313. package/dist/coordinator/graph-loader.js +0 -190
  314. package/dist/coordinator/graph-loader.js.map +0 -1
  315. package/dist/coordinator/graph-types.d.ts +0 -304
  316. package/dist/coordinator/graph-types.d.ts.map +0 -1
  317. package/dist/coordinator/graph-types.js +0 -6
  318. package/dist/coordinator/graph-types.js.map +0 -1
  319. package/dist/coordinator/graph-walker.d.ts +0 -51
  320. package/dist/coordinator/graph-walker.d.ts.map +0 -1
  321. package/dist/coordinator/graph-walker.js +0 -666
  322. package/dist/coordinator/graph-walker.js.map +0 -1
  323. package/dist/coordinator/index.d.ts +0 -13
  324. package/dist/coordinator/index.d.ts.map +0 -1
  325. package/dist/coordinator/index.js +0 -14
  326. package/dist/coordinator/index.js.map +0 -1
  327. package/dist/coordinator/intent-router.d.ts +0 -11
  328. package/dist/coordinator/intent-router.d.ts.map +0 -1
  329. package/dist/coordinator/intent-router.js +0 -65
  330. package/dist/coordinator/intent-router.js.map +0 -1
  331. package/dist/coordinator/link-session.d.ts +0 -29
  332. package/dist/coordinator/link-session.d.ts.map +0 -1
  333. package/dist/coordinator/link-session.js +0 -192
  334. package/dist/coordinator/link-session.js.map +0 -1
  335. package/dist/coordinator/link-walker.d.ts +0 -56
  336. package/dist/coordinator/link-walker.d.ts.map +0 -1
  337. package/dist/coordinator/link-walker.js +0 -548
  338. package/dist/coordinator/link-walker.js.map +0 -1
  339. package/dist/coordinator/output-parser.d.ts +0 -5
  340. package/dist/coordinator/output-parser.d.ts.map +0 -1
  341. package/dist/coordinator/output-parser.js +0 -114
  342. package/dist/coordinator/output-parser.js.map +0 -1
  343. package/dist/coordinator/parallel-executor.d.ts +0 -24
  344. package/dist/coordinator/parallel-executor.d.ts.map +0 -1
  345. package/dist/coordinator/parallel-executor.js +0 -43
  346. package/dist/coordinator/parallel-executor.js.map +0 -1
  347. package/dist/coordinator/prompt-assembler.d.ts +0 -15
  348. package/dist/coordinator/prompt-assembler.d.ts.map +0 -1
  349. package/dist/coordinator/prompt-assembler.js +0 -228
  350. package/dist/coordinator/prompt-assembler.js.map +0 -1
  351. package/dist/coordinator/step-analyzer.d.ts +0 -8
  352. package/dist/coordinator/step-analyzer.d.ts.map +0 -1
  353. package/dist/coordinator/step-analyzer.js +0 -82
  354. package/dist/coordinator/step-analyzer.js.map +0 -1
  355. package/dist/core/extension-loader.d.ts +0 -11
  356. package/dist/core/extension-loader.d.ts.map +0 -1
  357. package/dist/core/extension-loader.js +0 -54
  358. package/dist/core/extension-loader.js.map +0 -1
  359. package/dist/core/manifest.d.ts +0 -24
  360. package/dist/core/manifest.d.ts.map +0 -1
  361. package/dist/core/manifest.js +0 -139
  362. package/dist/core/manifest.js.map +0 -1
  363. package/dist/core/mcp-tool-registry.integration.test.d.ts +0 -2
  364. package/dist/core/mcp-tool-registry.integration.test.d.ts.map +0 -1
  365. package/dist/core/mcp-tool-registry.integration.test.js +0 -220
  366. package/dist/core/mcp-tool-registry.integration.test.js.map +0 -1
  367. package/dist/core/overlay/applier.d.ts +0 -73
  368. package/dist/core/overlay/applier.d.ts.map +0 -1
  369. package/dist/core/overlay/applier.js +0 -248
  370. package/dist/core/overlay/applier.js.map +0 -1
  371. package/dist/core/overlay/loader.d.ts +0 -26
  372. package/dist/core/overlay/loader.d.ts.map +0 -1
  373. package/dist/core/overlay/loader.js +0 -199
  374. package/dist/core/overlay/loader.js.map +0 -1
  375. package/dist/core/overlay/patcher.d.ts +0 -26
  376. package/dist/core/overlay/patcher.d.ts.map +0 -1
  377. package/dist/core/overlay/patcher.js +0 -212
  378. package/dist/core/overlay/patcher.js.map +0 -1
  379. package/dist/core/overlay/section-parser.d.ts +0 -25
  380. package/dist/core/overlay/section-parser.d.ts.map +0 -1
  381. package/dist/core/overlay/section-parser.js +0 -99
  382. package/dist/core/overlay/section-parser.js.map +0 -1
  383. package/dist/core/overlay/types.d.ts +0 -51
  384. package/dist/core/overlay/types.d.ts.map +0 -1
  385. package/dist/core/overlay/types.js +0 -15
  386. package/dist/core/overlay/types.js.map +0 -1
  387. package/dist/core/tool-registry.d.ts +0 -10
  388. package/dist/core/tool-registry.d.ts.map +0 -1
  389. package/dist/core/tool-registry.js +0 -29
  390. package/dist/core/tool-registry.js.map +0 -1
  391. package/dist/core/tool-registry.test.d.ts +0 -2
  392. package/dist/core/tool-registry.test.d.ts.map +0 -1
  393. package/dist/core/tool-registry.test.js +0 -78
  394. package/dist/core/tool-registry.test.js.map +0 -1
  395. package/dist/db/connection-pool.d.ts +0 -21
  396. package/dist/db/connection-pool.d.ts.map +0 -1
  397. package/dist/db/connection-pool.js +0 -53
  398. package/dist/db/connection-pool.js.map +0 -1
  399. package/dist/db/index.d.ts +0 -6
  400. package/dist/db/index.d.ts.map +0 -1
  401. package/dist/db/index.js +0 -9
  402. package/dist/db/index.js.map +0 -1
  403. package/dist/db/schema/core/index.d.ts +0 -5
  404. package/dist/db/schema/core/index.d.ts.map +0 -1
  405. package/dist/db/schema/core/index.js +0 -5
  406. package/dist/db/schema/core/index.js.map +0 -1
  407. package/dist/db/schema/core/organizations.d.ts +0 -244
  408. package/dist/db/schema/core/organizations.d.ts.map +0 -1
  409. package/dist/db/schema/core/organizations.js +0 -44
  410. package/dist/db/schema/core/organizations.js.map +0 -1
  411. package/dist/db/schema/core/permissions.d.ts +0 -158
  412. package/dist/db/schema/core/permissions.d.ts.map +0 -1
  413. package/dist/db/schema/core/permissions.js +0 -62
  414. package/dist/db/schema/core/permissions.js.map +0 -1
  415. package/dist/db/schema/core/refresh-tokens.d.ts +0 -147
  416. package/dist/db/schema/core/refresh-tokens.d.ts.map +0 -1
  417. package/dist/db/schema/core/refresh-tokens.js +0 -22
  418. package/dist/db/schema/core/refresh-tokens.js.map +0 -1
  419. package/dist/db/schema/core/users.d.ts +0 -178
  420. package/dist/db/schema/core/users.d.ts.map +0 -1
  421. package/dist/db/schema/core/users.js +0 -14
  422. package/dist/db/schema/core/users.js.map +0 -1
  423. package/dist/db/tenant-migrator.d.ts +0 -11
  424. package/dist/db/tenant-migrator.d.ts.map +0 -1
  425. package/dist/db/tenant-migrator.js +0 -74
  426. package/dist/db/tenant-migrator.js.map +0 -1
  427. package/dist/db/tenant-schema.d.ts +0 -290
  428. package/dist/db/tenant-schema.d.ts.map +0 -1
  429. package/dist/db/tenant-schema.js +0 -32
  430. package/dist/db/tenant-schema.js.map +0 -1
  431. package/dist/hooks/constants.d.ts +0 -40
  432. package/dist/hooks/constants.d.ts.map +0 -1
  433. package/dist/hooks/constants.js +0 -53
  434. package/dist/hooks/constants.js.map +0 -1
  435. package/dist/hooks/context-monitor.d.ts +0 -33
  436. package/dist/hooks/context-monitor.d.ts.map +0 -1
  437. package/dist/hooks/context-monitor.js +0 -117
  438. package/dist/hooks/context-monitor.js.map +0 -1
  439. package/dist/hooks/delegate-monitor.d.ts +0 -24
  440. package/dist/hooks/delegate-monitor.d.ts.map +0 -1
  441. package/dist/hooks/delegate-monitor.js +0 -76
  442. package/dist/hooks/delegate-monitor.js.map +0 -1
  443. package/dist/hooks/index.d.ts +0 -4
  444. package/dist/hooks/index.d.ts.map +0 -1
  445. package/dist/hooks/index.js +0 -4
  446. package/dist/hooks/index.js.map +0 -1
  447. package/dist/hooks/statusline.d.ts +0 -29
  448. package/dist/hooks/statusline.d.ts.map +0 -1
  449. package/dist/hooks/statusline.js +0 -134
  450. package/dist/hooks/statusline.js.map +0 -1
  451. package/dist/index.d.ts +0 -8
  452. package/dist/index.d.ts.map +0 -1
  453. package/dist/index.js +0 -6
  454. package/dist/index.js.map +0 -1
  455. package/dist/mcp/delegate-channel-relay.d.ts +0 -51
  456. package/dist/mcp/delegate-channel-relay.d.ts.map +0 -1
  457. package/dist/mcp/delegate-channel-relay.js +0 -307
  458. package/dist/mcp/delegate-channel-relay.js.map +0 -1
  459. package/dist/mcp/server.d.ts +0 -6
  460. package/dist/mcp/server.d.ts.map +0 -1
  461. package/dist/mcp/server.js +0 -64
  462. package/dist/mcp/server.js.map +0 -1
  463. package/dist/middleware/auth.d.ts +0 -13
  464. package/dist/middleware/auth.d.ts.map +0 -1
  465. package/dist/middleware/auth.js +0 -27
  466. package/dist/middleware/auth.js.map +0 -1
  467. package/dist/middleware/permission.d.ts +0 -9
  468. package/dist/middleware/permission.d.ts.map +0 -1
  469. package/dist/middleware/permission.js +0 -19
  470. package/dist/middleware/permission.js.map +0 -1
  471. package/dist/middleware/rate-limit.d.ts +0 -9
  472. package/dist/middleware/rate-limit.d.ts.map +0 -1
  473. package/dist/middleware/rate-limit.js +0 -40
  474. package/dist/middleware/rate-limit.js.map +0 -1
  475. package/dist/middleware/tenant.d.ts +0 -17
  476. package/dist/middleware/tenant.d.ts.map +0 -1
  477. package/dist/middleware/tenant.js +0 -57
  478. package/dist/middleware/tenant.js.map +0 -1
  479. package/dist/middleware/validation.d.ts +0 -40
  480. package/dist/middleware/validation.d.ts.map +0 -1
  481. package/dist/middleware/validation.js +0 -51
  482. package/dist/middleware/validation.js.map +0 -1
  483. package/dist/routes/auth.d.ts +0 -3
  484. package/dist/routes/auth.d.ts.map +0 -1
  485. package/dist/routes/auth.js +0 -77
  486. package/dist/routes/auth.js.map +0 -1
  487. package/dist/routes/members.d.ts +0 -4
  488. package/dist/routes/members.d.ts.map +0 -1
  489. package/dist/routes/members.js +0 -114
  490. package/dist/routes/members.js.map +0 -1
  491. package/dist/routes/organizations.d.ts +0 -5
  492. package/dist/routes/organizations.d.ts.map +0 -1
  493. package/dist/routes/organizations.js +0 -97
  494. package/dist/routes/organizations.js.map +0 -1
  495. package/dist/services/auth.service.d.ts +0 -24
  496. package/dist/services/auth.service.d.ts.map +0 -1
  497. package/dist/services/auth.service.js +0 -70
  498. package/dist/services/auth.service.js.map +0 -1
  499. package/dist/services/password.service.d.ts +0 -3
  500. package/dist/services/password.service.d.ts.map +0 -1
  501. package/dist/services/password.service.js +0 -18
  502. package/dist/services/password.service.js.map +0 -1
  503. package/dist/services/rbac.service.d.ts +0 -7
  504. package/dist/services/rbac.service.d.ts.map +0 -1
  505. package/dist/services/rbac.service.js +0 -36
  506. package/dist/services/rbac.service.js.map +0 -1
  507. package/dist/services/token.service.d.ts +0 -18
  508. package/dist/services/token.service.d.ts.map +0 -1
  509. package/dist/services/token.service.js +0 -86
  510. package/dist/services/token.service.js.map +0 -1
  511. package/dist/tools/core-memory.d.ts +0 -12
  512. package/dist/tools/core-memory.d.ts.map +0 -1
  513. package/dist/tools/core-memory.js +0 -276
  514. package/dist/tools/core-memory.js.map +0 -1
  515. package/dist/tools/edit-file.d.ts +0 -25
  516. package/dist/tools/edit-file.d.ts.map +0 -1
  517. package/dist/tools/edit-file.js +0 -462
  518. package/dist/tools/edit-file.js.map +0 -1
  519. package/dist/tools/index.d.ts +0 -8
  520. package/dist/tools/index.d.ts.map +0 -1
  521. package/dist/tools/index.js +0 -536
  522. package/dist/tools/index.js.map +0 -1
  523. package/dist/tools/read-file.d.ts +0 -13
  524. package/dist/tools/read-file.d.ts.map +0 -1
  525. package/dist/tools/read-file.js +0 -91
  526. package/dist/tools/read-file.js.map +0 -1
  527. package/dist/tools/read-many-files.d.ts +0 -15
  528. package/dist/tools/read-many-files.d.ts.map +0 -1
  529. package/dist/tools/read-many-files.js +0 -187
  530. package/dist/tools/read-many-files.js.map +0 -1
  531. package/dist/tools/spec-index-builder.d.ts +0 -58
  532. package/dist/tools/spec-index-builder.d.ts.map +0 -1
  533. package/dist/tools/spec-index-builder.js +0 -211
  534. package/dist/tools/spec-index-builder.js.map +0 -1
  535. package/dist/tools/spec-init.d.ts +0 -17
  536. package/dist/tools/spec-init.d.ts.map +0 -1
  537. package/dist/tools/spec-init.js +0 -215
  538. package/dist/tools/spec-init.js.map +0 -1
  539. package/dist/tools/spec-keyword-extractor.d.ts +0 -24
  540. package/dist/tools/spec-keyword-extractor.d.ts.map +0 -1
  541. package/dist/tools/spec-keyword-extractor.js +0 -84
  542. package/dist/tools/spec-keyword-extractor.js.map +0 -1
  543. package/dist/tools/spec-keyword-extractor.test.d.ts +0 -2
  544. package/dist/tools/spec-keyword-extractor.test.d.ts.map +0 -1
  545. package/dist/tools/spec-keyword-extractor.test.js +0 -99
  546. package/dist/tools/spec-keyword-extractor.test.js.map +0 -1
  547. package/dist/tools/spec-loader.d.ts +0 -15
  548. package/dist/tools/spec-loader.d.ts.map +0 -1
  549. package/dist/tools/spec-loader.js +0 -93
  550. package/dist/tools/spec-loader.js.map +0 -1
  551. package/dist/tools/team-msg.d.ts +0 -52
  552. package/dist/tools/team-msg.d.ts.map +0 -1
  553. package/dist/tools/team-msg.js +0 -449
  554. package/dist/tools/team-msg.js.map +0 -1
  555. package/dist/tools/write-file.d.ts +0 -19
  556. package/dist/tools/write-file.d.ts.map +0 -1
  557. package/dist/tools/write-file.js +0 -165
  558. package/dist/tools/write-file.js.map +0 -1
  559. package/dist/types/index.d.ts +0 -47
  560. package/dist/types/index.d.ts.map +0 -1
  561. package/dist/types/index.js +0 -2
  562. package/dist/types/index.js.map +0 -1
  563. package/dist/types/tool-schema.d.ts +0 -37
  564. package/dist/types/tool-schema.d.ts.map +0 -1
  565. package/dist/types/tool-schema.js +0 -24
  566. package/dist/types/tool-schema.js.map +0 -1
  567. package/dist/utils/file-reader.d.ts +0 -74
  568. package/dist/utils/file-reader.d.ts.map +0 -1
  569. package/dist/utils/file-reader.js +0 -217
  570. package/dist/utils/file-reader.js.map +0 -1
  571. package/dist/utils/path-validator.d.ts +0 -52
  572. package/dist/utils/path-validator.d.ts.map +0 -1
  573. package/dist/utils/path-validator.js +0 -151
  574. package/dist/utils/path-validator.js.map +0 -1
@@ -1,1040 +0,0 @@
1
- import { createRequire } from 'node:module';
2
- import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
3
- import { dirname, join } from 'node:path';
4
- import { paths } from '../config/paths.js';
5
- const require = createRequire(import.meta.url);
6
- const DEFAULT_BROKER_STATE_PATH = join(paths.data, 'async', 'delegate-broker.json');
7
- const DEFAULT_BROKER_DB_PATH = join(paths.data, 'async', 'delegate-broker.sqlite');
8
- const TERMINAL_STATUSES = new Set(['completed', 'failed', 'cancelled']);
9
- const DEFAULT_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
10
- const DEFAULT_PURGE_MAX_AGE_MS = 2 * 60 * 60 * 1000; // 2 hours
11
- function createEmptyState() {
12
- return {
13
- version: 1,
14
- nextEventId: 1,
15
- sessions: {},
16
- jobs: {},
17
- eventsByJob: {},
18
- };
19
- }
20
- function inferStatus(type, explicitStatus, currentStatus) {
21
- if (explicitStatus) {
22
- return explicitStatus;
23
- }
24
- switch (type) {
25
- case 'queued':
26
- return 'queued';
27
- case 'completed':
28
- return 'completed';
29
- case 'failed':
30
- return 'failed';
31
- case 'cancelled':
32
- return 'cancelled';
33
- default:
34
- return currentStatus ?? 'running';
35
- }
36
- }
37
- function ensureDirectoryFor(filePath) {
38
- const dir = dirname(filePath);
39
- if (!existsSync(dir)) {
40
- mkdirSync(dir, { recursive: true });
41
- }
42
- }
43
- function isJsonObject(value) {
44
- return typeof value === 'object' && value !== null && !Array.isArray(value);
45
- }
46
- function stripStoredEvent(event) {
47
- const { ackedBy: _ackedBy, ...publicEvent } = event;
48
- return publicEvent;
49
- }
50
- function mergeJsonObjects(base, patch) {
51
- if (!base && !patch) {
52
- return undefined;
53
- }
54
- if (!base) {
55
- return patch ? { ...patch } : undefined;
56
- }
57
- if (!patch) {
58
- return { ...base };
59
- }
60
- return { ...base, ...patch };
61
- }
62
- function isTerminalStatus(status) {
63
- return status !== undefined && TERMINAL_STATUSES.has(status);
64
- }
65
- function buildCancelMetadata(existing, input, now) {
66
- return {
67
- ...(existing ?? {}),
68
- cancelRequestedAt: now,
69
- ...(input.requestedBy ? { cancelRequestedBy: input.requestedBy } : {}),
70
- ...(input.reason ? { cancelReason: input.reason } : {}),
71
- };
72
- }
73
- function buildCancelPayload(input) {
74
- return {
75
- summary: input.reason ? `Cancellation requested: ${input.reason}` : 'Cancellation requested',
76
- ...(input.requestedBy ? { requestedBy: input.requestedBy } : {}),
77
- ...(input.reason ? { reason: input.reason } : {}),
78
- };
79
- }
80
- /** Accept current + legacy delivery values for backward-compat deserialization */
81
- function isLegacyDelivery(value) {
82
- return value === 'inject' || value === 'after_complete'
83
- || value === 'streaming' || value === 'interrupt_resume';
84
- }
85
- /** Normalize legacy delivery values to current type */
86
- function normalizeDelivery(value) {
87
- if (value === 'streaming' || value === 'interrupt_resume')
88
- return 'inject';
89
- return value;
90
- }
91
- function isDelegateMessageStatus(value) {
92
- return value === 'queued' || value === 'dispatched' || value === 'dropped' || value === 'injected';
93
- }
94
- function readQueuedMessages(metadata) {
95
- const raw = metadata?.queuedMessages;
96
- if (!Array.isArray(raw)) {
97
- return [];
98
- }
99
- return raw
100
- .filter((value) => isJsonObject(value))
101
- .map((value) => {
102
- const messageId = typeof value.messageId === 'string' ? value.messageId : '';
103
- const createdAt = typeof value.createdAt === 'string' ? value.createdAt : '';
104
- const delivery = isLegacyDelivery(value.delivery) ? normalizeDelivery(value.delivery) : null;
105
- const message = typeof value.message === 'string' ? value.message : '';
106
- const status = isDelegateMessageStatus(value.status) ? value.status : null;
107
- if (!messageId || !createdAt || !delivery || !message || !status) {
108
- return null;
109
- }
110
- return {
111
- messageId,
112
- createdAt,
113
- delivery,
114
- message,
115
- status,
116
- ...(typeof value.requestedBy === 'string' ? { requestedBy: value.requestedBy } : {}),
117
- ...(typeof value.dispatchedAt === 'string' ? { dispatchedAt: value.dispatchedAt } : {}),
118
- ...(typeof value.dispatchReason === 'string' ? { dispatchReason: value.dispatchReason } : {}),
119
- };
120
- })
121
- .filter((value) => value !== null);
122
- }
123
- function writeQueuedMessages(metadata, messages) {
124
- const next = { ...(metadata ?? {}) };
125
- if (messages.length === 0) {
126
- delete next.queuedMessages;
127
- }
128
- else {
129
- next.queuedMessages = messages.map((message) => ({
130
- messageId: message.messageId,
131
- createdAt: message.createdAt,
132
- delivery: message.delivery,
133
- message: message.message,
134
- status: message.status,
135
- ...(message.requestedBy ? { requestedBy: message.requestedBy } : {}),
136
- ...(message.dispatchedAt ? { dispatchedAt: message.dispatchedAt } : {}),
137
- ...(message.dispatchReason ? { dispatchReason: message.dispatchReason } : {}),
138
- }));
139
- }
140
- return Object.keys(next).length > 0 ? next : undefined;
141
- }
142
- function readJsonObject(raw) {
143
- if (!raw) {
144
- return undefined;
145
- }
146
- try {
147
- const parsed = JSON.parse(raw);
148
- return isJsonObject(parsed) ? parsed : undefined;
149
- }
150
- catch {
151
- return undefined;
152
- }
153
- }
154
- function writeJson(value) {
155
- if (!value) {
156
- return null;
157
- }
158
- return JSON.stringify(value);
159
- }
160
- function requireSqlite() {
161
- return require('node:sqlite');
162
- }
163
- function sqliteAvailable() {
164
- try {
165
- requireSqlite();
166
- return true;
167
- }
168
- catch {
169
- return false;
170
- }
171
- }
172
- export function defaultDelegateBrokerDbPath() {
173
- return DEFAULT_BROKER_DB_PATH;
174
- }
175
- export class FileDelegateBroker {
176
- statePath;
177
- constructor(options = {}) {
178
- this.statePath = options.statePath ?? DEFAULT_BROKER_STATE_PATH;
179
- ensureDirectoryFor(this.statePath);
180
- if (!existsSync(this.statePath)) {
181
- this.writeState(createEmptyState());
182
- }
183
- }
184
- registerSession(input) {
185
- const now = input.now ?? new Date().toISOString();
186
- return this.updateState((state) => {
187
- const existing = state.sessions[input.sessionId];
188
- const nextSession = {
189
- sessionId: input.sessionId,
190
- channelId: input.channelId ?? existing?.channelId,
191
- metadata: mergeJsonObjects(existing?.metadata, input.metadata),
192
- registeredAt: existing?.registeredAt ?? now,
193
- lastSeenAt: now,
194
- };
195
- state.sessions[input.sessionId] = nextSession;
196
- return nextSession;
197
- });
198
- }
199
- heartbeat(input) {
200
- const now = input.now ?? new Date().toISOString();
201
- return this.updateState((state) => {
202
- const session = state.sessions[input.sessionId];
203
- if (!session) {
204
- throw new Error(`Unknown delegate session: ${input.sessionId}`);
205
- }
206
- const nextSession = {
207
- ...session,
208
- lastSeenAt: now,
209
- };
210
- state.sessions[input.sessionId] = nextSession;
211
- return nextSession;
212
- });
213
- }
214
- publishEvent(input) {
215
- const now = input.now ?? new Date().toISOString();
216
- return this.updateState((state) => {
217
- const existingJob = state.jobs[input.jobId];
218
- const events = state.eventsByJob[input.jobId] ?? [];
219
- const eventId = state.nextEventId++;
220
- const snapshot = input.snapshot ?? (isJsonObject(input.payload?.snapshot) ? input.payload.snapshot : undefined);
221
- const metadata = mergeJsonObjects(existingJob?.metadata, input.jobMetadata);
222
- const event = {
223
- eventId,
224
- sequence: events.length + 1,
225
- jobId: input.jobId,
226
- type: input.type,
227
- createdAt: now,
228
- status: input.status,
229
- snapshot,
230
- payload: input.payload ?? {},
231
- metadata,
232
- ackedBy: {},
233
- };
234
- events.push(event);
235
- state.eventsByJob[input.jobId] = events;
236
- state.jobs[input.jobId] = {
237
- jobId: input.jobId,
238
- status: inferStatus(input.type, input.status, existingJob?.status),
239
- createdAt: existingJob?.createdAt ?? now,
240
- updatedAt: now,
241
- lastEventId: eventId,
242
- lastEventType: input.type,
243
- latestSnapshot: snapshot ?? existingJob?.latestSnapshot ?? null,
244
- metadata,
245
- };
246
- return stripStoredEvent(event);
247
- });
248
- }
249
- pollEvents(input) {
250
- const now = input.now ?? new Date().toISOString();
251
- const limit = Math.max(1, input.limit ?? 100);
252
- return this.updateState((state) => {
253
- const session = state.sessions[input.sessionId];
254
- if (!session) {
255
- throw new Error(`Unknown delegate session: ${input.sessionId}`);
256
- }
257
- state.sessions[input.sessionId] = {
258
- ...session,
259
- lastSeenAt: now,
260
- };
261
- const jobIds = input.jobId ? [input.jobId] : Object.keys(state.eventsByJob);
262
- return jobIds
263
- .flatMap((jobId) => state.eventsByJob[jobId] ?? [])
264
- .filter((event) => !event.ackedBy[input.sessionId])
265
- .filter((event) => input.afterEventId === undefined || event.eventId > input.afterEventId)
266
- .sort((left, right) => left.eventId - right.eventId)
267
- .slice(0, limit)
268
- .map(stripStoredEvent);
269
- });
270
- }
271
- ack(input) {
272
- const now = input.now ?? new Date().toISOString();
273
- const eventIds = new Set(input.eventIds);
274
- return this.updateState((state) => {
275
- const session = state.sessions[input.sessionId];
276
- if (!session) {
277
- throw new Error(`Unknown delegate session: ${input.sessionId}`);
278
- }
279
- state.sessions[input.sessionId] = {
280
- ...session,
281
- lastSeenAt: now,
282
- };
283
- let ackedCount = 0;
284
- for (const events of Object.values(state.eventsByJob)) {
285
- for (const event of events) {
286
- if (!eventIds.has(event.eventId) || event.ackedBy[input.sessionId]) {
287
- continue;
288
- }
289
- event.ackedBy[input.sessionId] = now;
290
- ackedCount += 1;
291
- }
292
- }
293
- return ackedCount;
294
- });
295
- }
296
- getJob(jobId) {
297
- const state = this.readState();
298
- return state.jobs[jobId] ?? null;
299
- }
300
- listJobEvents(jobId) {
301
- const state = this.readState();
302
- return (state.eventsByJob[jobId] ?? []).map(stripStoredEvent);
303
- }
304
- requestCancel(input) {
305
- const now = input.now ?? new Date().toISOString();
306
- return this.updateState((state) => {
307
- const existingJob = state.jobs[input.jobId];
308
- if (existingJob && (isTerminalStatus(existingJob.status) || existingJob.metadata?.cancelRequestedAt)) {
309
- return existingJob;
310
- }
311
- const metadata = buildCancelMetadata(existingJob?.metadata, input, now);
312
- const events = state.eventsByJob[input.jobId] ?? [];
313
- const eventId = state.nextEventId++;
314
- const status = existingJob?.status ?? 'queued';
315
- const event = {
316
- eventId,
317
- sequence: events.length + 1,
318
- jobId: input.jobId,
319
- type: 'cancel_requested',
320
- createdAt: now,
321
- status,
322
- snapshot: existingJob?.latestSnapshot ?? undefined,
323
- payload: buildCancelPayload(input),
324
- metadata,
325
- ackedBy: {},
326
- };
327
- events.push(event);
328
- state.eventsByJob[input.jobId] = events;
329
- const job = {
330
- jobId: input.jobId,
331
- status,
332
- createdAt: existingJob?.createdAt ?? now,
333
- updatedAt: now,
334
- lastEventId: eventId,
335
- lastEventType: 'cancel_requested',
336
- latestSnapshot: existingJob?.latestSnapshot ?? null,
337
- metadata,
338
- };
339
- state.jobs[input.jobId] = job;
340
- return job;
341
- });
342
- }
343
- queueMessage(input) {
344
- const now = input.now ?? new Date().toISOString();
345
- return this.updateState((state) => {
346
- const existingJob = state.jobs[input.jobId];
347
- if (!existingJob) {
348
- throw new Error(`Unknown delegate job: ${input.jobId}`);
349
- }
350
- const queuedMessages = readQueuedMessages(existingJob.metadata);
351
- const queuedMessage = {
352
- messageId: `msg-${state.nextEventId}`,
353
- createdAt: now,
354
- delivery: input.delivery,
355
- message: input.message,
356
- status: 'queued',
357
- ...(input.requestedBy ? { requestedBy: input.requestedBy } : {}),
358
- };
359
- const metadata = writeQueuedMessages(existingJob.metadata, [...queuedMessages, queuedMessage]);
360
- const events = state.eventsByJob[input.jobId] ?? [];
361
- const eventId = state.nextEventId++;
362
- const event = {
363
- eventId,
364
- sequence: events.length + 1,
365
- jobId: input.jobId,
366
- type: 'message_queued',
367
- createdAt: now,
368
- status: existingJob.status,
369
- snapshot: existingJob.latestSnapshot ?? undefined,
370
- payload: {
371
- summary: `Queued ${input.delivery} follow-up message`,
372
- delivery: input.delivery,
373
- messageId: queuedMessage.messageId,
374
- },
375
- metadata,
376
- ackedBy: {},
377
- };
378
- events.push(event);
379
- state.eventsByJob[input.jobId] = events;
380
- state.jobs[input.jobId] = {
381
- ...existingJob,
382
- updatedAt: now,
383
- lastEventId: eventId,
384
- lastEventType: 'message_queued',
385
- metadata,
386
- };
387
- return queuedMessage;
388
- });
389
- }
390
- listMessages(jobId) {
391
- return readQueuedMessages(this.getJob(jobId)?.metadata);
392
- }
393
- updateMessage(input) {
394
- const now = input.now ?? new Date().toISOString();
395
- return this.updateState((state) => {
396
- const existingJob = state.jobs[input.jobId];
397
- if (!existingJob) {
398
- return null;
399
- }
400
- const queuedMessages = readQueuedMessages(existingJob.metadata);
401
- const index = queuedMessages.findIndex((message) => message.messageId === input.messageId);
402
- if (index === -1) {
403
- return null;
404
- }
405
- const updatedMessage = {
406
- ...queuedMessages[index],
407
- status: input.status,
408
- ...(input.status === 'dispatched' ? { dispatchedAt: now } : {}),
409
- ...(input.dispatchReason ? { dispatchReason: input.dispatchReason } : {}),
410
- };
411
- queuedMessages[index] = updatedMessage;
412
- const metadata = writeQueuedMessages(existingJob.metadata, queuedMessages);
413
- const events = state.eventsByJob[input.jobId] ?? [];
414
- const eventId = state.nextEventId++;
415
- const eventType = input.status === 'dispatched'
416
- ? 'message_dispatched'
417
- : input.status === 'injected'
418
- ? 'message_injected'
419
- : 'message_dropped';
420
- const event = {
421
- eventId,
422
- sequence: events.length + 1,
423
- jobId: input.jobId,
424
- type: eventType,
425
- createdAt: now,
426
- status: existingJob.status,
427
- snapshot: existingJob.latestSnapshot ?? undefined,
428
- payload: {
429
- summary: input.status === 'dispatched'
430
- ? `Dispatched ${updatedMessage.delivery} follow-up message`
431
- : input.status === 'injected'
432
- ? `Injected ${updatedMessage.delivery} follow-up message`
433
- : `Dropped ${updatedMessage.delivery} follow-up message`,
434
- delivery: updatedMessage.delivery,
435
- messageId: updatedMessage.messageId,
436
- ...(input.dispatchReason ? { reason: input.dispatchReason } : {}),
437
- },
438
- metadata,
439
- ackedBy: {},
440
- };
441
- events.push(event);
442
- state.eventsByJob[input.jobId] = events;
443
- state.jobs[input.jobId] = {
444
- ...existingJob,
445
- updatedAt: now,
446
- lastEventId: eventId,
447
- lastEventType: eventType,
448
- metadata,
449
- };
450
- return updatedMessage;
451
- });
452
- }
453
- checkTimeouts(input) {
454
- const timeoutMs = input?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
455
- const now = input?.now ?? new Date().toISOString();
456
- const nowMs = new Date(now).getTime();
457
- return this.updateState((state) => {
458
- const timedOut = [];
459
- for (const job of Object.values(state.jobs)) {
460
- if (isTerminalStatus(job.status)) {
461
- continue;
462
- }
463
- const createdMs = new Date(job.createdAt).getTime();
464
- if (nowMs - createdMs < timeoutMs) {
465
- continue;
466
- }
467
- const events = state.eventsByJob[job.jobId] ?? [];
468
- const eventId = state.nextEventId++;
469
- const event = {
470
- eventId,
471
- sequence: events.length + 1,
472
- jobId: job.jobId,
473
- type: 'failed',
474
- createdAt: now,
475
- status: 'failed',
476
- snapshot: job.latestSnapshot ?? undefined,
477
- payload: { summary: 'Timed out', reason: 'timeout' },
478
- metadata: job.metadata,
479
- ackedBy: {},
480
- };
481
- events.push(event);
482
- state.eventsByJob[job.jobId] = events;
483
- const updatedJob = {
484
- ...job,
485
- status: 'failed',
486
- updatedAt: now,
487
- lastEventId: eventId,
488
- lastEventType: 'failed',
489
- };
490
- state.jobs[job.jobId] = updatedJob;
491
- timedOut.push(updatedJob);
492
- }
493
- return timedOut;
494
- });
495
- }
496
- purgeExpiredEvents(input) {
497
- const maxAgeMs = input?.maxAgeMs ?? DEFAULT_PURGE_MAX_AGE_MS;
498
- const now = input?.now ?? new Date().toISOString();
499
- const nowMs = new Date(now).getTime();
500
- const cutoff = nowMs - maxAgeMs;
501
- return this.updateState((state) => {
502
- let purgedEventCount = 0;
503
- let purgedJobCount = 0;
504
- let purgedSessionCount = 0;
505
- // Purge events and jobs for terminal jobs older than cutoff
506
- for (const [jobId, job] of Object.entries(state.jobs)) {
507
- if (!isTerminalStatus(job.status)) {
508
- continue;
509
- }
510
- if (new Date(job.updatedAt).getTime() > cutoff) {
511
- continue;
512
- }
513
- const events = state.eventsByJob[jobId];
514
- purgedEventCount += events?.length ?? 0;
515
- delete state.eventsByJob[jobId];
516
- delete state.jobs[jobId];
517
- purgedJobCount += 1;
518
- }
519
- // Purge stale sessions not seen since cutoff
520
- for (const [sessionId, session] of Object.entries(state.sessions)) {
521
- if (new Date(session.lastSeenAt).getTime() > cutoff) {
522
- continue;
523
- }
524
- delete state.sessions[sessionId];
525
- purgedSessionCount += 1;
526
- }
527
- return { purgedEventCount, purgedJobCount, purgedSessionCount };
528
- });
529
- }
530
- updateState(updater) {
531
- const state = this.readState();
532
- const result = updater(state);
533
- this.writeState(state);
534
- return result;
535
- }
536
- readState() {
537
- try {
538
- const raw = readFileSync(this.statePath, 'utf-8');
539
- const parsed = JSON.parse(raw);
540
- if (parsed.version === 1) {
541
- return parsed;
542
- }
543
- }
544
- catch {
545
- // fall through
546
- }
547
- return createEmptyState();
548
- }
549
- writeState(state) {
550
- ensureDirectoryFor(this.statePath);
551
- const tmpPath = `${this.statePath}.${process.pid}.tmp`;
552
- writeFileSync(tmpPath, JSON.stringify(state, null, 2), 'utf-8');
553
- renameSync(tmpPath, this.statePath);
554
- }
555
- }
556
- export class SqliteDelegateBroker {
557
- dbPath;
558
- db;
559
- constructor(options = {}) {
560
- this.dbPath = options.dbPath ?? DEFAULT_BROKER_DB_PATH;
561
- ensureDirectoryFor(this.dbPath);
562
- const { DatabaseSync } = requireSqlite();
563
- this.db = new DatabaseSync(this.dbPath);
564
- this.initialize();
565
- }
566
- registerSession(input) {
567
- const now = input.now ?? new Date().toISOString();
568
- return this.transaction(() => {
569
- const existing = this.getSessionRow(input.sessionId);
570
- const metadata = mergeJsonObjects(readJsonObject(existing?.metadata), input.metadata);
571
- this.db.prepare(`
572
- INSERT INTO delegate_sessions (session_id, channel_id, metadata, registered_at, last_seen_at)
573
- VALUES (?, ?, ?, ?, ?)
574
- ON CONFLICT(session_id) DO UPDATE SET
575
- channel_id = excluded.channel_id,
576
- metadata = excluded.metadata,
577
- last_seen_at = excluded.last_seen_at
578
- `).run(input.sessionId, input.channelId ?? existing?.channel_id ?? null, writeJson(metadata), existing?.registered_at ?? now, now);
579
- return {
580
- sessionId: input.sessionId,
581
- channelId: input.channelId ?? existing?.channel_id ?? undefined,
582
- metadata,
583
- registeredAt: existing?.registered_at ?? now,
584
- lastSeenAt: now,
585
- };
586
- });
587
- }
588
- heartbeat(input) {
589
- const now = input.now ?? new Date().toISOString();
590
- return this.transaction(() => {
591
- const existing = this.getSessionRow(input.sessionId);
592
- if (!existing) {
593
- throw new Error(`Unknown delegate session: ${input.sessionId}`);
594
- }
595
- this.db.prepare('UPDATE delegate_sessions SET last_seen_at = ? WHERE session_id = ?').run(now, input.sessionId);
596
- return this.sessionFromRow({ ...existing, last_seen_at: now });
597
- });
598
- }
599
- publishEvent(input) {
600
- const now = input.now ?? new Date().toISOString();
601
- return this.transaction(() => {
602
- const existingJob = this.getJob(input.jobId);
603
- const metadata = mergeJsonObjects(existingJob?.metadata, input.jobMetadata);
604
- const snapshot = input.snapshot ?? (isJsonObject(input.payload?.snapshot) ? input.payload.snapshot : undefined);
605
- const sequenceRow = this.db.prepare('SELECT COALESCE(MAX(sequence), 0) AS value FROM delegate_events WHERE job_id = ?').get(input.jobId);
606
- const sequence = Number(sequenceRow?.value ?? 0) + 1;
607
- const eventResult = this.db.prepare(`
608
- INSERT INTO delegate_events (sequence, job_id, type, created_at, status, snapshot, payload, metadata)
609
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
610
- `).run(sequence, input.jobId, input.type, now, input.status ?? null, writeJson(snapshot), JSON.stringify(input.payload ?? {}), writeJson(metadata));
611
- const eventId = Number(eventResult.lastInsertRowid ?? 0);
612
- const status = inferStatus(input.type, input.status, existingJob?.status);
613
- this.db.prepare(`
614
- INSERT INTO delegate_jobs (job_id, status, created_at, updated_at, last_event_id, last_event_type, latest_snapshot, metadata)
615
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
616
- ON CONFLICT(job_id) DO UPDATE SET
617
- status = excluded.status,
618
- updated_at = excluded.updated_at,
619
- last_event_id = excluded.last_event_id,
620
- last_event_type = excluded.last_event_type,
621
- latest_snapshot = excluded.latest_snapshot,
622
- metadata = excluded.metadata
623
- `).run(input.jobId, status, existingJob?.createdAt ?? now, now, eventId, input.type, writeJson(snapshot ?? existingJob?.latestSnapshot ?? null), writeJson(metadata));
624
- return {
625
- eventId,
626
- sequence,
627
- jobId: input.jobId,
628
- type: input.type,
629
- createdAt: now,
630
- status: input.status,
631
- snapshot,
632
- payload: input.payload ?? {},
633
- metadata,
634
- };
635
- });
636
- }
637
- pollEvents(input) {
638
- const now = input.now ?? new Date().toISOString();
639
- const limit = Math.max(1, input.limit ?? 100);
640
- return this.transaction(() => {
641
- const session = this.getSessionRow(input.sessionId);
642
- if (!session) {
643
- throw new Error(`Unknown delegate session: ${input.sessionId}`);
644
- }
645
- this.db.prepare('UPDATE delegate_sessions SET last_seen_at = ? WHERE session_id = ?').run(now, input.sessionId);
646
- const params = [input.sessionId];
647
- let where = 'a.event_id IS NULL';
648
- if (input.jobId) {
649
- where += ' AND e.job_id = ?';
650
- params.push(input.jobId);
651
- }
652
- if (input.afterEventId !== undefined) {
653
- where += ' AND e.event_id > ?';
654
- params.push(input.afterEventId);
655
- }
656
- params.push(limit);
657
- const rows = this.db.prepare(`
658
- SELECT
659
- e.event_id,
660
- e.sequence,
661
- e.job_id,
662
- e.type,
663
- e.created_at,
664
- e.status,
665
- e.snapshot,
666
- e.payload,
667
- e.metadata
668
- FROM delegate_events e
669
- LEFT JOIN delegate_event_acks a
670
- ON a.event_id = e.event_id AND a.session_id = ?
671
- WHERE ${where}
672
- ORDER BY e.event_id ASC
673
- LIMIT ?
674
- `).all(...params);
675
- return rows.map((row) => this.eventFromRow(row));
676
- });
677
- }
678
- ack(input) {
679
- const now = input.now ?? new Date().toISOString();
680
- if (input.eventIds.length === 0) {
681
- return 0;
682
- }
683
- return this.transaction(() => {
684
- const session = this.getSessionRow(input.sessionId);
685
- if (!session) {
686
- throw new Error(`Unknown delegate session: ${input.sessionId}`);
687
- }
688
- this.db.prepare('UPDATE delegate_sessions SET last_seen_at = ? WHERE session_id = ?').run(now, input.sessionId);
689
- const statement = this.db.prepare(`
690
- INSERT OR IGNORE INTO delegate_event_acks (session_id, event_id, acked_at)
691
- VALUES (?, ?, ?)
692
- `);
693
- let acked = 0;
694
- for (const eventId of input.eventIds) {
695
- const result = statement.run(input.sessionId, eventId, now);
696
- if (Number(result.lastInsertRowid ?? 0) > 0) {
697
- acked += 1;
698
- }
699
- else {
700
- const exists = this.db.prepare(`
701
- SELECT 1 AS value FROM delegate_event_acks WHERE session_id = ? AND event_id = ?
702
- `).get(input.sessionId, eventId);
703
- if (exists) {
704
- continue;
705
- }
706
- }
707
- }
708
- return acked;
709
- });
710
- }
711
- getJob(jobId) {
712
- const row = this.getJobRow(jobId);
713
- return row ? this.jobFromRow(row) : null;
714
- }
715
- listJobEvents(jobId) {
716
- const rows = this.db.prepare(`
717
- SELECT event_id, sequence, job_id, type, created_at, status, snapshot, payload, metadata
718
- FROM delegate_events
719
- WHERE job_id = ?
720
- ORDER BY event_id ASC
721
- `).all(jobId);
722
- return rows.map((row) => this.eventFromRow(row));
723
- }
724
- requestCancel(input) {
725
- const now = input.now ?? new Date().toISOString();
726
- return this.transaction(() => {
727
- const existingJob = this.getJob(input.jobId);
728
- if (existingJob && (isTerminalStatus(existingJob.status) || existingJob.metadata?.cancelRequestedAt)) {
729
- return existingJob;
730
- }
731
- const metadata = buildCancelMetadata(existingJob?.metadata, input, now);
732
- const sequenceRow = this.db.prepare('SELECT COALESCE(MAX(sequence), 0) AS value FROM delegate_events WHERE job_id = ?').get(input.jobId);
733
- const sequence = Number(sequenceRow?.value ?? 0) + 1;
734
- const status = existingJob?.status ?? 'queued';
735
- const eventResult = this.db.prepare(`
736
- INSERT INTO delegate_events (sequence, job_id, type, created_at, status, snapshot, payload, metadata)
737
- VALUES (?, ?, 'cancel_requested', ?, ?, ?, ?, ?)
738
- `).run(sequence, input.jobId, now, status, writeJson(existingJob?.latestSnapshot ?? null), JSON.stringify(buildCancelPayload(input)), writeJson(metadata));
739
- const eventId = Number(eventResult.lastInsertRowid ?? 0);
740
- this.db.prepare(`
741
- INSERT INTO delegate_jobs (job_id, status, created_at, updated_at, last_event_id, last_event_type, latest_snapshot, metadata)
742
- VALUES (?, ?, ?, ?, ?, 'cancel_requested', ?, ?)
743
- ON CONFLICT(job_id) DO UPDATE SET
744
- updated_at = excluded.updated_at,
745
- last_event_id = excluded.last_event_id,
746
- last_event_type = excluded.last_event_type,
747
- latest_snapshot = excluded.latest_snapshot,
748
- metadata = excluded.metadata
749
- `).run(input.jobId, status, existingJob?.createdAt ?? now, now, eventId, writeJson(existingJob?.latestSnapshot ?? null), writeJson(metadata));
750
- const updated = this.getJob(input.jobId);
751
- if (!updated) {
752
- throw new Error(`Failed to request cancellation for: ${input.jobId}`);
753
- }
754
- return updated;
755
- });
756
- }
757
- queueMessage(input) {
758
- const now = input.now ?? new Date().toISOString();
759
- return this.transaction(() => {
760
- const existingJob = this.getJob(input.jobId);
761
- if (!existingJob) {
762
- throw new Error(`Unknown delegate job: ${input.jobId}`);
763
- }
764
- const queuedMessages = readQueuedMessages(existingJob.metadata);
765
- const queuedMessage = {
766
- messageId: `msg-${existingJob.lastEventId + 1}`,
767
- createdAt: now,
768
- delivery: input.delivery,
769
- message: input.message,
770
- status: 'queued',
771
- ...(input.requestedBy ? { requestedBy: input.requestedBy } : {}),
772
- };
773
- const metadata = writeQueuedMessages(existingJob.metadata, [...queuedMessages, queuedMessage]);
774
- const sequenceRow = this.db.prepare('SELECT COALESCE(MAX(sequence), 0) AS value FROM delegate_events WHERE job_id = ?').get(input.jobId);
775
- const sequence = Number(sequenceRow?.value ?? 0) + 1;
776
- const eventResult = this.db.prepare(`
777
- INSERT INTO delegate_events (sequence, job_id, type, created_at, status, snapshot, payload, metadata)
778
- VALUES (?, ?, 'message_queued', ?, ?, ?, ?, ?)
779
- `).run(sequence, input.jobId, now, existingJob.status, writeJson(existingJob.latestSnapshot ?? null), JSON.stringify({
780
- summary: `Queued ${input.delivery} follow-up message`,
781
- delivery: input.delivery,
782
- messageId: queuedMessage.messageId,
783
- }), writeJson(metadata));
784
- const eventId = Number(eventResult.lastInsertRowid ?? 0);
785
- this.db.prepare(`
786
- UPDATE delegate_jobs
787
- SET updated_at = ?, last_event_id = ?, last_event_type = 'message_queued', metadata = ?
788
- WHERE job_id = ?
789
- `).run(now, eventId, writeJson(metadata), input.jobId);
790
- return queuedMessage;
791
- });
792
- }
793
- listMessages(jobId) {
794
- return readQueuedMessages(this.getJob(jobId)?.metadata);
795
- }
796
- updateMessage(input) {
797
- const now = input.now ?? new Date().toISOString();
798
- return this.transaction(() => {
799
- const existingJob = this.getJob(input.jobId);
800
- if (!existingJob) {
801
- return null;
802
- }
803
- const queuedMessages = readQueuedMessages(existingJob.metadata);
804
- const index = queuedMessages.findIndex((message) => message.messageId === input.messageId);
805
- if (index === -1) {
806
- return null;
807
- }
808
- const updatedMessage = {
809
- ...queuedMessages[index],
810
- status: input.status,
811
- ...(input.status === 'dispatched' ? { dispatchedAt: now } : {}),
812
- ...(input.dispatchReason ? { dispatchReason: input.dispatchReason } : {}),
813
- };
814
- queuedMessages[index] = updatedMessage;
815
- const metadata = writeQueuedMessages(existingJob.metadata, queuedMessages);
816
- const sequenceRow = this.db.prepare('SELECT COALESCE(MAX(sequence), 0) AS value FROM delegate_events WHERE job_id = ?').get(input.jobId);
817
- const sequence = Number(sequenceRow?.value ?? 0) + 1;
818
- const eventType = input.status === 'dispatched' ? 'message_dispatched' : input.status === 'injected' ? 'message_injected' : 'message_dropped';
819
- const eventResult = this.db.prepare(`
820
- INSERT INTO delegate_events (sequence, job_id, type, created_at, status, snapshot, payload, metadata)
821
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
822
- `).run(sequence, input.jobId, eventType, now, existingJob.status, writeJson(existingJob.latestSnapshot ?? null), JSON.stringify({
823
- summary: input.status === 'dispatched'
824
- ? `Dispatched ${updatedMessage.delivery} follow-up message`
825
- : input.status === 'injected'
826
- ? `Injected ${updatedMessage.delivery} follow-up message`
827
- : `Dropped ${updatedMessage.delivery} follow-up message`,
828
- delivery: updatedMessage.delivery,
829
- messageId: updatedMessage.messageId,
830
- ...(input.dispatchReason ? { reason: input.dispatchReason } : {}),
831
- }), writeJson(metadata));
832
- const eventId = Number(eventResult.lastInsertRowid ?? 0);
833
- this.db.prepare(`
834
- UPDATE delegate_jobs
835
- SET updated_at = ?, last_event_id = ?, last_event_type = ?, metadata = ?
836
- WHERE job_id = ?
837
- `).run(now, eventId, eventType, writeJson(metadata), input.jobId);
838
- return updatedMessage;
839
- });
840
- }
841
- checkTimeouts(input) {
842
- const timeoutMs = input?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
843
- const now = input?.now ?? new Date().toISOString();
844
- const nowMs = new Date(now).getTime();
845
- return this.transaction(() => {
846
- const rows = this.db.prepare(`
847
- SELECT job_id, status, created_at, updated_at, last_event_id, last_event_type, latest_snapshot, metadata
848
- FROM delegate_jobs
849
- WHERE status NOT IN ('completed', 'failed', 'cancelled')
850
- `).all();
851
- const timedOut = [];
852
- for (const row of rows) {
853
- const createdMs = new Date(row.created_at).getTime();
854
- if (nowMs - createdMs < timeoutMs) {
855
- continue;
856
- }
857
- const metadata = readJsonObject(row.metadata);
858
- const snapshot = readJsonObject(row.latest_snapshot);
859
- const sequenceRow = this.db.prepare('SELECT COALESCE(MAX(sequence), 0) AS value FROM delegate_events WHERE job_id = ?').get(row.job_id);
860
- const sequence = Number(sequenceRow?.value ?? 0) + 1;
861
- const eventResult = this.db.prepare(`
862
- INSERT INTO delegate_events (sequence, job_id, type, created_at, status, snapshot, payload, metadata)
863
- VALUES (?, ?, 'failed', ?, 'failed', ?, ?, ?)
864
- `).run(sequence, row.job_id, now, writeJson(snapshot), JSON.stringify({ summary: 'Timed out', reason: 'timeout' }), writeJson(metadata));
865
- const eventId = Number(eventResult.lastInsertRowid ?? 0);
866
- this.db.prepare(`
867
- UPDATE delegate_jobs
868
- SET status = 'failed', updated_at = ?, last_event_id = ?, last_event_type = 'failed'
869
- WHERE job_id = ?
870
- `).run(now, eventId, row.job_id);
871
- timedOut.push({
872
- jobId: row.job_id,
873
- status: 'failed',
874
- createdAt: row.created_at,
875
- updatedAt: now,
876
- lastEventId: eventId,
877
- lastEventType: 'failed',
878
- latestSnapshot: snapshot ?? null,
879
- metadata,
880
- });
881
- }
882
- return timedOut;
883
- });
884
- }
885
- purgeExpiredEvents(input) {
886
- const maxAgeMs = input?.maxAgeMs ?? DEFAULT_PURGE_MAX_AGE_MS;
887
- const now = input?.now ?? new Date().toISOString();
888
- const nowMs = new Date(now).getTime();
889
- const cutoffIso = new Date(nowMs - maxAgeMs).toISOString();
890
- return this.transaction(() => {
891
- // Find terminal jobs older than cutoff
892
- const expiredJobs = this.db.prepare(`
893
- SELECT job_id FROM delegate_jobs
894
- WHERE status IN ('completed', 'failed', 'cancelled')
895
- AND updated_at <= ?
896
- `).all(cutoffIso);
897
- let purgedEventCount = 0;
898
- for (const { job_id } of expiredJobs) {
899
- const countRow = this.db.prepare('SELECT COUNT(*) AS cnt FROM delegate_events WHERE job_id = ?').get(job_id);
900
- purgedEventCount += Number(countRow?.cnt ?? 0);
901
- this.db.prepare(`
902
- DELETE FROM delegate_event_acks
903
- WHERE event_id IN (SELECT event_id FROM delegate_events WHERE job_id = ?)
904
- `).run(job_id);
905
- this.db.prepare('DELETE FROM delegate_events WHERE job_id = ?').run(job_id);
906
- this.db.prepare('DELETE FROM delegate_jobs WHERE job_id = ?').run(job_id);
907
- }
908
- // Purge stale sessions
909
- const sessionCountRow = this.db.prepare('SELECT COUNT(*) AS cnt FROM delegate_sessions WHERE last_seen_at <= ?').get(cutoffIso);
910
- const purgedSessionCount = Number(sessionCountRow?.cnt ?? 0);
911
- this.db.prepare('DELETE FROM delegate_sessions WHERE last_seen_at <= ?').run(cutoffIso);
912
- return {
913
- purgedEventCount,
914
- purgedJobCount: expiredJobs.length,
915
- purgedSessionCount,
916
- };
917
- });
918
- }
919
- close() {
920
- this.db.close();
921
- }
922
- initialize() {
923
- this.db.exec(`
924
- PRAGMA journal_mode = WAL;
925
- PRAGMA busy_timeout = 5000;
926
-
927
- CREATE TABLE IF NOT EXISTS delegate_sessions (
928
- session_id TEXT PRIMARY KEY,
929
- channel_id TEXT,
930
- metadata TEXT,
931
- registered_at TEXT NOT NULL,
932
- last_seen_at TEXT NOT NULL
933
- );
934
-
935
- CREATE TABLE IF NOT EXISTS delegate_jobs (
936
- job_id TEXT PRIMARY KEY,
937
- status TEXT NOT NULL,
938
- created_at TEXT NOT NULL,
939
- updated_at TEXT NOT NULL,
940
- last_event_id INTEGER NOT NULL,
941
- last_event_type TEXT NOT NULL,
942
- latest_snapshot TEXT,
943
- metadata TEXT
944
- );
945
-
946
- CREATE TABLE IF NOT EXISTS delegate_events (
947
- event_id INTEGER PRIMARY KEY AUTOINCREMENT,
948
- sequence INTEGER NOT NULL,
949
- job_id TEXT NOT NULL,
950
- type TEXT NOT NULL,
951
- created_at TEXT NOT NULL,
952
- status TEXT,
953
- snapshot TEXT,
954
- payload TEXT NOT NULL,
955
- metadata TEXT
956
- );
957
-
958
- CREATE TABLE IF NOT EXISTS delegate_event_acks (
959
- session_id TEXT NOT NULL,
960
- event_id INTEGER NOT NULL,
961
- acked_at TEXT NOT NULL,
962
- PRIMARY KEY (session_id, event_id)
963
- );
964
-
965
- CREATE INDEX IF NOT EXISTS idx_delegate_events_job_id ON delegate_events(job_id, event_id);
966
- CREATE INDEX IF NOT EXISTS idx_delegate_events_event_id ON delegate_events(event_id);
967
- `);
968
- }
969
- transaction(fn) {
970
- this.db.exec('BEGIN IMMEDIATE');
971
- try {
972
- const result = fn();
973
- this.db.exec('COMMIT');
974
- return result;
975
- }
976
- catch (error) {
977
- this.db.exec('ROLLBACK');
978
- throw error;
979
- }
980
- }
981
- getSessionRow(sessionId) {
982
- const row = this.db.prepare(`
983
- SELECT session_id, channel_id, metadata, registered_at, last_seen_at
984
- FROM delegate_sessions
985
- WHERE session_id = ?
986
- `).get(sessionId);
987
- return row ?? null;
988
- }
989
- getJobRow(jobId) {
990
- const row = this.db.prepare(`
991
- SELECT job_id, status, created_at, updated_at, last_event_id, last_event_type, latest_snapshot, metadata
992
- FROM delegate_jobs
993
- WHERE job_id = ?
994
- `).get(jobId);
995
- return row ?? null;
996
- }
997
- sessionFromRow(row) {
998
- return {
999
- sessionId: row.session_id,
1000
- channelId: row.channel_id ?? undefined,
1001
- metadata: readJsonObject(row.metadata),
1002
- registeredAt: row.registered_at,
1003
- lastSeenAt: row.last_seen_at,
1004
- };
1005
- }
1006
- jobFromRow(row) {
1007
- return {
1008
- jobId: row.job_id,
1009
- status: row.status,
1010
- createdAt: row.created_at,
1011
- updatedAt: row.updated_at,
1012
- lastEventId: Number(row.last_event_id),
1013
- lastEventType: row.last_event_type,
1014
- latestSnapshot: readJsonObject(row.latest_snapshot) ?? null,
1015
- metadata: readJsonObject(row.metadata),
1016
- };
1017
- }
1018
- eventFromRow(row) {
1019
- const payload = readJsonObject(row.payload) ?? {};
1020
- return {
1021
- eventId: Number(row.event_id),
1022
- sequence: Number(row.sequence),
1023
- jobId: row.job_id,
1024
- type: row.type,
1025
- createdAt: row.created_at,
1026
- status: row.status ? row.status : undefined,
1027
- snapshot: readJsonObject(row.snapshot),
1028
- payload,
1029
- metadata: readJsonObject(row.metadata),
1030
- };
1031
- }
1032
- }
1033
- export function createDefaultDelegateBroker(options = {}) {
1034
- const preferSqlite = options.preferSqlite ?? !options.statePath;
1035
- if (preferSqlite && sqliteAvailable()) {
1036
- return new SqliteDelegateBroker(options);
1037
- }
1038
- return new FileDelegateBroker(options);
1039
- }
1040
- //# sourceMappingURL=delegate-broker.js.map