@capybara-hq/kernel 0.1.0-rc.23 → 0.1.0-rc.25

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 (293) hide show
  1. package/bootstrap.json +25 -25
  2. package/dist/admin/admin.module.d.ts +2 -1
  3. package/dist/admin/admin.module.js +9 -3
  4. package/dist/admin/health.service.d.ts +2 -2
  5. package/dist/admin/health.service.js +6 -2
  6. package/dist/admin/outbox-dead.controller.d.ts +23 -0
  7. package/dist/admin/outbox-dead.controller.js +62 -0
  8. package/dist/admin/outbox-dead.schemas.d.ts +8 -0
  9. package/dist/admin/outbox-dead.schemas.js +18 -0
  10. package/dist/admin/outbox-dead.service.d.ts +66 -0
  11. package/dist/admin/outbox-dead.service.js +179 -0
  12. package/dist/admin/overview.service.d.ts +40 -5
  13. package/dist/admin/overview.service.js +41 -7
  14. package/dist/agents/agents.module.js +3 -0
  15. package/dist/agents/agents.service.d.ts +6 -1
  16. package/dist/agents/agents.service.js +11 -2
  17. package/dist/agents/from-template.js +1 -1
  18. package/dist/background/finish.d.ts +5 -2
  19. package/dist/background/finish.js +14 -3
  20. package/dist/background/launch.d.ts +2 -1
  21. package/dist/background/launch.js +5 -2
  22. package/dist/background/store.d.ts +8 -0
  23. package/dist/background/store.js +24 -0
  24. package/dist/catalog/admin-catalog.controller.d.ts +21 -2
  25. package/dist/catalog/admin-catalog.controller.js +45 -6
  26. package/dist/catalog/admin-catalog.schemas.d.ts +5 -0
  27. package/dist/catalog/admin-catalog.schemas.js +8 -0
  28. package/dist/catalog/catalog-import.module.js +0 -4
  29. package/dist/catalog/catalog-scope.service.d.ts +63 -26
  30. package/dist/catalog/catalog-scope.service.js +146 -71
  31. package/dist/catalog/catalog.module.d.ts +2 -1
  32. package/dist/catalog/catalog.module.js +9 -4
  33. package/dist/catalog/catalog.service.d.ts +11 -4
  34. package/dist/catalog/catalog.service.js +21 -5
  35. package/dist/catalog/cli.d.ts +4 -3
  36. package/dist/catalog/cli.js +8 -13
  37. package/dist/catalog/job-ids.d.ts +8 -20
  38. package/dist/catalog/job-ids.js +11 -16
  39. package/dist/catalog/marketplaces.service.d.ts +1 -1
  40. package/dist/catalog/org-plugin-uploads.d.ts +11 -4
  41. package/dist/catalog/org-plugin-uploads.js +21 -6
  42. package/dist/catalog/owned-items.d.ts +6 -13
  43. package/dist/catalog/owned-items.js +11 -29
  44. package/dist/catalog/owned-plugin-cleanup.d.ts +8 -17
  45. package/dist/catalog/owned-plugin-cleanup.js +12 -66
  46. package/dist/catalog/platform-components.d.ts +56 -34
  47. package/dist/catalog/platform-components.js +68 -78
  48. package/dist/catalog/platform-import-update.d.ts +50 -0
  49. package/dist/catalog/platform-import-update.js +116 -0
  50. package/dist/catalog/plugin-import.d.ts +64 -26
  51. package/dist/catalog/plugin-import.js +113 -77
  52. package/dist/catalog/plugin-upgrade.d.ts +22 -4
  53. package/dist/catalog/plugin-upgrade.js +26 -19
  54. package/dist/catalog/scope-jobs.d.ts +59 -0
  55. package/dist/catalog/scope-jobs.js +65 -0
  56. package/dist/catalog/scope-sync-workers.d.ts +22 -0
  57. package/dist/catalog/scope-sync-workers.js +58 -2
  58. package/dist/catalog/scope-sync.d.ts +40 -65
  59. package/dist/catalog/scope-sync.js +114 -122
  60. package/dist/channels/channels.module.d.ts +5 -2
  61. package/dist/channels/channels.module.js +9 -2
  62. package/dist/channels/deliver-job.d.ts +25 -0
  63. package/dist/channels/deliver-job.js +25 -0
  64. package/dist/channels/inbound.d.ts +1 -1
  65. package/dist/channels/inbound.js +4 -17
  66. package/dist/channels/jobs.d.ts +28 -18
  67. package/dist/channels/jobs.js +63 -26
  68. package/dist/channels/threads.d.ts +4 -3
  69. package/dist/channels/threads.js +4 -3
  70. package/dist/config/schema.d.ts +0 -3
  71. package/dist/config/schema.js +11 -20
  72. package/dist/conversations/agent-tree.d.ts +16 -0
  73. package/dist/conversations/agent-tree.js +36 -0
  74. package/dist/conversations/conversations.controller.js +4 -2
  75. package/dist/conversations/conversations.service.d.ts +61 -19
  76. package/dist/conversations/conversations.service.js +69 -43
  77. package/dist/conversations/event-log.d.ts +7 -10
  78. package/dist/conversations/event-log.js +24 -15
  79. package/dist/conversations/events.d.ts +21 -0
  80. package/dist/conversations/events.js +26 -2
  81. package/dist/conversations/queue.service.d.ts +8 -3
  82. package/dist/conversations/queue.service.js +37 -13
  83. package/dist/conversations/source.d.ts +10 -0
  84. package/dist/conversations/source.js +17 -0
  85. package/dist/conversations/titles.d.ts +21 -8
  86. package/dist/conversations/titles.js +42 -15
  87. package/dist/conversations/tree.d.ts +10 -0
  88. package/dist/conversations/tree.js +35 -0
  89. package/dist/db/kernel-schema.d.ts +35 -22
  90. package/dist/devices/devices.service.d.ts +23 -11
  91. package/dist/devices/devices.service.js +34 -26
  92. package/dist/errors.d.ts +11 -0
  93. package/dist/errors.js +11 -0
  94. package/dist/evals/run-replay.d.ts +13 -2
  95. package/dist/evals/run-replay.js +42 -9
  96. package/dist/evals/snapshot.d.ts +7 -1
  97. package/dist/evals/snapshot.js +2 -1
  98. package/dist/extensions/extensions.module.js +3 -0
  99. package/dist/extensions/hooks.d.ts +22 -3
  100. package/dist/extensions/hooks.js +15 -1
  101. package/dist/extensions/lifecycle-hooks.d.ts +99 -0
  102. package/dist/extensions/lifecycle-hooks.js +273 -0
  103. package/dist/extensions/lifecycle.d.ts +6 -1
  104. package/dist/extensions/lifecycle.js +9 -2
  105. package/dist/extensions/org-config.d.ts +13 -1
  106. package/dist/extensions/org-config.js +19 -2
  107. package/dist/extensions/permission-view.d.ts +9 -5
  108. package/dist/extensions/permission-view.js +9 -4
  109. package/dist/extensions/point-defaults.d.ts +28 -1
  110. package/dist/extensions/point-defaults.js +44 -13
  111. package/dist/extensions/usage-subscribers.d.ts +43 -0
  112. package/dist/extensions/usage-subscribers.js +108 -0
  113. package/dist/http/api.module.js +2 -0
  114. package/dist/inbox/inbox.service.d.ts +6 -20
  115. package/dist/inbox/inbox.service.js +0 -3
  116. package/dist/inbox/org-notices.d.ts +1 -1
  117. package/dist/inbox/platform-inbox.service.d.ts +3 -32
  118. package/dist/inbox/platform-inbox.service.js +5 -54
  119. package/dist/index.d.ts +1 -0
  120. package/dist/index.js +1 -0
  121. package/dist/infra/cli/kernel-cli.module.js +5 -0
  122. package/dist/infra/events/kernel-events.d.ts +9 -35
  123. package/dist/infra/outbox/outbox-relay.module.d.ts +6 -0
  124. package/dist/infra/outbox/outbox-relay.module.js +18 -0
  125. package/dist/infra/outbox/outbox.dispatcher.d.ts +103 -0
  126. package/dist/infra/outbox/outbox.dispatcher.js +310 -0
  127. package/dist/infra/outbox/outbox.module.d.ts +24 -0
  128. package/dist/infra/outbox/outbox.module.js +50 -0
  129. package/dist/infra/outbox/outbox.relay.d.ts +31 -0
  130. package/dist/infra/outbox/outbox.relay.js +76 -0
  131. package/dist/infra/outbox/outbox.service.d.ts +51 -0
  132. package/dist/infra/outbox/outbox.service.js +131 -0
  133. package/dist/infra/outbox/registry.d.ts +244 -0
  134. package/dist/infra/outbox/registry.js +234 -0
  135. package/dist/infra/queue/queue-names.d.ts +8 -0
  136. package/dist/infra/queue/queue-names.js +17 -0
  137. package/dist/kernel.module.js +3 -0
  138. package/dist/local-devices/device-policy.service.d.ts +4 -0
  139. package/dist/local-devices/device-policy.service.js +61 -3
  140. package/dist/local-devices/machines.d.ts +13 -5
  141. package/dist/local-devices/machines.js +45 -7
  142. package/dist/local-devices/policy-summary.d.ts +44 -1
  143. package/dist/local-devices/policy-summary.js +69 -0
  144. package/dist/models/embeddings.d.ts +9 -9
  145. package/dist/models/embeddings.js +11 -18
  146. package/dist/models/models.module.js +3 -0
  147. package/dist/orgs/directory-sync.js +1 -1
  148. package/dist/orgs/members.service.js +1 -1
  149. package/dist/orgs/offboarding.d.ts +50 -57
  150. package/dist/orgs/offboarding.js +117 -162
  151. package/dist/orgs/orgs.module.js +3 -0
  152. package/dist/orgs/orgs.service.d.ts +11 -5
  153. package/dist/orgs/orgs.service.js +22 -6
  154. package/dist/overrides.d.ts +23 -3
  155. package/dist/overrides.js +12 -2
  156. package/dist/platform/exclusions.js +5 -0
  157. package/dist/platform/ops/admin.ops.js +18 -2
  158. package/dist/platform/ops/catalog-admin.ops.d.ts +3 -1
  159. package/dist/platform/ops/catalog-admin.ops.js +32 -4
  160. package/dist/platform/ops/inbox.ops.js +4 -20
  161. package/dist/platform/ops/outbox.ops.d.ts +21 -0
  162. package/dist/platform/ops/outbox.ops.js +125 -0
  163. package/dist/platform/ops/platform.ops.d.ts +1 -0
  164. package/dist/platform/ops/platform.ops.js +6 -3
  165. package/dist/platform/ops/schedules.ops.js +40 -1
  166. package/dist/platform/platform-ops.module.d.ts +2 -1
  167. package/dist/platform/platform-ops.module.js +3 -0
  168. package/dist/platform/route-schemas.js +3 -0
  169. package/dist/roles/worker-role.d.ts +10 -5
  170. package/dist/roles/worker-role.js +19 -9
  171. package/dist/roles/worker.module.js +11 -8
  172. package/dist/runtime/context/build.d.ts +3 -0
  173. package/dist/runtime/context/build.js +15 -0
  174. package/dist/runtime/context/plugin-context.d.ts +20 -0
  175. package/dist/runtime/context/plugin-context.js +30 -0
  176. package/dist/runtime/langgraph-loop.js +17 -5
  177. package/dist/runtime/limits.d.ts +15 -0
  178. package/dist/runtime/limits.js +25 -0
  179. package/dist/runtime/loop.d.ts +16 -3
  180. package/dist/runtime/loop.js +2 -1
  181. package/dist/runtime/maintenance.d.ts +7 -3
  182. package/dist/runtime/maintenance.js +52 -12
  183. package/dist/runtime/model-call.d.ts +20 -17
  184. package/dist/runtime/model-call.js +15 -24
  185. package/dist/runtime/plugin-context.service.d.ts +69 -0
  186. package/dist/runtime/plugin-context.service.js +208 -0
  187. package/dist/runtime/queue-lost-jobs.d.ts +24 -0
  188. package/dist/runtime/queue-lost-jobs.js +51 -0
  189. package/dist/runtime/run-control.d.ts +47 -5
  190. package/dist/runtime/run-control.js +79 -12
  191. package/dist/runtime/run-finish.d.ts +39 -12
  192. package/dist/runtime/run-finish.js +97 -14
  193. package/dist/runtime/run-jobs.d.ts +95 -13
  194. package/dist/runtime/run-jobs.js +199 -28
  195. package/dist/runtime/run-orphan-check.job.d.ts +142 -0
  196. package/dist/runtime/run-orphan-check.job.js +339 -0
  197. package/dist/runtime/run-processors.d.ts +16 -9
  198. package/dist/runtime/run-processors.js +1 -1
  199. package/dist/runtime/run-queue.d.ts +75 -53
  200. package/dist/runtime/run-queue.js +189 -263
  201. package/dist/runtime/run-steps.d.ts +1 -2
  202. package/dist/runtime/run-steps.js +8 -11
  203. package/dist/runtime/run-worker.d.ts +26 -16
  204. package/dist/runtime/run-worker.js +132 -37
  205. package/dist/runtime/runtime.module.d.ts +2 -3
  206. package/dist/runtime/runtime.module.js +7 -6
  207. package/dist/runtime/step-log.d.ts +16 -4
  208. package/dist/runtime/step-log.js +26 -6
  209. package/dist/runtime/stream.controller.d.ts +2 -4
  210. package/dist/runtime/stream.controller.js +5 -11
  211. package/dist/runtime/subagents/child.js +1 -1
  212. package/dist/runtime/subagents/definition.d.ts +2 -1
  213. package/dist/runtime/subagents/definition.js +4 -2
  214. package/dist/runtime/subagents/deliveries.d.ts +6 -3
  215. package/dist/runtime/subagents/deliveries.js +16 -7
  216. package/dist/runtime/subagents/dispatch.d.ts +12 -12
  217. package/dist/runtime/subagents/dispatch.js +14 -38
  218. package/dist/runtime/subagents/messages.d.ts +5 -1
  219. package/dist/runtime/subagents/messages.js +11 -3
  220. package/dist/runtime/subagents/skill-fork.d.ts +3 -3
  221. package/dist/runtime/subagents/skill-fork.js +8 -5
  222. package/dist/runtime/subagents/subagents.service.js +1 -1
  223. package/dist/runtime/subagents/tree-jobs.d.ts +61 -0
  224. package/dist/runtime/subagents/tree-jobs.js +86 -0
  225. package/dist/runtime/usage-report-jobs.d.ts +23 -48
  226. package/dist/runtime/usage-report-jobs.js +67 -119
  227. package/dist/runtime/usage-report.d.ts +28 -77
  228. package/dist/runtime/usage-report.js +35 -213
  229. package/dist/runtime/waits.d.ts +48 -198
  230. package/dist/runtime/waits.js +103 -805
  231. package/dist/sandbox/jobs.d.ts +20 -10
  232. package/dist/sandbox/jobs.js +23 -17
  233. package/dist/sandbox/sandbox.service.d.ts +17 -4
  234. package/dist/sandbox/sandbox.service.js +55 -14
  235. package/dist/schedules/calendar.d.ts +134 -0
  236. package/dist/schedules/calendar.js +410 -0
  237. package/dist/schedules/fire.d.ts +26 -7
  238. package/dist/schedules/fire.js +91 -22
  239. package/dist/schedules/job-ids.d.ts +66 -17
  240. package/dist/schedules/job-ids.js +81 -13
  241. package/dist/schedules/run-tracker.d.ts +0 -5
  242. package/dist/schedules/run-tracker.js +2 -14
  243. package/dist/schedules/scan.job.d.ts +13 -32
  244. package/dist/schedules/scan.job.js +50 -164
  245. package/dist/schedules/schedule-math.d.ts +42 -0
  246. package/dist/schedules/schedule-math.js +52 -0
  247. package/dist/schedules/scheduled-tasks.service.d.ts +22 -6
  248. package/dist/schedules/scheduled-tasks.service.js +70 -14
  249. package/dist/schedules/schedules.controller.d.ts +5 -1
  250. package/dist/schedules/schedules.controller.js +15 -1
  251. package/dist/schedules/schedules.module.js +0 -4
  252. package/dist/schedules/schedules.schemas.d.ts +35 -0
  253. package/dist/schedules/schedules.schemas.js +27 -0
  254. package/dist/schedules/store.d.ts +5 -0
  255. package/dist/schedules/store.js +20 -0
  256. package/dist/skills/changes.controller.d.ts +1 -1
  257. package/dist/skills/changes.controller.js +1 -1
  258. package/dist/tools/approvals.service.d.ts +41 -11
  259. package/dist/tools/approvals.service.js +108 -14
  260. package/dist/tools/builtin-names.d.ts +5 -3
  261. package/dist/tools/builtin-names.js +12 -4
  262. package/dist/tools/builtins/builtin-tools.d.ts +1 -2
  263. package/dist/tools/builtins/builtin-tools.js +21 -17
  264. package/dist/tools/builtins/sandbox/bash.js +9 -3
  265. package/dist/tools/builtins/sandbox/common.d.ts +18 -1
  266. package/dist/tools/builtins/sandbox/common.js +14 -1
  267. package/dist/tools/builtins/sandbox/index.d.ts +2 -1
  268. package/dist/tools/builtins/sandbox/index.js +4 -1
  269. package/dist/tools/builtins/sandbox/task-list.d.ts +12 -0
  270. package/dist/tools/builtins/sandbox/task-list.js +130 -0
  271. package/dist/tools/builtins/sandbox/task-output.d.ts +8 -1
  272. package/dist/tools/builtins/sandbox/task-output.js +21 -3
  273. package/dist/tools/builtins/web/extract.d.ts +2 -4
  274. package/dist/tools/builtins/web/extract.js +2 -5
  275. package/dist/tools/pipeline.d.ts +12 -3
  276. package/dist/tools/pipeline.js +6 -1
  277. package/dist/tools/questions.service.d.ts +30 -10
  278. package/dist/tools/questions.service.js +41 -27
  279. package/dist/tools/registry.d.ts +12 -3
  280. package/dist/tools/registry.js +13 -3
  281. package/dist/tools/tools.module.js +4 -3
  282. package/package.json +3 -3
  283. package/src/migrations/0118_device_policy_ops.sql +6 -0
  284. package/src/migrations/0119_outbox.sql +22 -0
  285. package/src/migrations/0120_drop_usage_report_sweep.sql +7 -0
  286. package/src/migrations/0121_drop_platform_migration_runs.sql +12 -0
  287. package/src/migrations/0122_drop_scheduled_task_runs_rechecked_at.sql +5 -0
  288. package/src/migrations/0123_pgvector.sql +27 -0
  289. package/src/migrations/0124_conversation_source.sql +36 -0
  290. package/dist/catalog/platform-migration.d.ts +0 -115
  291. package/dist/catalog/platform-migration.js +0 -583
  292. package/dist/infra/queue/add-job-once.d.ts +0 -14
  293. package/dist/infra/queue/add-job-once.js +0 -16
package/bootstrap.json CHANGED
@@ -3,103 +3,103 @@
3
3
  "schemaVersion": 1,
4
4
  "marketplace": {
5
5
  "url": "https://github.com/capybara-hq/plugins.git",
6
- "commit": "050de1403662d2ba04cb96839b742aaa0166c00e"
6
+ "commit": "4bfd588739e5cec6f2177d4e8f72e43a4dae50f3"
7
7
  },
8
8
  "plugins": [
9
9
  {
10
10
  "name": "openai-compatible",
11
11
  "source": "npm",
12
12
  "npm": "@capybara-hq/plugin-openai-compatible",
13
- "version": "0.1.0-rc.7",
14
- "integrity": "sha512-EVsWj0bJns6DirtzTXIbXrrktoiJbZi+8NeLzYpZ53Gwo4hNoNAaIhnfHge9RBhSgZ0xMTKEAP/PlyQ6uasAVA==",
13
+ "version": "0.1.0-rc.8",
14
+ "integrity": "sha512-IDINuU0r2JONeoEneACLhqnIeDCHX0AICaUJd8TeVmCbzsjMPlchTXngFQin66UN3jqi92yhFDGMKixLsArVCA==",
15
15
  "required": true
16
16
  },
17
17
  {
18
18
  "name": "object-store-s3",
19
19
  "source": "npm",
20
20
  "npm": "@capybara-hq/plugin-object-store-s3",
21
- "version": "0.1.0-rc.6",
22
- "integrity": "sha512-zoJ0DDzeZ1WHxZZyHL/D855FTI2Mdjb0Z5RCqWu745eHA4+5DbboBiHsxSwyzQHp7LixyVQLoWxjFgdXCOkcFw==",
21
+ "version": "0.1.0-rc.7",
22
+ "integrity": "sha512-7HHh45e2CiMxQVfMEKexdRkT7k2iUqznNWMEVazzd+rhT4tguLVY8TkWClv4EK246fqVXvnj48rmmL6Dd6oTvw==",
23
23
  "required": true
24
24
  },
25
25
  {
26
26
  "name": "anthropic",
27
27
  "source": "npm",
28
28
  "npm": "@capybara-hq/plugin-anthropic",
29
- "version": "0.1.0-rc.6",
30
- "integrity": "sha512-x3/vR09Rlcw+kikk9ztmD4fqG0ThscAjAP+R2IOfQxqMNLfcppF0S6zGAWibof3qJ0LG/dr3o0yyH3j20TGlRg==",
29
+ "version": "0.1.0-rc.7",
30
+ "integrity": "sha512-yjUyDqJppihZmhgLVomFbhf1Iek31xyJ4W4+It4Dy3K4wsyZV9khhWrm9x1xxtcb1RvDIGgUxRmvLgoTIeUTYQ==",
31
31
  "required": false
32
32
  },
33
33
  {
34
34
  "name": "openai",
35
35
  "source": "npm",
36
36
  "npm": "@capybara-hq/plugin-openai",
37
- "version": "0.1.0-rc.7",
38
- "integrity": "sha512-67wjrPJd8/CUzTLOxK+rw1dBL2iCzQ5nj9Zg4R6M6K046i/yp8RGLJiYfFags8SFk3yHCBdQIigBWRsFF7HOfg==",
37
+ "version": "0.1.0-rc.8",
38
+ "integrity": "sha512-n8IRL9u+yxmtd/aEntgSdTswjTDdhn2tjXTN9FWARGI+dTQnsbkX9108P4T31kmOBVcuwPYzNB09NG+im2LQIg==",
39
39
  "required": false
40
40
  },
41
41
  {
42
42
  "name": "deepseek",
43
43
  "source": "npm",
44
44
  "npm": "@capybara-hq/plugin-deepseek",
45
- "version": "0.1.0-rc.6",
46
- "integrity": "sha512-MO04BQm08JexZ+Pns/I8x6zWG5lSlXuADM2tZaE6/61hA3L1qKnZly9vmE8H6tt+JgbPZda+lMrINhbQ4biv2A==",
45
+ "version": "0.1.0-rc.7",
46
+ "integrity": "sha512-f0kYjYzvwxPtT2bnpf7fYkggMHvlLTJX7bacaWnIoR1cHeTxiNKuvOv8ptkztpkgTmKadjKqllI5b9AOhhILRg==",
47
47
  "required": false
48
48
  },
49
49
  {
50
50
  "name": "bailian",
51
51
  "source": "npm",
52
52
  "npm": "@capybara-hq/plugin-bailian",
53
- "version": "0.1.0-rc.6",
54
- "integrity": "sha512-dqj7fnUkjs5PnsJsqolkZMZ/a+MWz2yMSORiecyRPoM5hNNgc1LY0jtoTLTOFxG6b5sMJJ0iqyISDrZeV4ScyQ==",
53
+ "version": "0.1.0-rc.7",
54
+ "integrity": "sha512-VqTq6mjzka+iEW5BdcZspBdkWSQ1mLsLueg/XABaZzNDEAE/a6ErDE10GadzOTzorqAttXebTLJDjJebgLmtwA==",
55
55
  "required": false
56
56
  },
57
57
  {
58
58
  "name": "ark",
59
59
  "source": "npm",
60
60
  "npm": "@capybara-hq/plugin-ark",
61
- "version": "0.1.0-rc.6",
62
- "integrity": "sha512-VamP4U4zU6d9uvSAIo9KLxqh0Vt05EnexOF+78W3oY35YrNRXevk/ABFGMVwGEflq9LiJYJ6xisl38t3Aq5fDA==",
61
+ "version": "0.1.0-rc.7",
62
+ "integrity": "sha512-Ml/HS3w3fD4x0gh/Yh0jbz8Riv8x7Jkd5phPZUsKDtuE4pvr+hllRYOxs9p0/Lax11BDvbUK9EFzRkCa+xAQeQ==",
63
63
  "required": false
64
64
  },
65
65
  {
66
66
  "name": "connector-mcp",
67
67
  "source": "npm",
68
68
  "npm": "@capybara-hq/plugin-connector-mcp",
69
- "version": "0.1.0-rc.6",
70
- "integrity": "sha512-p8YmmutRTdj5auF5Ua5ox77S1tht+2URguehopjFaK8Cl34rURM4hY0f7WSJ5Xj884156HBua4AmsBTaDMiasQ==",
69
+ "version": "0.1.0-rc.7",
70
+ "integrity": "sha512-hJlW+u1iLt/mKJ9iPBbGT6tbpGevPVTS+8dvLtPbpf2fFRhM2eLrQy6+zuKUhuVQCcJYBrpz4vu5vh1ZBkqNZg==",
71
71
  "required": false
72
72
  },
73
73
  {
74
74
  "name": "connector-openapi",
75
75
  "source": "npm",
76
76
  "npm": "@capybara-hq/plugin-connector-openapi",
77
- "version": "0.1.0-rc.7",
78
- "integrity": "sha512-hcLe9Ay6ho6C1dFXtVk7VU6kL9NYmjjbh2+7dXl4BJYglGwrGbfVr0FN7TNRQ+Bsy2ni4BuSsJSGv6BYOp6/EA==",
77
+ "version": "0.1.0-rc.8",
78
+ "integrity": "sha512-2WU6sU0yAeWDy10DZ2I45uv2I6Q1FQDKvok2W0r6dfIO11G9iTsRNIMbtNsdVO2OUWY8nhAgh95BXBrpUELELQ==",
79
79
  "required": false
80
80
  },
81
81
  {
82
82
  "name": "jina",
83
83
  "source": "npm",
84
84
  "npm": "@capybara-hq/plugin-jina",
85
- "version": "0.1.0-rc.6",
86
- "integrity": "sha512-ViVwzmq4Ic4iJ7vnwYFSRHm3ON96npVDvcLQH7CqIkpUAKabt8GNBVuD5yAeadKmXY3Gn76VkfjjfmHzJgbOMw==",
85
+ "version": "0.1.0-rc.7",
86
+ "integrity": "sha512-rpr59xbQJg+DuzhnAjn7Ql0rW9Cw9gKWHpER9nKvILvEYjEurmhniJkkqeHMnMlPba8lNUeQRGzmxdmLfKA10g==",
87
87
  "required": false
88
88
  },
89
89
  {
90
90
  "name": "sandbox-docker",
91
91
  "source": "npm",
92
92
  "npm": "@capybara-hq/plugin-sandbox-docker",
93
- "version": "0.1.0-rc.10",
94
- "integrity": "sha512-nDdaWCgrGoAfOiaKMVGheCLTlbFtSo10+8sgPSmJCO4z2LJW0qDMuN7rPwd3QnFsBReNeBwDB5fT6eHscNWDqw==",
93
+ "version": "0.1.0-rc.12",
94
+ "integrity": "sha512-c1iTAu/ifkwfnvVOsxEDfxEJNU7HDVewDtX4vdibwpodIhBvxz8tGjGYJ0HXDL3ipGEodiiIgJsVpabnMQ6cBQ==",
95
95
  "required": false
96
96
  },
97
97
  {
98
98
  "name": "todo",
99
99
  "source": "npm",
100
100
  "npm": "@capybara-hq/plugin-todo",
101
- "version": "0.1.0-rc.6",
102
- "integrity": "sha512-AOKLpoaBfOQUWnP9nszg9DQWR+6z5gl+ZHoTlHysA9LAeC2h/zipjGE9hY69HF9rueSHzM2kGESJLvXIuQODAA==",
101
+ "version": "0.1.0-rc.8",
102
+ "integrity": "sha512-xNdzvAmOQmBaDj29hsvbhMJINy2xe+ILTqG+cQhUfsyar7gUJaVOehseufvIq+cVbTjkI2tW7XlwGrtP3E3NtA==",
103
103
  "required": false
104
104
  },
105
105
  {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Deployment administration: the setup wizard, the platform-level audit log and the admin overview
3
- * with its health read and seven-day usage aggregate (its controllers are the api role's, `ApiModule`).
3
+ * with its health read, seven-day usage aggregate and dead outbox rows (its controllers are the api
4
+ * role's, `ApiModule`).
4
5
  */
5
6
  export declare class AdminModule {
6
7
  }
@@ -10,14 +10,16 @@ import { ChannelsModule } from "../channels/channels.module.js";
10
10
  import { TitlesModule } from "../conversations/titles.js";
11
11
  import { EvalsModule } from "../evals/evals.module.js";
12
12
  import { ExtensionsModule } from "../extensions/extensions.module.js";
13
+ import { LifecycleHooksModule } from "../extensions/lifecycle-hooks.js";
13
14
  import { IdentityModule } from "../identity/identity.module.js";
14
15
  import { InboxModule } from "../inbox/inbox.module.js";
15
16
  import { ModelsModule } from "../models/models.module.js";
16
17
  import { OrgsModule } from "../orgs/orgs.module.js";
17
18
  import { ProvidersModule } from "../runtime/providers.js";
18
19
  import { RunJobsModule } from "../runtime/run-jobs.js";
19
- import { UsageReportJobsModule } from "../runtime/usage-report-jobs.js";
20
+ import { UsageReportModule } from "../runtime/usage-report.js";
20
21
  import { AdminHealthService } from "./health.service.js";
22
+ import { OutboxDeadService } from "./outbox-dead.service.js";
21
23
  import { AdminOverviewService } from "./overview.service.js";
22
24
  import { PlatformAuditService } from "./platform-audit.service.js";
23
25
  import { SetupService } from "./setup.service.js";
@@ -25,7 +27,8 @@ import { SetupLockModule } from "./setup-lock.js";
25
27
  import { AdminUsageService } from "./usage.service.js";
26
28
  /**
27
29
  * Deployment administration: the setup wizard, the platform-level audit log and the admin overview
28
- * with its health read and seven-day usage aggregate (its controllers are the api role's, `ApiModule`).
30
+ * with its health read, seven-day usage aggregate and dead outbox rows (its controllers are the api
31
+ * role's, `ApiModule`).
29
32
  */
30
33
  let AdminModule = class AdminModule {
31
34
  };
@@ -44,8 +47,9 @@ AdminModule = __decorate([
44
47
  RunJobsModule,
45
48
  ChannelsModule,
46
49
  TitlesModule,
47
- UsageReportJobsModule,
50
+ UsageReportModule,
48
51
  EvalsModule,
52
+ LifecycleHooksModule,
49
53
  // the price table of the usage aggregate
50
54
  ModelsModule,
51
55
  ],
@@ -55,6 +59,7 @@ AdminModule = __decorate([
55
59
  AdminOverviewService,
56
60
  AdminHealthService,
57
61
  AdminUsageService,
62
+ OutboxDeadService,
58
63
  ],
59
64
  exports: [
60
65
  SetupService,
@@ -62,6 +67,7 @@ AdminModule = __decorate([
62
67
  AdminOverviewService,
63
68
  AdminHealthService,
64
69
  AdminUsageService,
70
+ OutboxDeadService,
65
71
  ],
66
72
  })
67
73
  ], AdminModule);
@@ -4,7 +4,7 @@ import { KernelDb } from "../infra/database/kernel-db.js";
4
4
  import { type LiveReplica, ReplicaPresence } from "../infra/presence/replica-presence.js";
5
5
  import type { KernelLogger } from "../log.js";
6
6
  /** The kernel's own queues, in the order the overview lists them (extension queues are not read). */
7
- export declare const KERNEL_QUEUE_NAMES: readonly ["cap-kernel-runs", "cap-kernel-subagent-runs", "cap-kernel-channels", "cap-kernel-maintenance", "cap-kernel-plugin-scope", "cap-kernel-titles", "cap-kernel-usage-report", "cap-kernel-evals"];
7
+ export declare const KERNEL_QUEUE_NAMES: readonly ["cap-kernel-runs", "cap-kernel-subagent-runs", "cap-kernel-channels", "cap-kernel-maintenance", "cap-kernel-plugin-scope", "cap-kernel-titles", "cap-kernel-usage-report", "cap-kernel-evals", "cap-kernel-lifecycle"];
8
8
  /** How long each source's reads may take before the answer marks it unavailable. */
9
9
  export declare const HEALTH_READ_TIMEOUT_MS = 3000;
10
10
  /** A live replica as the overview shows it. */
@@ -97,7 +97,7 @@ export declare class AdminHealthService {
97
97
  private readonly redis;
98
98
  private readonly log;
99
99
  private readonly queues;
100
- constructor(presence: Pick<ReplicaPresence, "live">, db: KernelDb, redis: Pick<Redis, "zcount" | "status">, log: Pick<KernelLogger, "warn">, runs: Queue, subagentRuns: Queue, channels: Queue, maintenance: Queue, pluginScope: Queue, titles: Queue, usageReport: Queue, evals: Queue);
100
+ constructor(presence: Pick<ReplicaPresence, "live">, db: KernelDb, redis: Pick<Redis, "zcount" | "status">, log: Pick<KernelLogger, "warn">, runs: Queue, subagentRuns: Queue, channels: Queue, maintenance: Queue, pluginScope: Queue, titles: Queue, usageReport: Queue, evals: Queue, lifecycle: Queue);
101
101
  read(): Promise<AdminHealth>;
102
102
  private readRedis;
103
103
  private readDb;
@@ -14,6 +14,7 @@ import { PLUGIN_SCOPE_QUEUE } from "../catalog/scope-sync.js";
14
14
  import { CHANNEL_QUEUE_NAME } from "../channels/jobs.js";
15
15
  import { TITLE_QUEUE } from "../conversations/titles.js";
16
16
  import { EVAL_QUEUE_NAME } from "../evals/jobs.js";
17
+ import { LIFECYCLE_QUEUE } from "../extensions/lifecycle-hooks.js";
17
18
  import { KernelDb } from "../infra/database/kernel-db.js";
18
19
  import { ReplicaPresence } from "../infra/presence/replica-presence.js";
19
20
  import { KERNEL_LOGGER, REDIS } from "../infra/tokens.js";
@@ -31,6 +32,7 @@ export const KERNEL_QUEUE_NAMES = [
31
32
  TITLE_QUEUE,
32
33
  USAGE_REPORT_QUEUE,
33
34
  EVAL_QUEUE_NAME,
35
+ LIFECYCLE_QUEUE,
34
36
  ];
35
37
  /** How long each source's reads may take before the answer marks it unavailable. */
36
38
  export const HEALTH_READ_TIMEOUT_MS = 3_000;
@@ -58,7 +60,7 @@ let AdminHealthService = class AdminHealthService {
58
60
  redis;
59
61
  log;
60
62
  queues;
61
- constructor(presence, db, redis, log, runs, subagentRuns, channels, maintenance, pluginScope, titles, usageReport, evals) {
63
+ constructor(presence, db, redis, log, runs, subagentRuns, channels, maintenance, pluginScope, titles, usageReport, evals, lifecycle) {
62
64
  this.presence = presence;
63
65
  this.db = db;
64
66
  this.redis = redis;
@@ -73,6 +75,7 @@ let AdminHealthService = class AdminHealthService {
73
75
  titles,
74
76
  usageReport,
75
77
  evals,
78
+ lifecycle,
76
79
  ];
77
80
  }
78
81
  async read() {
@@ -241,6 +244,7 @@ AdminHealthService = __decorate([
241
244
  __param(8, Inject(getQueueToken(PLUGIN_SCOPE_QUEUE))),
242
245
  __param(9, Inject(getQueueToken(TITLE_QUEUE))),
243
246
  __param(10, Inject(getQueueToken(USAGE_REPORT_QUEUE))),
244
- __param(11, Inject(getQueueToken(EVAL_QUEUE_NAME)))
247
+ __param(11, Inject(getQueueToken(EVAL_QUEUE_NAME))),
248
+ __param(12, Inject(getQueueToken(LIFECYCLE_QUEUE)))
245
249
  ], AdminHealthService);
246
250
  export { AdminHealthService };
@@ -0,0 +1,23 @@
1
+ import type { z } from "zod";
2
+ import { type Principal } from "../identity/principal.js";
3
+ import { OutboxDeadParams } from "./outbox-dead.schemas.js";
4
+ import { type OutboxDeadRow, OutboxDeadService, type OutboxRetryOutcome } from "./outbox-dead.service.js";
5
+ /**
6
+ * Dead outbox rows (`/api/v1/admin/outbox/dead*`, transactional outbox spec §3.4): background work
7
+ * the kernel could not queue after its last attempt. Super admins only; service tokens 403. Retry
8
+ * and discard are audited (`outbox.retried`, `outbox.discarded`); the list is not (decision D5).
9
+ */
10
+ export declare class OutboxDeadController {
11
+ private readonly dead;
12
+ constructor(dead: OutboxDeadService);
13
+ /** The dead rows, oldest first (at most 200). */
14
+ list(): Promise<{
15
+ items: OutboxDeadRow[];
16
+ }>;
17
+ /** Makes the row due again, or discards it when the same job is owed already (`already_owed`). */
18
+ retry(principal: Principal, { id }: z.infer<typeof OutboxDeadParams>): Promise<{
19
+ outcome: OutboxRetryOutcome;
20
+ }>;
21
+ /** Deletes the row: its job is never delivered. */
22
+ discard(principal: Principal, { id }: z.infer<typeof OutboxDeadParams>): Promise<void>;
23
+ }
@@ -0,0 +1,62 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
8
+ return function (target, key) { decorator(target, key, paramIndex); }
9
+ };
10
+ import { Controller, Delete, Get, HttpCode, Inject, Post } from "@nestjs/common";
11
+ import { CurrentPrincipal, SuperAdmin } from "../identity/principal.js";
12
+ import { writeActorOf } from "../identity/write-actor.js";
13
+ import { createZodDto } from "../infra/validation/create-zod-dto.js";
14
+ import { ZParam } from "../infra/validation/zod-params.js";
15
+ import { OutboxDeadParams } from "./outbox-dead.schemas.js";
16
+ import { OutboxDeadService, } from "./outbox-dead.service.js";
17
+ class OutboxDeadParamsDto extends createZodDto(OutboxDeadParams, "OutboxDeadParams") {
18
+ }
19
+ /**
20
+ * Dead outbox rows (`/api/v1/admin/outbox/dead*`, transactional outbox spec §3.4): background work
21
+ * the kernel could not queue after its last attempt. Super admins only; service tokens 403. Retry
22
+ * and discard are audited (`outbox.retried`, `outbox.discarded`); the list is not (decision D5).
23
+ */
24
+ let OutboxDeadController = class OutboxDeadController {
25
+ dead;
26
+ constructor(dead) {
27
+ this.dead = dead;
28
+ }
29
+ /** The dead rows, oldest first (at most 200). */
30
+ list() {
31
+ return this.dead.list();
32
+ }
33
+ /** Makes the row due again, or discards it when the same job is owed already (`already_owed`). */
34
+ retry(principal, { id }) {
35
+ return this.dead.retry(id, writeActorOf(principal));
36
+ }
37
+ /** Deletes the row: its job is never delivered. */
38
+ async discard(principal, { id }) {
39
+ await this.dead.discard(id, writeActorOf(principal));
40
+ }
41
+ };
42
+ __decorate([
43
+ Get()
44
+ ], OutboxDeadController.prototype, "list", null);
45
+ __decorate([
46
+ Post(":id/retry"),
47
+ HttpCode(200),
48
+ __param(0, CurrentPrincipal()),
49
+ __param(1, ZParam(OutboxDeadParamsDto))
50
+ ], OutboxDeadController.prototype, "retry", null);
51
+ __decorate([
52
+ Delete(":id"),
53
+ HttpCode(204),
54
+ __param(0, CurrentPrincipal()),
55
+ __param(1, ZParam(OutboxDeadParamsDto))
56
+ ], OutboxDeadController.prototype, "discard", null);
57
+ OutboxDeadController = __decorate([
58
+ Controller("api/v1/admin/outbox/dead"),
59
+ SuperAdmin(),
60
+ __param(0, Inject(OutboxDeadService))
61
+ ], OutboxDeadController);
62
+ export { OutboxDeadController };
@@ -0,0 +1,8 @@
1
+ import { z } from "zod";
2
+ import type { RouteSchemas } from "../platform/route-schemas.js";
3
+ /** A dead outbox row by id (`bigint` identity, read as a string; 400 when not digits). */
4
+ export declare const OutboxDeadParams: z.ZodObject<{
5
+ id: z.ZodString;
6
+ }, z.core.$strip>;
7
+ /** The super admin's dead outbox rows (transactional outbox spec §3.4). */
8
+ export declare const OUTBOX_DEAD_ROUTES: readonly RouteSchemas[];
@@ -0,0 +1,18 @@
1
+ import { z } from "zod";
2
+ /** The largest `bigint` id; a larger one would make PG refuse the comparison. */
3
+ const MAX_BIGINT = 9223372036854775807n;
4
+ /** A dead outbox row by id (`bigint` identity, read as a string; 400 when not digits). */
5
+ export const OutboxDeadParams = z.object({
6
+ id: z
7
+ .string()
8
+ .regex(/^\d{1,19}$/, "id must be an outbox row id (digits)")
9
+ // checks do not abort: only digits reach BigInt
10
+ .refine((v) => !/^\d{1,19}$/.test(v) || BigInt(v) <= MAX_BIGINT, "id must be an outbox row id")
11
+ .describe("The dead row's id, as admin.outbox-list-dead lists it."),
12
+ });
13
+ /** The super admin's dead outbox rows (transactional outbox spec §3.4). */
14
+ export const OUTBOX_DEAD_ROUTES = [
15
+ { route: "GET /api/v1/admin/outbox/dead" },
16
+ { route: "POST /api/v1/admin/outbox/dead/:id/retry", params: OutboxDeadParams },
17
+ { route: "DELETE /api/v1/admin/outbox/dead/:id", params: OutboxDeadParams },
18
+ ];
@@ -0,0 +1,66 @@
1
+ import type { WriteActor } from "../identity/write-actor.js";
2
+ import { KernelDb } from "../infra/database/kernel-db.js";
3
+ import { TransactionHost } from "../infra/database/transaction-host.js";
4
+ import { type OutboxFastPath } from "../infra/outbox/outbox.service.js";
5
+ /** The most dead rows `GET /api/v1/admin/outbox/dead` returns, oldest first. */
6
+ export declare const OUTBOX_DEAD_LIST_MAX = 200;
7
+ /** A dead outbox row as the super admin sees it (transactional outbox spec §3.4). */
8
+ export interface OutboxDeadRow {
9
+ id: string;
10
+ queue: string;
11
+ jobName: string;
12
+ jobId: string;
13
+ /** The org the work belongs to; null for platform work (or an org deleted since). */
14
+ orgId: string | null;
15
+ attempts: number;
16
+ lastError: string | null;
17
+ deadAt: string;
18
+ createdAt: string;
19
+ }
20
+ /** Dead rows in all: how many and since when (the overview's `outbox_dead` attention item). */
21
+ export interface OutboxDeadSummary {
22
+ count: number;
23
+ oldestAt: Date | null;
24
+ }
25
+ /**
26
+ * What a retry did: `retried` (the row is due again, the relay delivers it) or `already_owed`
27
+ * (the same job is owed by a pending row already, so the dead copy was discarded: ruling R8).
28
+ */
29
+ export type OutboxRetryOutcome = "retried" | "already_owed";
30
+ /**
31
+ * The super admin's dead outbox rows (transactional outbox spec §3.4): the rows the dispatcher
32
+ * gave up on after its last attempt. Nothing is dropped silently: a row stays until a super admin
33
+ * retries it (it is due again with fresh attempts) or discards it, each audited at platform level
34
+ * (`outbox.retried`, `outbox.discarded`). A retry does not look at what the job is about: every
35
+ * job name added through the outbox is harmless when its work is gone or done (spec §3.5).
36
+ */
37
+ export declare class OutboxDeadService {
38
+ readonly txHost: TransactionHost;
39
+ private readonly db;
40
+ private readonly fastPath;
41
+ constructor(txHost: TransactionHost, db: KernelDb, fastPath: OutboxFastPath);
42
+ /** The dead rows, oldest first, at most {@link OUTBOX_DEAD_LIST_MAX}. */
43
+ list(): Promise<{
44
+ items: OutboxDeadRow[];
45
+ }>;
46
+ /** How many rows are dead, and the oldest one's `dead_at`. */
47
+ summary(): Promise<OutboxDeadSummary>;
48
+ /**
49
+ * Makes a dead row due again (`dead_at` cleared, no attempts, next attempt now) and hands it to
50
+ * the fast path after the commit; the relay delivers it otherwise. When the same (queue, job id)
51
+ * is owed by a pending row already, the dead row is deleted instead (`already_owed`). A pending
52
+ * row added between the check and the update fails the update on the unique index: the retry
53
+ * then runs once more and takes the `already_owed` branch. `outbox.not_found` (404) when no dead
54
+ * row has the id.
55
+ */
56
+ retry(id: string, actor: WriteActor, detail?: Record<string, unknown>): Promise<{
57
+ outcome: OutboxRetryOutcome;
58
+ }>;
59
+ private retryOnce;
60
+ /** Deletes a dead row: its job is never delivered. `outbox.not_found` (404) when none. */
61
+ discard(id: string, actor: WriteActor, detail?: Record<string, unknown>): Promise<void>;
62
+ /** The dead row `id`, locked for the transaction; `outbox.not_found` when it is not dead. */
63
+ private lockDead;
64
+ /** A platform-level audit event (no org: the outbox is the deployment's), naming the job. */
65
+ private audit;
66
+ }
@@ -0,0 +1,179 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
8
+ return function (target, key) { decorator(target, key, paramIndex); }
9
+ };
10
+ import { Inject, Injectable } from "@nestjs/common";
11
+ import { sql } from "kysely";
12
+ import { ApiError } from "../errors.js";
13
+ import { audit } from "../identity/audit.js";
14
+ import { afterCommit } from "../infra/database/after-commit.js";
15
+ import { KernelDb } from "../infra/database/kernel-db.js";
16
+ import { TransactionHost } from "../infra/database/transaction-host.js";
17
+ import { Transactional } from "../infra/database/transactional.decorator.js";
18
+ import { OUTBOX_FAST_PATH } from "../infra/outbox/outbox.service.js";
19
+ /** The most dead rows `GET /api/v1/admin/outbox/dead` returns, oldest first. */
20
+ export const OUTBOX_DEAD_LIST_MAX = 200;
21
+ /** The unique index of pending rows (0119): one pending row per (queue, job_id). */
22
+ const PENDING_UNIQUE = "outbox_job_uniq";
23
+ const isPendingConflict = (e) => typeof e === "object" &&
24
+ e !== null &&
25
+ e.code === "23505" &&
26
+ e.constraint === PENDING_UNIQUE;
27
+ const notFound = (id) => new ApiError("outbox.not_found", `No dead outbox row ${id}; list them with GET /api/v1/admin/outbox/dead`);
28
+ /**
29
+ * The super admin's dead outbox rows (transactional outbox spec §3.4): the rows the dispatcher
30
+ * gave up on after its last attempt. Nothing is dropped silently: a row stays until a super admin
31
+ * retries it (it is due again with fresh attempts) or discards it, each audited at platform level
32
+ * (`outbox.retried`, `outbox.discarded`). A retry does not look at what the job is about: every
33
+ * job name added through the outbox is harmless when its work is gone or done (spec §3.5).
34
+ */
35
+ let OutboxDeadService = class OutboxDeadService {
36
+ txHost;
37
+ db;
38
+ fastPath;
39
+ constructor(txHost, db, fastPath) {
40
+ this.txHost = txHost;
41
+ this.db = db;
42
+ this.fastPath = fastPath;
43
+ }
44
+ /** The dead rows, oldest first, at most {@link OUTBOX_DEAD_LIST_MAX}. */
45
+ async list() {
46
+ const rows = await this.db.db
47
+ .selectFrom("outbox")
48
+ .select([
49
+ "id",
50
+ "queue",
51
+ "job_name",
52
+ "job_id",
53
+ "org_id",
54
+ "attempts",
55
+ "last_error",
56
+ "dead_at",
57
+ "created_at",
58
+ ])
59
+ .where("dead_at", "is not", null)
60
+ .orderBy("dead_at")
61
+ .orderBy("id")
62
+ .limit(OUTBOX_DEAD_LIST_MAX)
63
+ .execute();
64
+ return {
65
+ items: rows.map((r) => ({
66
+ id: String(r.id),
67
+ queue: r.queue,
68
+ jobName: r.job_name,
69
+ jobId: r.job_id,
70
+ orgId: r.org_id,
71
+ attempts: r.attempts,
72
+ lastError: r.last_error,
73
+ deadAt: r.dead_at.toISOString(),
74
+ createdAt: r.created_at.toISOString(),
75
+ })),
76
+ };
77
+ }
78
+ /** How many rows are dead, and the oldest one's `dead_at`. */
79
+ async summary() {
80
+ const row = await this.db.db
81
+ .selectFrom("outbox")
82
+ .select([sql `count(*)`.as("count"), sql `min(dead_at)`.as("oldest")])
83
+ .where("dead_at", "is not", null)
84
+ .executeTakeFirstOrThrow();
85
+ return { count: Number(row.count), oldestAt: row.oldest };
86
+ }
87
+ /**
88
+ * Makes a dead row due again (`dead_at` cleared, no attempts, next attempt now) and hands it to
89
+ * the fast path after the commit; the relay delivers it otherwise. When the same (queue, job id)
90
+ * is owed by a pending row already, the dead row is deleted instead (`already_owed`). A pending
91
+ * row added between the check and the update fails the update on the unique index: the retry
92
+ * then runs once more and takes the `already_owed` branch. `outbox.not_found` (404) when no dead
93
+ * row has the id.
94
+ */
95
+ async retry(id, actor, detail = {}) {
96
+ try {
97
+ return await this.retryOnce(id, actor, detail);
98
+ }
99
+ catch (e) {
100
+ if (!isPendingConflict(e))
101
+ throw e;
102
+ return this.retryOnce(id, actor, detail);
103
+ }
104
+ }
105
+ async retryOnce(id, actor, detail) {
106
+ const row = await this.lockDead(id);
107
+ const owed = await this.db.db
108
+ .selectFrom("outbox")
109
+ .select("id")
110
+ .where("queue", "=", row.queue)
111
+ .where("job_id", "=", row.job_id)
112
+ .where("dead_at", "is", null)
113
+ .executeTakeFirst();
114
+ let outcome;
115
+ if (owed) {
116
+ await this.db.db.deleteFrom("outbox").where("id", "=", id).execute();
117
+ outcome = "already_owed";
118
+ }
119
+ else {
120
+ await this.db.db
121
+ .updateTable("outbox")
122
+ .set({ dead_at: null, attempts: 0, next_attempt_at: sql `now()` })
123
+ .where("id", "=", id)
124
+ .execute();
125
+ outcome = "retried";
126
+ afterCommit(() => this.fastPath([id]));
127
+ }
128
+ await this.audit("outbox.retried", id, row, actor, { outcome, ...detail });
129
+ return { outcome };
130
+ }
131
+ /** Deletes a dead row: its job is never delivered. `outbox.not_found` (404) when none. */
132
+ async discard(id, actor, detail = {}) {
133
+ const row = await this.lockDead(id);
134
+ await this.db.db.deleteFrom("outbox").where("id", "=", id).execute();
135
+ await this.audit("outbox.discarded", id, row, actor, detail);
136
+ }
137
+ /** The dead row `id`, locked for the transaction; `outbox.not_found` when it is not dead. */
138
+ async lockDead(id) {
139
+ const row = await this.db.db
140
+ .selectFrom("outbox")
141
+ .select(["queue", "job_name", "job_id", "org_id", "attempts", "last_error"])
142
+ .where("id", "=", id)
143
+ .where("dead_at", "is not", null)
144
+ .forUpdate()
145
+ .executeTakeFirst();
146
+ if (!row)
147
+ throw notFound(id);
148
+ return row;
149
+ }
150
+ /** A platform-level audit event (no org: the outbox is the deployment's), naming the job. */
151
+ audit(action, id, row, actor, detail) {
152
+ return audit(this.db.db, {
153
+ actorAccountId: actor.accountId,
154
+ ...(actor.tokenId !== undefined && { actorTokenId: actor.tokenId }),
155
+ action,
156
+ target: id,
157
+ detail: {
158
+ queue: row.queue,
159
+ jobName: row.job_name,
160
+ jobId: row.job_id,
161
+ ...(row.org_id !== null && { orgId: row.org_id }),
162
+ ...detail,
163
+ },
164
+ });
165
+ }
166
+ };
167
+ __decorate([
168
+ Transactional()
169
+ ], OutboxDeadService.prototype, "retryOnce", null);
170
+ __decorate([
171
+ Transactional()
172
+ ], OutboxDeadService.prototype, "discard", null);
173
+ OutboxDeadService = __decorate([
174
+ Injectable(),
175
+ __param(0, Inject(TransactionHost)),
176
+ __param(1, Inject(KernelDb)),
177
+ __param(2, Inject(OUTBOX_FAST_PATH))
178
+ ], OutboxDeadService);
179
+ export { OutboxDeadService };