maestro-flow 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (425) hide show
  1. package/.claude/commands/maestro-overlay.md +178 -122
  2. package/.claude/commands/manage-harvest.md +4 -4
  3. package/.codex/skills/maestro-coordinate/SKILL.md +3 -4
  4. package/dist/src/commands/launcher.js +1 -1
  5. package/dist/src/commands/launcher.js.map +1 -1
  6. package/dist/src/commands/overlay-ui/OverlayList.d.ts +35 -0
  7. package/dist/src/commands/overlay-ui/OverlayList.d.ts.map +1 -0
  8. package/dist/src/commands/overlay-ui/OverlayList.js +143 -0
  9. package/dist/src/commands/overlay-ui/OverlayList.js.map +1 -0
  10. package/dist/src/commands/overlay-ui/index.d.ts +2 -0
  11. package/dist/src/commands/overlay-ui/index.d.ts.map +1 -0
  12. package/dist/src/commands/overlay-ui/index.js +188 -0
  13. package/dist/src/commands/overlay-ui/index.js.map +1 -0
  14. package/dist/src/commands/overlay.d.ts.map +1 -1
  15. package/dist/src/commands/overlay.js +79 -59
  16. package/dist/src/commands/overlay.js.map +1 -1
  17. package/dist/src/core/overlay/applier.d.ts +32 -1
  18. package/dist/src/core/overlay/applier.d.ts.map +1 -1
  19. package/dist/src/core/overlay/applier.js +109 -1
  20. package/dist/src/core/overlay/applier.js.map +1 -1
  21. package/package.json +1 -1
  22. package/dist/agents/cli-agent-runner.d.ts +0 -131
  23. package/dist/agents/cli-agent-runner.d.ts.map +0 -1
  24. package/dist/agents/cli-agent-runner.js +0 -688
  25. package/dist/agents/cli-agent-runner.js.map +0 -1
  26. package/dist/agents/cli-history-store.d.ts +0 -63
  27. package/dist/agents/cli-history-store.d.ts.map +0 -1
  28. package/dist/agents/cli-history-store.js +0 -242
  29. package/dist/agents/cli-history-store.js.map +0 -1
  30. package/dist/agents/dashboard-bridge.d.ts +0 -39
  31. package/dist/agents/dashboard-bridge.d.ts.map +0 -1
  32. package/dist/agents/dashboard-bridge.js +0 -76
  33. package/dist/agents/dashboard-bridge.js.map +0 -1
  34. package/dist/agents/parallel-cli-runner.d.ts +0 -46
  35. package/dist/agents/parallel-cli-runner.d.ts.map +0 -1
  36. package/dist/agents/parallel-cli-runner.js +0 -277
  37. package/dist/agents/parallel-cli-runner.js.map +0 -1
  38. package/dist/agents/terminal-adapter.d.ts +0 -94
  39. package/dist/agents/terminal-adapter.d.ts.map +0 -1
  40. package/dist/agents/terminal-adapter.js +0 -132
  41. package/dist/agents/terminal-adapter.js.map +0 -1
  42. package/dist/agents/terminal-backend.d.ts +0 -53
  43. package/dist/agents/terminal-backend.d.ts.map +0 -1
  44. package/dist/agents/terminal-backend.js +0 -286
  45. package/dist/agents/terminal-backend.js.map +0 -1
  46. package/dist/async/delegate-broker-client.d.ts +0 -22
  47. package/dist/async/delegate-broker-client.d.ts.map +0 -1
  48. package/dist/async/delegate-broker-client.js +0 -47
  49. package/dist/async/delegate-broker-client.js.map +0 -1
  50. package/dist/async/delegate-broker.d.ts +0 -180
  51. package/dist/async/delegate-broker.d.ts.map +0 -1
  52. package/dist/async/delegate-broker.js +0 -1040
  53. package/dist/async/delegate-broker.js.map +0 -1
  54. package/dist/async/delegate-control.d.ts +0 -37
  55. package/dist/async/delegate-control.d.ts.map +0 -1
  56. package/dist/async/delegate-control.js +0 -155
  57. package/dist/async/delegate-control.js.map +0 -1
  58. package/dist/async/index.d.ts +0 -3
  59. package/dist/async/index.d.ts.map +0 -1
  60. package/dist/async/index.js +0 -3
  61. package/dist/async/index.js.map +0 -1
  62. package/dist/cli.d.ts +0 -2
  63. package/dist/cli.d.ts.map +0 -1
  64. package/dist/cli.js +0 -40
  65. package/dist/cli.js.map +0 -1
  66. package/dist/commands/cli.d.ts +0 -3
  67. package/dist/commands/cli.d.ts.map +0 -1
  68. package/dist/commands/cli.js +0 -262
  69. package/dist/commands/cli.js.map +0 -1
  70. package/dist/commands/coordinate.d.ts +0 -3
  71. package/dist/commands/coordinate.d.ts.map +0 -1
  72. package/dist/commands/coordinate.js +0 -275
  73. package/dist/commands/coordinate.js.map +0 -1
  74. package/dist/commands/delegate.d.ts +0 -37
  75. package/dist/commands/delegate.d.ts.map +0 -1
  76. package/dist/commands/delegate.js +0 -470
  77. package/dist/commands/delegate.js.map +0 -1
  78. package/dist/commands/ext.d.ts +0 -3
  79. package/dist/commands/ext.d.ts.map +0 -1
  80. package/dist/commands/ext.js +0 -28
  81. package/dist/commands/ext.js.map +0 -1
  82. package/dist/commands/hooks.d.ts +0 -3
  83. package/dist/commands/hooks.d.ts.map +0 -1
  84. package/dist/commands/hooks.js +0 -126
  85. package/dist/commands/hooks.js.map +0 -1
  86. package/dist/commands/install.d.ts +0 -3
  87. package/dist/commands/install.d.ts.map +0 -1
  88. package/dist/commands/install.js +0 -621
  89. package/dist/commands/install.js.map +0 -1
  90. package/dist/commands/launcher.d.ts +0 -3
  91. package/dist/commands/launcher.d.ts.map +0 -1
  92. package/dist/commands/launcher.js +0 -635
  93. package/dist/commands/launcher.js.map +0 -1
  94. package/dist/commands/link-coordinate.d.ts +0 -3
  95. package/dist/commands/link-coordinate.d.ts.map +0 -1
  96. package/dist/commands/link-coordinate.js +0 -225
  97. package/dist/commands/link-coordinate.js.map +0 -1
  98. package/dist/commands/msg.d.ts +0 -3
  99. package/dist/commands/msg.d.ts.map +0 -1
  100. package/dist/commands/msg.js +0 -110
  101. package/dist/commands/msg.js.map +0 -1
  102. package/dist/commands/overlay.d.ts +0 -3
  103. package/dist/commands/overlay.d.ts.map +0 -1
  104. package/dist/commands/overlay.js +0 -243
  105. package/dist/commands/overlay.js.map +0 -1
  106. package/dist/commands/run.d.ts +0 -3
  107. package/dist/commands/run.d.ts.map +0 -1
  108. package/dist/commands/run.js +0 -15
  109. package/dist/commands/run.js.map +0 -1
  110. package/dist/commands/serve.d.ts +0 -3
  111. package/dist/commands/serve.d.ts.map +0 -1
  112. package/dist/commands/serve.js +0 -16
  113. package/dist/commands/serve.js.map +0 -1
  114. package/dist/commands/spec.d.ts +0 -8
  115. package/dist/commands/spec.d.ts.map +0 -1
  116. package/dist/commands/spec.js +0 -147
  117. package/dist/commands/spec.js.map +0 -1
  118. package/dist/commands/stop.d.ts +0 -3
  119. package/dist/commands/stop.d.ts.map +0 -1
  120. package/dist/commands/stop.js +0 -218
  121. package/dist/commands/stop.js.map +0 -1
  122. package/dist/commands/tool.d.ts +0 -3
  123. package/dist/commands/tool.d.ts.map +0 -1
  124. package/dist/commands/tool.js +0 -29
  125. package/dist/commands/tool.js.map +0 -1
  126. package/dist/commands/uninstall.d.ts +0 -3
  127. package/dist/commands/uninstall.d.ts.map +0 -1
  128. package/dist/commands/uninstall.js +0 -77
  129. package/dist/commands/uninstall.js.map +0 -1
  130. package/dist/commands/view.d.ts +0 -3
  131. package/dist/commands/view.d.ts.map +0 -1
  132. package/dist/commands/view.js +0 -337
  133. package/dist/commands/view.js.map +0 -1
  134. package/dist/config/cli-tools-config.d.ts +0 -26
  135. package/dist/config/cli-tools-config.d.ts.map +0 -1
  136. package/dist/config/cli-tools-config.js +0 -49
  137. package/dist/config/cli-tools-config.js.map +0 -1
  138. package/dist/config/cli-tools-config.test.d.ts +0 -2
  139. package/dist/config/cli-tools-config.test.d.ts.map +0 -1
  140. package/dist/config/cli-tools-config.test.js +0 -59
  141. package/dist/config/cli-tools-config.test.js.map +0 -1
  142. package/dist/config/index.d.ts +0 -4
  143. package/dist/config/index.d.ts.map +0 -1
  144. package/dist/config/index.js +0 -27
  145. package/dist/config/index.js.map +0 -1
  146. package/dist/config/paths.d.ts +0 -15
  147. package/dist/config/paths.d.ts.map +0 -1
  148. package/dist/config/paths.js +0 -27
  149. package/dist/config/paths.js.map +0 -1
  150. package/dist/config/template-discovery.d.ts +0 -32
  151. package/dist/config/template-discovery.d.ts.map +0 -1
  152. package/dist/config/template-discovery.js +0 -128
  153. package/dist/config/template-discovery.js.map +0 -1
  154. package/dist/coordinator/cli-executor.d.ts +0 -22
  155. package/dist/coordinator/cli-executor.d.ts.map +0 -1
  156. package/dist/coordinator/cli-executor.js +0 -49
  157. package/dist/coordinator/cli-executor.js.map +0 -1
  158. package/dist/coordinator/expr-evaluator.d.ts +0 -11
  159. package/dist/coordinator/expr-evaluator.d.ts.map +0 -1
  160. package/dist/coordinator/expr-evaluator.js +0 -351
  161. package/dist/coordinator/expr-evaluator.js.map +0 -1
  162. package/dist/coordinator/graph-loader.d.ts +0 -16
  163. package/dist/coordinator/graph-loader.d.ts.map +0 -1
  164. package/dist/coordinator/graph-loader.js +0 -190
  165. package/dist/coordinator/graph-loader.js.map +0 -1
  166. package/dist/coordinator/graph-types.d.ts +0 -304
  167. package/dist/coordinator/graph-types.d.ts.map +0 -1
  168. package/dist/coordinator/graph-types.js +0 -6
  169. package/dist/coordinator/graph-types.js.map +0 -1
  170. package/dist/coordinator/graph-walker.d.ts +0 -51
  171. package/dist/coordinator/graph-walker.d.ts.map +0 -1
  172. package/dist/coordinator/graph-walker.js +0 -666
  173. package/dist/coordinator/graph-walker.js.map +0 -1
  174. package/dist/coordinator/index.d.ts +0 -13
  175. package/dist/coordinator/index.d.ts.map +0 -1
  176. package/dist/coordinator/index.js +0 -14
  177. package/dist/coordinator/index.js.map +0 -1
  178. package/dist/coordinator/intent-router.d.ts +0 -11
  179. package/dist/coordinator/intent-router.d.ts.map +0 -1
  180. package/dist/coordinator/intent-router.js +0 -65
  181. package/dist/coordinator/intent-router.js.map +0 -1
  182. package/dist/coordinator/link-session.d.ts +0 -29
  183. package/dist/coordinator/link-session.d.ts.map +0 -1
  184. package/dist/coordinator/link-session.js +0 -192
  185. package/dist/coordinator/link-session.js.map +0 -1
  186. package/dist/coordinator/link-walker.d.ts +0 -56
  187. package/dist/coordinator/link-walker.d.ts.map +0 -1
  188. package/dist/coordinator/link-walker.js +0 -548
  189. package/dist/coordinator/link-walker.js.map +0 -1
  190. package/dist/coordinator/output-parser.d.ts +0 -5
  191. package/dist/coordinator/output-parser.d.ts.map +0 -1
  192. package/dist/coordinator/output-parser.js +0 -114
  193. package/dist/coordinator/output-parser.js.map +0 -1
  194. package/dist/coordinator/parallel-executor.d.ts +0 -24
  195. package/dist/coordinator/parallel-executor.d.ts.map +0 -1
  196. package/dist/coordinator/parallel-executor.js +0 -43
  197. package/dist/coordinator/parallel-executor.js.map +0 -1
  198. package/dist/coordinator/prompt-assembler.d.ts +0 -15
  199. package/dist/coordinator/prompt-assembler.d.ts.map +0 -1
  200. package/dist/coordinator/prompt-assembler.js +0 -228
  201. package/dist/coordinator/prompt-assembler.js.map +0 -1
  202. package/dist/coordinator/step-analyzer.d.ts +0 -8
  203. package/dist/coordinator/step-analyzer.d.ts.map +0 -1
  204. package/dist/coordinator/step-analyzer.js +0 -82
  205. package/dist/coordinator/step-analyzer.js.map +0 -1
  206. package/dist/core/extension-loader.d.ts +0 -11
  207. package/dist/core/extension-loader.d.ts.map +0 -1
  208. package/dist/core/extension-loader.js +0 -54
  209. package/dist/core/extension-loader.js.map +0 -1
  210. package/dist/core/manifest.d.ts +0 -24
  211. package/dist/core/manifest.d.ts.map +0 -1
  212. package/dist/core/manifest.js +0 -139
  213. package/dist/core/manifest.js.map +0 -1
  214. package/dist/core/mcp-tool-registry.integration.test.d.ts +0 -2
  215. package/dist/core/mcp-tool-registry.integration.test.d.ts.map +0 -1
  216. package/dist/core/mcp-tool-registry.integration.test.js +0 -220
  217. package/dist/core/mcp-tool-registry.integration.test.js.map +0 -1
  218. package/dist/core/overlay/applier.d.ts +0 -73
  219. package/dist/core/overlay/applier.d.ts.map +0 -1
  220. package/dist/core/overlay/applier.js +0 -248
  221. package/dist/core/overlay/applier.js.map +0 -1
  222. package/dist/core/overlay/loader.d.ts +0 -26
  223. package/dist/core/overlay/loader.d.ts.map +0 -1
  224. package/dist/core/overlay/loader.js +0 -199
  225. package/dist/core/overlay/loader.js.map +0 -1
  226. package/dist/core/overlay/patcher.d.ts +0 -26
  227. package/dist/core/overlay/patcher.d.ts.map +0 -1
  228. package/dist/core/overlay/patcher.js +0 -212
  229. package/dist/core/overlay/patcher.js.map +0 -1
  230. package/dist/core/overlay/section-parser.d.ts +0 -25
  231. package/dist/core/overlay/section-parser.d.ts.map +0 -1
  232. package/dist/core/overlay/section-parser.js +0 -99
  233. package/dist/core/overlay/section-parser.js.map +0 -1
  234. package/dist/core/overlay/types.d.ts +0 -51
  235. package/dist/core/overlay/types.d.ts.map +0 -1
  236. package/dist/core/overlay/types.js +0 -15
  237. package/dist/core/overlay/types.js.map +0 -1
  238. package/dist/core/tool-registry.d.ts +0 -10
  239. package/dist/core/tool-registry.d.ts.map +0 -1
  240. package/dist/core/tool-registry.js +0 -29
  241. package/dist/core/tool-registry.js.map +0 -1
  242. package/dist/core/tool-registry.test.d.ts +0 -2
  243. package/dist/core/tool-registry.test.d.ts.map +0 -1
  244. package/dist/core/tool-registry.test.js +0 -78
  245. package/dist/core/tool-registry.test.js.map +0 -1
  246. package/dist/db/connection-pool.d.ts +0 -21
  247. package/dist/db/connection-pool.d.ts.map +0 -1
  248. package/dist/db/connection-pool.js +0 -53
  249. package/dist/db/connection-pool.js.map +0 -1
  250. package/dist/db/index.d.ts +0 -6
  251. package/dist/db/index.d.ts.map +0 -1
  252. package/dist/db/index.js +0 -9
  253. package/dist/db/index.js.map +0 -1
  254. package/dist/db/schema/core/index.d.ts +0 -5
  255. package/dist/db/schema/core/index.d.ts.map +0 -1
  256. package/dist/db/schema/core/index.js +0 -5
  257. package/dist/db/schema/core/index.js.map +0 -1
  258. package/dist/db/schema/core/organizations.d.ts +0 -244
  259. package/dist/db/schema/core/organizations.d.ts.map +0 -1
  260. package/dist/db/schema/core/organizations.js +0 -44
  261. package/dist/db/schema/core/organizations.js.map +0 -1
  262. package/dist/db/schema/core/permissions.d.ts +0 -158
  263. package/dist/db/schema/core/permissions.d.ts.map +0 -1
  264. package/dist/db/schema/core/permissions.js +0 -62
  265. package/dist/db/schema/core/permissions.js.map +0 -1
  266. package/dist/db/schema/core/refresh-tokens.d.ts +0 -147
  267. package/dist/db/schema/core/refresh-tokens.d.ts.map +0 -1
  268. package/dist/db/schema/core/refresh-tokens.js +0 -22
  269. package/dist/db/schema/core/refresh-tokens.js.map +0 -1
  270. package/dist/db/schema/core/users.d.ts +0 -178
  271. package/dist/db/schema/core/users.d.ts.map +0 -1
  272. package/dist/db/schema/core/users.js +0 -14
  273. package/dist/db/schema/core/users.js.map +0 -1
  274. package/dist/db/tenant-migrator.d.ts +0 -11
  275. package/dist/db/tenant-migrator.d.ts.map +0 -1
  276. package/dist/db/tenant-migrator.js +0 -74
  277. package/dist/db/tenant-migrator.js.map +0 -1
  278. package/dist/db/tenant-schema.d.ts +0 -290
  279. package/dist/db/tenant-schema.d.ts.map +0 -1
  280. package/dist/db/tenant-schema.js +0 -32
  281. package/dist/db/tenant-schema.js.map +0 -1
  282. package/dist/hooks/constants.d.ts +0 -40
  283. package/dist/hooks/constants.d.ts.map +0 -1
  284. package/dist/hooks/constants.js +0 -53
  285. package/dist/hooks/constants.js.map +0 -1
  286. package/dist/hooks/context-monitor.d.ts +0 -33
  287. package/dist/hooks/context-monitor.d.ts.map +0 -1
  288. package/dist/hooks/context-monitor.js +0 -117
  289. package/dist/hooks/context-monitor.js.map +0 -1
  290. package/dist/hooks/delegate-monitor.d.ts +0 -24
  291. package/dist/hooks/delegate-monitor.d.ts.map +0 -1
  292. package/dist/hooks/delegate-monitor.js +0 -76
  293. package/dist/hooks/delegate-monitor.js.map +0 -1
  294. package/dist/hooks/index.d.ts +0 -4
  295. package/dist/hooks/index.d.ts.map +0 -1
  296. package/dist/hooks/index.js +0 -4
  297. package/dist/hooks/index.js.map +0 -1
  298. package/dist/hooks/statusline.d.ts +0 -29
  299. package/dist/hooks/statusline.d.ts.map +0 -1
  300. package/dist/hooks/statusline.js +0 -134
  301. package/dist/hooks/statusline.js.map +0 -1
  302. package/dist/index.d.ts +0 -8
  303. package/dist/index.d.ts.map +0 -1
  304. package/dist/index.js +0 -6
  305. package/dist/index.js.map +0 -1
  306. package/dist/mcp/delegate-channel-relay.d.ts +0 -51
  307. package/dist/mcp/delegate-channel-relay.d.ts.map +0 -1
  308. package/dist/mcp/delegate-channel-relay.js +0 -307
  309. package/dist/mcp/delegate-channel-relay.js.map +0 -1
  310. package/dist/mcp/server.d.ts +0 -6
  311. package/dist/mcp/server.d.ts.map +0 -1
  312. package/dist/mcp/server.js +0 -64
  313. package/dist/mcp/server.js.map +0 -1
  314. package/dist/middleware/auth.d.ts +0 -13
  315. package/dist/middleware/auth.d.ts.map +0 -1
  316. package/dist/middleware/auth.js +0 -27
  317. package/dist/middleware/auth.js.map +0 -1
  318. package/dist/middleware/permission.d.ts +0 -9
  319. package/dist/middleware/permission.d.ts.map +0 -1
  320. package/dist/middleware/permission.js +0 -19
  321. package/dist/middleware/permission.js.map +0 -1
  322. package/dist/middleware/rate-limit.d.ts +0 -9
  323. package/dist/middleware/rate-limit.d.ts.map +0 -1
  324. package/dist/middleware/rate-limit.js +0 -40
  325. package/dist/middleware/rate-limit.js.map +0 -1
  326. package/dist/middleware/tenant.d.ts +0 -17
  327. package/dist/middleware/tenant.d.ts.map +0 -1
  328. package/dist/middleware/tenant.js +0 -57
  329. package/dist/middleware/tenant.js.map +0 -1
  330. package/dist/middleware/validation.d.ts +0 -40
  331. package/dist/middleware/validation.d.ts.map +0 -1
  332. package/dist/middleware/validation.js +0 -51
  333. package/dist/middleware/validation.js.map +0 -1
  334. package/dist/routes/auth.d.ts +0 -3
  335. package/dist/routes/auth.d.ts.map +0 -1
  336. package/dist/routes/auth.js +0 -77
  337. package/dist/routes/auth.js.map +0 -1
  338. package/dist/routes/members.d.ts +0 -4
  339. package/dist/routes/members.d.ts.map +0 -1
  340. package/dist/routes/members.js +0 -114
  341. package/dist/routes/members.js.map +0 -1
  342. package/dist/routes/organizations.d.ts +0 -5
  343. package/dist/routes/organizations.d.ts.map +0 -1
  344. package/dist/routes/organizations.js +0 -97
  345. package/dist/routes/organizations.js.map +0 -1
  346. package/dist/services/auth.service.d.ts +0 -24
  347. package/dist/services/auth.service.d.ts.map +0 -1
  348. package/dist/services/auth.service.js +0 -70
  349. package/dist/services/auth.service.js.map +0 -1
  350. package/dist/services/password.service.d.ts +0 -3
  351. package/dist/services/password.service.d.ts.map +0 -1
  352. package/dist/services/password.service.js +0 -18
  353. package/dist/services/password.service.js.map +0 -1
  354. package/dist/services/rbac.service.d.ts +0 -7
  355. package/dist/services/rbac.service.d.ts.map +0 -1
  356. package/dist/services/rbac.service.js +0 -36
  357. package/dist/services/rbac.service.js.map +0 -1
  358. package/dist/services/token.service.d.ts +0 -18
  359. package/dist/services/token.service.d.ts.map +0 -1
  360. package/dist/services/token.service.js +0 -86
  361. package/dist/services/token.service.js.map +0 -1
  362. package/dist/tools/core-memory.d.ts +0 -12
  363. package/dist/tools/core-memory.d.ts.map +0 -1
  364. package/dist/tools/core-memory.js +0 -276
  365. package/dist/tools/core-memory.js.map +0 -1
  366. package/dist/tools/edit-file.d.ts +0 -25
  367. package/dist/tools/edit-file.d.ts.map +0 -1
  368. package/dist/tools/edit-file.js +0 -462
  369. package/dist/tools/edit-file.js.map +0 -1
  370. package/dist/tools/index.d.ts +0 -8
  371. package/dist/tools/index.d.ts.map +0 -1
  372. package/dist/tools/index.js +0 -536
  373. package/dist/tools/index.js.map +0 -1
  374. package/dist/tools/read-file.d.ts +0 -13
  375. package/dist/tools/read-file.d.ts.map +0 -1
  376. package/dist/tools/read-file.js +0 -91
  377. package/dist/tools/read-file.js.map +0 -1
  378. package/dist/tools/read-many-files.d.ts +0 -15
  379. package/dist/tools/read-many-files.d.ts.map +0 -1
  380. package/dist/tools/read-many-files.js +0 -187
  381. package/dist/tools/read-many-files.js.map +0 -1
  382. package/dist/tools/spec-index-builder.d.ts +0 -58
  383. package/dist/tools/spec-index-builder.d.ts.map +0 -1
  384. package/dist/tools/spec-index-builder.js +0 -211
  385. package/dist/tools/spec-index-builder.js.map +0 -1
  386. package/dist/tools/spec-init.d.ts +0 -17
  387. package/dist/tools/spec-init.d.ts.map +0 -1
  388. package/dist/tools/spec-init.js +0 -215
  389. package/dist/tools/spec-init.js.map +0 -1
  390. package/dist/tools/spec-keyword-extractor.d.ts +0 -24
  391. package/dist/tools/spec-keyword-extractor.d.ts.map +0 -1
  392. package/dist/tools/spec-keyword-extractor.js +0 -84
  393. package/dist/tools/spec-keyword-extractor.js.map +0 -1
  394. package/dist/tools/spec-keyword-extractor.test.d.ts +0 -2
  395. package/dist/tools/spec-keyword-extractor.test.d.ts.map +0 -1
  396. package/dist/tools/spec-keyword-extractor.test.js +0 -99
  397. package/dist/tools/spec-keyword-extractor.test.js.map +0 -1
  398. package/dist/tools/spec-loader.d.ts +0 -15
  399. package/dist/tools/spec-loader.d.ts.map +0 -1
  400. package/dist/tools/spec-loader.js +0 -93
  401. package/dist/tools/spec-loader.js.map +0 -1
  402. package/dist/tools/team-msg.d.ts +0 -52
  403. package/dist/tools/team-msg.d.ts.map +0 -1
  404. package/dist/tools/team-msg.js +0 -449
  405. package/dist/tools/team-msg.js.map +0 -1
  406. package/dist/tools/write-file.d.ts +0 -19
  407. package/dist/tools/write-file.d.ts.map +0 -1
  408. package/dist/tools/write-file.js +0 -165
  409. package/dist/tools/write-file.js.map +0 -1
  410. package/dist/types/index.d.ts +0 -47
  411. package/dist/types/index.d.ts.map +0 -1
  412. package/dist/types/index.js +0 -2
  413. package/dist/types/index.js.map +0 -1
  414. package/dist/types/tool-schema.d.ts +0 -37
  415. package/dist/types/tool-schema.d.ts.map +0 -1
  416. package/dist/types/tool-schema.js +0 -24
  417. package/dist/types/tool-schema.js.map +0 -1
  418. package/dist/utils/file-reader.d.ts +0 -74
  419. package/dist/utils/file-reader.d.ts.map +0 -1
  420. package/dist/utils/file-reader.js +0 -217
  421. package/dist/utils/file-reader.js.map +0 -1
  422. package/dist/utils/path-validator.d.ts +0 -52
  423. package/dist/utils/path-validator.d.ts.map +0 -1
  424. package/dist/utils/path-validator.js +0 -151
  425. 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