@capybara-hq/kernel 0.1.0-rc.0 → 0.1.0-rc.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 (626) hide show
  1. package/bootstrap.json +10 -6
  2. package/dist/admin/admin.controller.d.ts +17 -17
  3. package/dist/admin/admin.controller.js +43 -26
  4. package/dist/admin/admin.module.d.ts +3 -0
  5. package/dist/admin/admin.module.js +22 -0
  6. package/dist/admin/extensions.controller.d.ts +14 -14
  7. package/dist/admin/extensions.controller.js +30 -17
  8. package/dist/admin/setup-lock.d.ts +16 -0
  9. package/dist/admin/setup-lock.js +47 -0
  10. package/dist/admin/setup.controller.d.ts +8 -8
  11. package/dist/admin/setup.controller.js +27 -25
  12. package/dist/admin/setup.service.d.ts +19 -27
  13. package/dist/admin/setup.service.js +61 -61
  14. package/dist/agents/agent-lookup.d.ts +53 -0
  15. package/dist/agents/agent-lookup.js +179 -0
  16. package/dist/agents/agents.controller.d.ts +1 -1
  17. package/dist/agents/agents.controller.js +14 -8
  18. package/dist/agents/agents.module.d.ts +7 -0
  19. package/dist/agents/agents.module.js +41 -0
  20. package/dist/agents/agents.service.d.ts +39 -58
  21. package/dist/agents/agents.service.js +261 -329
  22. package/dist/agents/definition.d.ts +8 -0
  23. package/dist/agents/definition.js +8 -0
  24. package/dist/agents/models.controller.d.ts +1 -1
  25. package/dist/agents/models.controller.js +2 -2
  26. package/dist/agents/templates.controller.d.ts +1 -1
  27. package/dist/agents/templates.controller.js +2 -2
  28. package/dist/agents/templates.d.ts +6 -8
  29. package/dist/agents/templates.js +20 -4
  30. package/dist/app.d.ts +93 -0
  31. package/dist/app.js +150 -0
  32. package/dist/catalog/admin-catalog.controller.d.ts +3 -3
  33. package/dist/catalog/admin-catalog.controller.js +27 -13
  34. package/dist/catalog/catalog-content.d.ts +185 -0
  35. package/dist/catalog/catalog-content.js +323 -0
  36. package/dist/catalog/catalog-items.d.ts +186 -0
  37. package/dist/catalog/catalog-items.js +410 -0
  38. package/dist/catalog/catalog.module.d.ts +14 -0
  39. package/dist/catalog/catalog.module.js +71 -0
  40. package/dist/catalog/catalog.service.d.ts +34 -188
  41. package/dist/catalog/catalog.service.js +155 -489
  42. package/dist/catalog/cli.d.ts +3 -2
  43. package/dist/catalog/cli.js +13 -31
  44. package/dist/catalog/job-ids.d.ts +15 -0
  45. package/dist/catalog/job-ids.js +15 -0
  46. package/dist/catalog/jobs.d.ts +27 -0
  47. package/dist/catalog/jobs.js +70 -0
  48. package/dist/catalog/locks.d.ts +24 -0
  49. package/dist/catalog/locks.js +63 -0
  50. package/dist/catalog/marketplaces.controller.d.ts +4 -4
  51. package/dist/catalog/marketplaces.controller.js +22 -11
  52. package/dist/catalog/marketplaces.service.d.ts +30 -13
  53. package/dist/catalog/marketplaces.service.js +330 -256
  54. package/dist/catalog/org-catalog.controller.d.ts +4 -3
  55. package/dist/catalog/org-catalog.controller.js +29 -14
  56. package/dist/catalog/org-catalog.service.d.ts +32 -198
  57. package/dist/catalog/org-catalog.service.js +159 -400
  58. package/dist/catalog/plugin-import.d.ts +73 -34
  59. package/dist/catalog/plugin-import.js +356 -217
  60. package/dist/catalog/plugin-install.d.ts +83 -41
  61. package/dist/catalog/plugin-install.js +421 -269
  62. package/dist/catalog/plugin-upgrade.d.ts +59 -4
  63. package/dist/catalog/plugin-upgrade.js +407 -282
  64. package/dist/catalog/requests.service.d.ts +27 -15
  65. package/dist/catalog/requests.service.js +201 -145
  66. package/dist/catalog/upgrade-targets.d.ts +4 -7
  67. package/dist/channels/actions.d.ts +6 -4
  68. package/dist/channels/actions.js +1 -1
  69. package/dist/channels/cards.d.ts +2 -2
  70. package/dist/channels/channels.module.d.ts +40 -0
  71. package/dist/channels/channels.module.js +128 -0
  72. package/dist/channels/connections.controller.d.ts +1 -1
  73. package/dist/channels/connections.controller.js +11 -6
  74. package/dist/channels/connections.service.d.ts +43 -21
  75. package/dist/channels/connections.service.js +236 -131
  76. package/dist/channels/inbound.d.ts +34 -38
  77. package/dist/channels/inbound.js +107 -41
  78. package/dist/channels/job-ids.d.ts +10 -0
  79. package/dist/channels/job-ids.js +10 -0
  80. package/dist/channels/jobs.d.ts +85 -0
  81. package/dist/channels/jobs.js +157 -0
  82. package/dist/channels/outbound.d.ts +60 -82
  83. package/dist/channels/outbound.js +165 -193
  84. package/dist/channels/supervisor.d.ts +88 -46
  85. package/dist/channels/supervisor.js +230 -132
  86. package/dist/channels/threads.d.ts +29 -8
  87. package/dist/channels/threads.js +71 -13
  88. package/dist/channels/webhook.d.ts +20 -14
  89. package/dist/channels/webhook.js +51 -20
  90. package/dist/config/load.d.ts +3 -2
  91. package/dist/config/load.js +3 -2
  92. package/dist/config/nacos-source.js +11 -2
  93. package/dist/config/schema.d.ts +16 -1
  94. package/dist/config/schema.js +54 -7
  95. package/dist/conversations/access.d.ts +29 -0
  96. package/dist/conversations/access.js +86 -0
  97. package/dist/conversations/artifacts.d.ts +10 -10
  98. package/dist/conversations/artifacts.js +35 -9
  99. package/dist/conversations/attachments.controller.d.ts +1 -1
  100. package/dist/conversations/attachments.controller.js +8 -6
  101. package/dist/conversations/attachments.module.d.ts +7 -0
  102. package/dist/conversations/attachments.module.js +25 -0
  103. package/dist/conversations/attachments.service.d.ts +30 -22
  104. package/dist/conversations/attachments.service.js +119 -46
  105. package/dist/conversations/conversations.controller.d.ts +8 -7
  106. package/dist/conversations/conversations.controller.js +59 -29
  107. package/dist/conversations/conversations.module.d.ts +8 -0
  108. package/dist/conversations/conversations.module.js +69 -0
  109. package/dist/conversations/conversations.service.d.ts +40 -38
  110. package/dist/conversations/conversations.service.js +130 -140
  111. package/dist/conversations/event-log.d.ts +28 -18
  112. package/dist/conversations/event-log.js +74 -27
  113. package/dist/conversations/files.d.ts +10 -10
  114. package/dist/conversations/files.js +37 -11
  115. package/dist/conversations/idem-keys.d.ts +5 -0
  116. package/dist/conversations/idem-keys.js +5 -0
  117. package/dist/conversations/job-ids.d.ts +6 -0
  118. package/dist/conversations/job-ids.js +6 -0
  119. package/dist/conversations/outputs-read.d.ts +11 -11
  120. package/dist/conversations/outputs-read.js +31 -7
  121. package/dist/conversations/queue.d.ts +48 -56
  122. package/dist/conversations/queue.js +13 -289
  123. package/dist/conversations/queue.service.d.ts +60 -0
  124. package/dist/conversations/queue.service.js +343 -0
  125. package/dist/conversations/sandbox-status.d.ts +13 -10
  126. package/dist/conversations/sandbox-status.js +36 -8
  127. package/dist/conversations/titles.d.ts +71 -24
  128. package/dist/conversations/titles.js +159 -62
  129. package/dist/ctx/bus.js +9 -3
  130. package/dist/ctx/create-ctx.d.ts +6 -0
  131. package/dist/ctx/create-ctx.js +7 -9
  132. package/dist/ctx/lock.d.ts +7 -3
  133. package/dist/ctx/lock.js +9 -20
  134. package/dist/ctx/queue.js +3 -2
  135. package/dist/ctx/secrets.d.ts +10 -2
  136. package/dist/ctx/secrets.js +7 -3
  137. package/dist/db/kernel-schema.d.ts +2 -2
  138. package/dist/db/pool.d.ts +5 -0
  139. package/dist/db/pool.js +1 -0
  140. package/dist/errors.d.ts +2 -0
  141. package/dist/errors.js +2 -0
  142. package/dist/evals/budget.d.ts +42 -21
  143. package/dist/evals/budget.js +114 -62
  144. package/dist/evals/evals.module.d.ts +31 -0
  145. package/dist/evals/evals.module.js +114 -0
  146. package/dist/evals/jobs.d.ts +20 -0
  147. package/dist/evals/jobs.js +45 -0
  148. package/dist/evals/run-replay.d.ts +56 -8
  149. package/dist/evals/run-replay.js +140 -80
  150. package/dist/evals/runs.controller.d.ts +1 -1
  151. package/dist/evals/runs.controller.js +17 -8
  152. package/dist/evals/runs.service.d.ts +23 -45
  153. package/dist/evals/runs.service.js +245 -234
  154. package/dist/evals/sets.controller.d.ts +1 -1
  155. package/dist/evals/sets.controller.js +17 -8
  156. package/dist/evals/sets.service.d.ts +22 -6
  157. package/dist/evals/sets.service.js +248 -194
  158. package/dist/evals/snapshot.d.ts +2 -2
  159. package/dist/evals/step-replay.d.ts +2 -2
  160. package/dist/evals/step-replay.js +1 -1
  161. package/dist/evals/trajectory.controller.d.ts +1 -1
  162. package/dist/evals/trajectory.controller.js +11 -7
  163. package/dist/evals/trajectory.service.d.ts +5 -4
  164. package/dist/evals/trajectory.service.js +30 -7
  165. package/dist/evals/worker.d.ts +44 -27
  166. package/dist/evals/worker.js +220 -120
  167. package/dist/extensions/admin-ops.d.ts +61 -33
  168. package/dist/extensions/admin-ops.js +248 -154
  169. package/dist/extensions/admin-view.d.ts +38 -27
  170. package/dist/extensions/admin-view.js +126 -55
  171. package/dist/extensions/approvals.d.ts +12 -8
  172. package/dist/extensions/approvals.js +73 -46
  173. package/dist/extensions/blobs.d.ts +27 -10
  174. package/dist/extensions/blobs.js +111 -45
  175. package/dist/extensions/bootstrap.d.ts +96 -42
  176. package/dist/extensions/bootstrap.js +303 -155
  177. package/dist/extensions/cli.d.ts +20 -10
  178. package/dist/extensions/cli.js +41 -96
  179. package/dist/extensions/config-issues.d.ts +7 -0
  180. package/dist/extensions/config-issues.js +31 -0
  181. package/dist/extensions/deployment-config-store.d.ts +49 -0
  182. package/dist/extensions/deployment-config-store.js +133 -0
  183. package/dist/extensions/deployment-config.d.ts +58 -67
  184. package/dist/extensions/deployment-config.js +202 -230
  185. package/dist/extensions/enabled.d.ts +5 -5
  186. package/dist/extensions/extensions.module.d.ts +8 -0
  187. package/dist/extensions/extensions.module.js +77 -0
  188. package/dist/extensions/hooks.d.ts +3 -2
  189. package/dist/extensions/hooks.js +1 -1
  190. package/dist/extensions/host.d.ts +72 -68
  191. package/dist/extensions/host.js +191 -152
  192. package/dist/extensions/installs.d.ts +49 -16
  193. package/dist/extensions/installs.js +128 -32
  194. package/dist/extensions/job-ids.d.ts +6 -0
  195. package/dist/extensions/job-ids.js +6 -0
  196. package/dist/extensions/lifecycle-topics.d.ts +18 -0
  197. package/dist/extensions/lifecycle-topics.js +18 -0
  198. package/dist/extensions/lifecycle.d.ts +35 -47
  199. package/dist/extensions/lifecycle.js +103 -39
  200. package/dist/extensions/locks.d.ts +33 -0
  201. package/dist/extensions/locks.js +86 -0
  202. package/dist/extensions/migrate-lock.d.ts +3 -4
  203. package/dist/extensions/org-config.controller.d.ts +1 -1
  204. package/dist/extensions/org-config.controller.js +8 -5
  205. package/dist/extensions/org-config.d.ts +48 -46
  206. package/dist/extensions/org-config.js +284 -226
  207. package/dist/extensions/registry.d.ts +50 -2
  208. package/dist/extensions/registry.js +89 -4
  209. package/dist/extensions/sources.d.ts +12 -8
  210. package/dist/extensions/sources.js +34 -13
  211. package/dist/files/files.module.d.ts +3 -0
  212. package/dist/files/files.module.js +22 -0
  213. package/dist/files/previewers.controller.d.ts +7 -2
  214. package/dist/files/previewers.controller.js +17 -9
  215. package/dist/files/previewers.d.ts +13 -18
  216. package/dist/files/previewers.js +83 -36
  217. package/dist/http/adapter.d.ts +3 -0
  218. package/dist/http/adapter.js +25 -0
  219. package/dist/http/api.module.d.ts +3 -110
  220. package/dist/http/api.module.js +47 -355
  221. package/dist/http/app.d.ts +11 -15
  222. package/dist/http/app.js +52 -47
  223. package/dist/http/error-filter.module.d.ts +5 -0
  224. package/dist/http/error-filter.module.js +18 -0
  225. package/dist/http/error.filter.js +2 -2
  226. package/dist/identity/accounts.d.ts +82 -29
  227. package/dist/identity/accounts.js +294 -175
  228. package/dist/identity/api-tokens.d.ts +11 -7
  229. package/dist/identity/api-tokens.js +71 -44
  230. package/dist/identity/audit.d.ts +7 -4
  231. package/dist/identity/audit.js +5 -1
  232. package/dist/identity/auth.controller.d.ts +11 -10
  233. package/dist/identity/auth.controller.js +31 -25
  234. package/dist/identity/auth.guard.d.ts +3 -3
  235. package/dist/identity/auth.guard.js +6 -4
  236. package/dist/identity/binding.d.ts +9 -11
  237. package/dist/identity/binding.js +41 -13
  238. package/dist/identity/enterprise-admin.d.ts +18 -12
  239. package/dist/identity/enterprise-admin.js +67 -13
  240. package/dist/identity/external-identity-lock.d.ts +17 -0
  241. package/dist/identity/external-identity-lock.js +39 -0
  242. package/dist/identity/external.d.ts +19 -15
  243. package/dist/identity/external.js +163 -125
  244. package/dist/identity/identity.module.d.ts +6 -0
  245. package/dist/identity/identity.module.js +56 -0
  246. package/dist/identity/me.controller.d.ts +16 -15
  247. package/dist/identity/me.controller.js +37 -31
  248. package/dist/identity/sessions.d.ts +12 -10
  249. package/dist/identity/sessions.js +74 -42
  250. package/dist/identity/settings.d.ts +20 -14
  251. package/dist/identity/settings.js +85 -57
  252. package/dist/identity/sso.controller.d.ts +7 -7
  253. package/dist/identity/sso.controller.js +13 -9
  254. package/dist/identity/sso.d.ts +9 -12
  255. package/dist/identity/sso.js +54 -24
  256. package/dist/inbox/inbox.module.d.ts +3 -0
  257. package/dist/inbox/inbox.module.js +22 -0
  258. package/dist/inbox/inbox.service.d.ts +7 -9
  259. package/dist/inbox/inbox.service.js +32 -11
  260. package/dist/index.d.ts +19 -12
  261. package/dist/index.js +13 -8
  262. package/dist/infra/cache/cache.module.d.ts +3 -0
  263. package/dist/infra/cache/cache.module.js +16 -0
  264. package/dist/infra/cache/cache.service.d.ts +21 -0
  265. package/dist/infra/cache/cache.service.js +80 -0
  266. package/dist/infra/cache/cacheable.decorator.d.ts +32 -0
  267. package/dist/infra/cache/cacheable.decorator.js +83 -0
  268. package/dist/infra/cli/kernel-cli.module.d.ts +66 -0
  269. package/dist/infra/cli/kernel-cli.module.js +165 -0
  270. package/dist/infra/close-within.d.ts +15 -0
  271. package/dist/infra/close-within.js +36 -0
  272. package/dist/infra/config/config.module.d.ts +13 -0
  273. package/dist/infra/config/config.module.js +39 -0
  274. package/dist/infra/config/kernel-config.service.d.ts +25 -0
  275. package/dist/infra/config/kernel-config.service.js +126 -0
  276. package/dist/infra/database/after-commit.d.ts +6 -0
  277. package/dist/infra/database/after-commit.js +9 -0
  278. package/dist/infra/database/database.module.d.ts +25 -0
  279. package/dist/infra/database/database.module.js +90 -0
  280. package/dist/infra/database/kernel-db.d.ts +22 -0
  281. package/dist/infra/database/kernel-db.js +65 -0
  282. package/dist/infra/database/transaction-host.d.ts +50 -0
  283. package/dist/infra/database/transaction-host.js +125 -0
  284. package/dist/infra/database/transactional.decorator.d.ts +15 -0
  285. package/dist/infra/database/transactional.decorator.js +27 -0
  286. package/dist/infra/database/xact-lock.d.ts +17 -0
  287. package/dist/infra/database/xact-lock.js +43 -0
  288. package/dist/infra/events/kernel-events.d.ts +96 -0
  289. package/dist/infra/events/kernel-events.js +65 -0
  290. package/dist/infra/health/health.controller.d.ts +26 -0
  291. package/dist/infra/health/health.controller.js +104 -0
  292. package/dist/infra/health/health.module.d.ts +9 -0
  293. package/dist/infra/health/health.module.js +24 -0
  294. package/dist/infra/health/health.options.d.ts +10 -0
  295. package/dist/infra/health/health.options.js +15 -0
  296. package/dist/infra/health/shutdown-state.d.ts +6 -0
  297. package/dist/infra/health/shutdown-state.js +2 -0
  298. package/dist/infra/lifecycle/graceful-shutdown.module.d.ts +6 -0
  299. package/dist/infra/lifecycle/graceful-shutdown.module.js +23 -0
  300. package/dist/infra/lifecycle/graceful-shutdown.service.d.ts +70 -0
  301. package/dist/infra/lifecycle/graceful-shutdown.service.js +135 -0
  302. package/dist/infra/lifecycle/process-guards.d.ts +52 -0
  303. package/dist/infra/lifecycle/process-guards.js +86 -0
  304. package/dist/infra/lifecycle/shutdown-signals.d.ts +30 -0
  305. package/dist/infra/lifecycle/shutdown-signals.js +48 -0
  306. package/dist/infra/lock/key-template.d.ts +13 -0
  307. package/dist/infra/lock/key-template.js +46 -0
  308. package/dist/infra/lock/lock.module.d.ts +3 -0
  309. package/dist/infra/lock/lock.module.js +16 -0
  310. package/dist/infra/lock/lock.service.d.ts +120 -0
  311. package/dist/infra/lock/lock.service.js +343 -0
  312. package/dist/infra/lock/shared-lease.d.ts +44 -0
  313. package/dist/infra/lock/shared-lease.js +121 -0
  314. package/dist/infra/lock/with-lock.decorator.d.ts +28 -0
  315. package/dist/infra/lock/with-lock.decorator.js +49 -0
  316. package/dist/infra/logging/logging.module.d.ts +16 -0
  317. package/dist/infra/logging/logging.module.js +34 -0
  318. package/dist/infra/queue/configured-processor.d.ts +18 -0
  319. package/dist/infra/queue/configured-processor.js +23 -0
  320. package/dist/infra/queue/job-failure.d.ts +18 -0
  321. package/dist/infra/queue/job-failure.js +26 -0
  322. package/dist/infra/queue/queue-shutdown.d.ts +27 -0
  323. package/dist/infra/queue/queue-shutdown.js +81 -0
  324. package/dist/infra/queue/queue.module.d.ts +16 -0
  325. package/dist/infra/queue/queue.module.js +61 -0
  326. package/dist/infra/queue/redis-connection.d.ts +7 -0
  327. package/dist/infra/queue/redis-connection.js +18 -0
  328. package/dist/infra/queue/retired-schedulers.d.ts +7 -0
  329. package/dist/infra/queue/retired-schedulers.js +9 -0
  330. package/dist/infra/queue/run-job.d.ts +16 -0
  331. package/dist/infra/queue/run-job.js +19 -0
  332. package/dist/infra/redis/redis.module.d.ts +24 -0
  333. package/dist/infra/redis/redis.module.js +87 -0
  334. package/dist/infra/schedule/cron-tick.d.ts +12 -0
  335. package/dist/infra/schedule/cron-tick.js +25 -0
  336. package/dist/infra/schedule/locked-cron.decorator.d.ts +27 -0
  337. package/dist/infra/schedule/locked-cron.decorator.js +53 -0
  338. package/dist/infra/schedule/locked-interval.d.ts +69 -0
  339. package/dist/infra/schedule/locked-interval.js +190 -0
  340. package/dist/infra/schedule/locked-tick.d.ts +90 -0
  341. package/dist/infra/schedule/locked-tick.js +137 -0
  342. package/dist/infra/schedule/schedule.module.d.ts +8 -0
  343. package/dist/infra/schedule/schedule.module.js +27 -0
  344. package/dist/infra/schedule/scheduled-runs.d.ts +69 -0
  345. package/dist/infra/schedule/scheduled-runs.js +163 -0
  346. package/dist/infra/swagger/swagger.d.ts +16 -0
  347. package/dist/infra/swagger/swagger.js +31 -0
  348. package/dist/infra/throttler/credential-throttler.d.ts +35 -0
  349. package/dist/infra/throttler/credential-throttler.js +77 -0
  350. package/dist/infra/throttler/named-throttlers.d.ts +31 -0
  351. package/dist/infra/throttler/named-throttlers.js +119 -0
  352. package/dist/infra/throttler/redis-throttler-storage.d.ts +38 -0
  353. package/dist/infra/throttler/redis-throttler-storage.js +130 -0
  354. package/dist/infra/throttler/throttler.guard.d.ts +23 -0
  355. package/dist/infra/throttler/throttler.guard.js +68 -0
  356. package/dist/infra/throttler/throttler.module.d.ts +15 -0
  357. package/dist/infra/throttler/throttler.module.js +53 -0
  358. package/dist/infra/tokens.d.ts +15 -0
  359. package/dist/infra/tokens.js +15 -0
  360. package/dist/infra/validation/create-zod-dto.d.ts +23 -0
  361. package/dist/infra/validation/create-zod-dto.js +35 -0
  362. package/dist/infra/validation/parse-with-zod.d.ts +7 -0
  363. package/dist/infra/validation/parse-with-zod.js +12 -0
  364. package/dist/infra/validation/validation.module.d.ts +3 -0
  365. package/dist/infra/validation/validation.module.js +16 -0
  366. package/dist/infra/validation/zod-params.d.ts +7 -0
  367. package/dist/infra/validation/zod-params.js +42 -0
  368. package/dist/infra/validation/zod-validation.pipe.d.ts +11 -0
  369. package/dist/infra/validation/zod-validation.pipe.js +31 -0
  370. package/dist/kernel.d.ts +9 -241
  371. package/dist/kernel.js +8 -1305
  372. package/dist/kernel.module.d.ts +17 -0
  373. package/dist/kernel.module.js +136 -0
  374. package/dist/lifecycle/kernel-lifecycle.d.ts +140 -0
  375. package/dist/lifecycle/kernel-lifecycle.js +451 -0
  376. package/dist/lifecycle/tokens.d.ts +3 -0
  377. package/dist/lifecycle/tokens.js +3 -0
  378. package/dist/log-config.d.ts +9 -0
  379. package/dist/log-config.js +27 -0
  380. package/dist/log-context.d.ts +34 -0
  381. package/dist/log-context.js +44 -0
  382. package/dist/log-loki.d.ts +34 -0
  383. package/dist/log-loki.js +145 -0
  384. package/dist/log.d.ts +41 -10
  385. package/dist/log.js +91 -17
  386. package/dist/models/models.module.d.ts +3 -0
  387. package/dist/models/models.module.js +24 -0
  388. package/dist/models/prices.d.ts +8 -2
  389. package/dist/models/prices.js +65 -37
  390. package/dist/models/purposes.controller.d.ts +1 -1
  391. package/dist/models/purposes.controller.js +5 -6
  392. package/dist/models/purposes.d.ts +35 -13
  393. package/dist/models/purposes.js +101 -51
  394. package/dist/net/public-address.js +3 -2
  395. package/dist/orgs/directory-sync.controller.d.ts +1 -1
  396. package/dist/orgs/directory-sync.controller.js +2 -2
  397. package/dist/orgs/directory-sync.d.ts +61 -31
  398. package/dist/orgs/directory-sync.js +212 -125
  399. package/dist/orgs/invitations.controller.d.ts +8 -8
  400. package/dist/orgs/invitations.controller.js +27 -26
  401. package/dist/orgs/invitations.service.d.ts +12 -9
  402. package/dist/orgs/invitations.service.js +130 -92
  403. package/dist/orgs/job-ids.d.ts +8 -0
  404. package/dist/orgs/job-ids.js +8 -0
  405. package/dist/orgs/members.service.d.ts +19 -12
  406. package/dist/orgs/members.service.js +161 -117
  407. package/dist/orgs/offboarding.d.ts +54 -57
  408. package/dist/orgs/offboarding.js +161 -71
  409. package/dist/orgs/org-lock.d.ts +28 -19
  410. package/dist/orgs/org-lock.js +81 -35
  411. package/dist/orgs/org.guard.d.ts +1 -1
  412. package/dist/orgs/org.guard.js +2 -2
  413. package/dist/orgs/orgs.controller.d.ts +13 -13
  414. package/dist/orgs/orgs.controller.js +29 -17
  415. package/dist/orgs/orgs.module.d.ts +6 -0
  416. package/dist/orgs/orgs.module.js +68 -0
  417. package/dist/orgs/orgs.service.d.ts +30 -19
  418. package/dist/orgs/orgs.service.js +139 -86
  419. package/dist/orgs/settings.controller.d.ts +1 -1
  420. package/dist/orgs/settings.controller.js +8 -6
  421. package/dist/orgs/settings.service.d.ts +14 -8
  422. package/dist/orgs/settings.service.js +75 -46
  423. package/dist/overrides.d.ts +56 -0
  424. package/dist/overrides.js +30 -0
  425. package/dist/roles/gateway-role.d.ts +43 -0
  426. package/dist/roles/gateway-role.js +98 -0
  427. package/dist/roles/gateway.module.d.ts +8 -0
  428. package/dist/roles/gateway.module.js +28 -0
  429. package/dist/roles/worker-role.d.ts +63 -0
  430. package/dist/roles/worker-role.js +144 -0
  431. package/dist/roles/worker.module.d.ts +14 -0
  432. package/dist/roles/worker.module.js +90 -0
  433. package/dist/runtime/abort.js +19 -2
  434. package/dist/runtime/checkpointer.d.ts +8 -3
  435. package/dist/runtime/checkpointer.js +87 -55
  436. package/dist/runtime/conversation-lock.d.ts +20 -11
  437. package/dist/runtime/conversation-lock.js +62 -72
  438. package/dist/runtime/hook-calls.d.ts +3 -3
  439. package/dist/runtime/hook-calls.js +1 -6
  440. package/dist/runtime/job-ids.d.ts +10 -0
  441. package/dist/runtime/job-ids.js +10 -0
  442. package/dist/runtime/langgraph-loop.js +1 -1
  443. package/dist/runtime/loop.d.ts +7 -0
  444. package/dist/runtime/loop.js +14 -0
  445. package/dist/runtime/maintenance-queue.d.ts +10 -0
  446. package/dist/runtime/maintenance-queue.js +10 -0
  447. package/dist/runtime/maintenance.d.ts +45 -74
  448. package/dist/runtime/maintenance.js +139 -136
  449. package/dist/runtime/model-call.d.ts +7 -4
  450. package/dist/runtime/model-call.js +24 -57
  451. package/dist/runtime/providers.d.ts +17 -6
  452. package/dist/runtime/providers.js +66 -25
  453. package/dist/runtime/quota.d.ts +17 -3
  454. package/dist/runtime/quota.js +27 -2
  455. package/dist/runtime/retired-schedulers.d.ts +7 -0
  456. package/dist/runtime/retired-schedulers.js +31 -0
  457. package/dist/runtime/run-control.d.ts +33 -0
  458. package/dist/runtime/run-control.js +77 -0
  459. package/dist/runtime/run-finish.d.ts +26 -17
  460. package/dist/runtime/run-finish.js +98 -51
  461. package/dist/runtime/run-jobs.d.ts +48 -0
  462. package/dist/runtime/run-jobs.js +95 -0
  463. package/dist/runtime/run-processors.d.ts +60 -0
  464. package/dist/runtime/run-processors.js +185 -0
  465. package/dist/runtime/run-queue.d.ts +32 -57
  466. package/dist/runtime/run-queue.js +291 -295
  467. package/dist/runtime/run-steps.d.ts +39 -0
  468. package/dist/runtime/run-steps.js +96 -0
  469. package/dist/runtime/run-worker.d.ts +121 -75
  470. package/dist/runtime/run-worker.js +340 -225
  471. package/dist/runtime/runtime.module.d.ts +10 -0
  472. package/dist/runtime/runtime.module.js +112 -0
  473. package/dist/runtime/step-log.d.ts +40 -0
  474. package/dist/runtime/step-log.js +94 -0
  475. package/dist/runtime/stream.controller.d.ts +5 -8
  476. package/dist/runtime/stream.controller.js +14 -12
  477. package/dist/runtime/stream.d.ts +24 -6
  478. package/dist/runtime/stream.js +78 -7
  479. package/dist/runtime/subagents/child.d.ts +3 -44
  480. package/dist/runtime/subagents/child.js +0 -79
  481. package/dist/runtime/subagents/definition.d.ts +4 -4
  482. package/dist/runtime/subagents/definition.js +2 -2
  483. package/dist/runtime/subagents/dispatch.d.ts +87 -6
  484. package/dist/runtime/subagents/dispatch.js +135 -140
  485. package/dist/runtime/subagents/limits.d.ts +9 -4
  486. package/dist/runtime/subagents/limits.js +4 -2
  487. package/dist/runtime/subagents/org-agents.d.ts +4 -4
  488. package/dist/runtime/subagents/org-agents.js +1 -1
  489. package/dist/runtime/subagents/progress.d.ts +2 -2
  490. package/dist/runtime/subagents/roster.d.ts +3 -3
  491. package/dist/runtime/subagents/roster.js +1 -1
  492. package/dist/runtime/subagents/skill-fork.d.ts +6 -7
  493. package/dist/runtime/subagents/skill-fork.js +16 -5
  494. package/dist/runtime/subagents/subagents.service.d.ts +40 -0
  495. package/dist/runtime/subagents/subagents.service.js +101 -0
  496. package/dist/runtime/usage-report.d.ts +94 -52
  497. package/dist/runtime/usage-report.js +200 -99
  498. package/dist/runtime/waits.d.ts +125 -57
  499. package/dist/runtime/waits.js +431 -208
  500. package/dist/sandbox/job-ids.d.ts +10 -0
  501. package/dist/sandbox/job-ids.js +10 -0
  502. package/dist/sandbox/jobs.d.ts +41 -0
  503. package/dist/sandbox/jobs.js +113 -0
  504. package/dist/sandbox/leases.d.ts +39 -31
  505. package/dist/sandbox/leases.js +117 -257
  506. package/dist/sandbox/providers.d.ts +19 -0
  507. package/dist/sandbox/providers.js +38 -0
  508. package/dist/sandbox/sandbox.module.d.ts +8 -0
  509. package/dist/sandbox/sandbox.module.js +30 -0
  510. package/dist/sandbox/sandbox.service.d.ts +24 -29
  511. package/dist/sandbox/sandbox.service.js +106 -75
  512. package/dist/skills/catalog.d.ts +33 -20
  513. package/dist/skills/catalog.js +96 -53
  514. package/dist/skills/changes.controller.d.ts +4 -4
  515. package/dist/skills/changes.controller.js +15 -9
  516. package/dist/skills/changes.service.d.ts +28 -18
  517. package/dist/skills/changes.service.js +421 -364
  518. package/dist/skills/invocable.controller.d.ts +1 -1
  519. package/dist/skills/invocable.controller.js +8 -5
  520. package/dist/skills/invoke.d.ts +16 -15
  521. package/dist/skills/invoke.js +48 -17
  522. package/dist/skills/skills.controller.d.ts +1 -1
  523. package/dist/skills/skills.controller.js +11 -6
  524. package/dist/skills/skills.module.d.ts +6 -0
  525. package/dist/skills/skills.module.js +30 -0
  526. package/dist/skills/skills.service.d.ts +47 -30
  527. package/dist/skills/skills.service.js +221 -158
  528. package/dist/storage/job-ids.d.ts +6 -0
  529. package/dist/storage/job-ids.js +6 -0
  530. package/dist/storage/purge.d.ts +22 -7
  531. package/dist/storage/purge.js +55 -3
  532. package/dist/storage/storage.module.d.ts +6 -0
  533. package/dist/storage/storage.module.js +23 -0
  534. package/dist/storage/storage.service.d.ts +18 -4
  535. package/dist/storage/storage.service.js +44 -3
  536. package/dist/tools/approvals.controller.d.ts +1 -1
  537. package/dist/tools/approvals.controller.js +12 -8
  538. package/dist/tools/approvals.service.d.ts +27 -25
  539. package/dist/tools/approvals.service.js +324 -258
  540. package/dist/tools/breaker.d.ts +2 -2
  541. package/dist/tools/breaker.js +21 -3
  542. package/dist/tools/builtins/ask-user.d.ts +2 -2
  543. package/dist/tools/builtins/ask-user.js +1 -1
  544. package/dist/tools/builtins/builtin-tools.d.ts +21 -0
  545. package/dist/tools/builtins/builtin-tools.js +80 -0
  546. package/dist/tools/builtins/read-tool-output.d.ts +2 -2
  547. package/dist/tools/builtins/read-tool-output.js +1 -1
  548. package/dist/tools/builtins/sandbox/bash.js +2 -2
  549. package/dist/tools/builtins/sandbox/common.d.ts +7 -4
  550. package/dist/tools/builtins/sandbox/common.js +5 -3
  551. package/dist/tools/builtins/sandbox/deliver.js +2 -2
  552. package/dist/tools/builtins/sandbox/edit.js +1 -1
  553. package/dist/tools/builtins/sandbox/glob.js +2 -2
  554. package/dist/tools/builtins/sandbox/grep.js +2 -2
  555. package/dist/tools/builtins/sandbox/read.js +1 -1
  556. package/dist/tools/builtins/sandbox/write.js +1 -1
  557. package/dist/tools/builtins/skill-load.d.ts +3 -3
  558. package/dist/tools/builtins/skill-load.js +1 -1
  559. package/dist/tools/canonical-json.d.ts +6 -0
  560. package/dist/tools/canonical-json.js +16 -0
  561. package/dist/tools/connector-content.controller.d.ts +1 -1
  562. package/dist/tools/connector-content.controller.js +11 -6
  563. package/dist/tools/connector-content.d.ts +12 -15
  564. package/dist/tools/connector-content.js +53 -18
  565. package/dist/tools/connectors.controller.d.ts +1 -1
  566. package/dist/tools/connectors.controller.js +21 -10
  567. package/dist/tools/connectors.service.d.ts +31 -13
  568. package/dist/tools/connectors.service.js +434 -344
  569. package/dist/tools/credentials.d.ts +17 -20
  570. package/dist/tools/credentials.js +55 -34
  571. package/dist/tools/drift.d.ts +29 -41
  572. package/dist/tools/drift.js +111 -79
  573. package/dist/tools/info.d.ts +12 -9
  574. package/dist/tools/info.js +33 -7
  575. package/dist/tools/job-ids.d.ts +13 -0
  576. package/dist/tools/job-ids.js +15 -0
  577. package/dist/tools/jobs.d.ts +24 -0
  578. package/dist/tools/jobs.js +69 -0
  579. package/dist/tools/oauth/flow-paths.d.ts +16 -0
  580. package/dist/tools/oauth/flow-paths.js +38 -0
  581. package/dist/tools/oauth/flow.d.ts +30 -30
  582. package/dist/tools/oauth/flow.js +109 -81
  583. package/dist/tools/oauth/oauth.controller.d.ts +3 -3
  584. package/dist/tools/oauth/oauth.controller.js +12 -9
  585. package/dist/tools/oauth/tokens.d.ts +11 -3
  586. package/dist/tools/oauth/tokens.js +15 -14
  587. package/dist/tools/outputs.d.ts +13 -4
  588. package/dist/tools/outputs.js +47 -3
  589. package/dist/tools/pipeline.d.ts +62 -46
  590. package/dist/tools/pipeline.js +145 -64
  591. package/dist/tools/policy.d.ts +2 -2
  592. package/dist/tools/questions.controller.d.ts +1 -1
  593. package/dist/tools/questions.controller.js +8 -5
  594. package/dist/tools/questions.service.d.ts +25 -24
  595. package/dist/tools/questions.service.js +201 -142
  596. package/dist/tools/registry.d.ts +30 -20
  597. package/dist/tools/registry.js +73 -37
  598. package/dist/tools/specs.d.ts +5 -4
  599. package/dist/tools/specs.js +3 -1
  600. package/dist/tools/tools.module.d.ts +10 -0
  601. package/dist/tools/tools.module.js +91 -0
  602. package/dist/ui/call-extension.d.ts +16 -0
  603. package/dist/ui/call-extension.js +38 -0
  604. package/dist/ui/embed-token.d.ts +9 -5
  605. package/dist/ui/embed-token.js +34 -6
  606. package/dist/ui/ui-stream.d.ts +22 -17
  607. package/dist/ui/ui-stream.js +72 -12
  608. package/dist/ui/ui.module.d.ts +7 -0
  609. package/dist/ui/ui.module.js +28 -0
  610. package/dist/ui/views.controller.d.ts +14 -12
  611. package/dist/ui/views.controller.js +32 -25
  612. package/dist/ui/views.d.ts +9 -57
  613. package/dist/ui/views.js +43 -45
  614. package/package.json +11 -2
  615. package/dist/http/health.controller.d.ts +0 -26
  616. package/dist/http/health.controller.js +0 -79
  617. package/dist/http/tokens.d.ts +0 -131
  618. package/dist/http/tokens.js +0 -131
  619. package/dist/http/zod.pipe.d.ts +0 -8
  620. package/dist/http/zod.pipe.js +0 -14
  621. package/dist/identity/rate-limit.d.ts +0 -55
  622. package/dist/identity/rate-limit.js +0 -121
  623. package/dist/sandbox/lifecycle.d.ts +0 -21
  624. package/dist/sandbox/lifecycle.js +0 -68
  625. /package/dist/http/{gateway.module.d.ts → gateway-routes.d.ts} +0 -0
  626. /package/dist/http/{gateway.module.js → gateway-routes.js} +0 -0
@@ -1,37 +1,61 @@
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
+ };
1
10
  import { createHash } from "node:crypto";
2
- import { readFile } from "node:fs/promises";
11
+ import { readdir, readFile, stat } from "node:fs/promises";
3
12
  import { join } from "node:path";
4
13
  import { fileURLToPath } from "node:url";
5
- import { bootstrapFileName, parseBootstrapManifest, SDK_VERSION, } from "@capybara-hq/plugin-sdk";
14
+ import { parseBootstrapManifest, SDK_VERSION, } from "@capybara-hq/plugin-sdk";
15
+ import { Inject, Injectable, Optional } from "@nestjs/common";
6
16
  import { sql } from "kysely";
7
- import pg from "pg";
8
17
  import semver from "semver";
9
18
  import { catalogPackageError } from "../catalog/plugin-import.js";
10
19
  import { PluginPackageError, readPluginPackage } from "../catalog/plugin-package.js";
11
- import { pgConnectOptions } from "../db/pool.js";
12
20
  import { ApiError } from "../errors.js";
13
21
  import { audit } from "../identity/audit.js";
22
+ import { KernelConfigService } from "../infra/config/kernel-config.service.js";
23
+ import { KernelDb } from "../infra/database/kernel-db.js";
24
+ import { TransactionHost } from "../infra/database/transaction-host.js";
25
+ import { Transactional } from "../infra/database/transactional.decorator.js";
26
+ import { LockService } from "../infra/lock/lock.service.js";
27
+ import { KERNEL_LOGGER } from "../infra/tokens.js";
28
+ import { fetchNpmPackage, IntegrityMismatchError, NpmFetchError, PackageTooLargeError, } from "../packages/npm.js";
29
+ import { ExtensionAdminOps } from "./admin-ops.js";
14
30
  import { writeSnapshot } from "./approvals.js";
31
+ import { ExtensionInstalls } from "./installs.js";
32
+ import { PluginApproveLock } from "./locks.js";
15
33
  import { ExtensionPackageError, permissionSetOfPackage, readExtensionPackage } from "./package.js";
16
34
  import { diffPermissions } from "./permission-set.js";
35
+ import { ExtensionRegistry } from "./registry.js";
17
36
  /**
18
- * The bootstrap step (package ecosystem spec §7): installs the plugins pinned by the bootstrap
19
- * manifest (`packages/kernel/bootstrap.json`) from the tgz files baked into the image. It replaced
20
- * the builtin extensions.
37
+ * The bootstrap step (package ecosystem spec §7, startup bootstrap spec): installs the plugins
38
+ * pinned by the bootstrap manifest (`packages/kernel/bootstrap.json`). It replaced the builtin
39
+ * extensions.
21
40
  *
22
- * - Every file (`<dir>/<name>-<version>.tgz`) is checked against the entry's sha512 before anything
23
- * is read or written; a missing file is `bootstrap.missing_file`, a mismatch
24
- * `bootstrap.integrity_mismatch` (both name the plugin), and then nothing is written. It never
25
- * touches the network.
26
- * - The whole run holds the session advisory lock `capybara.bootstrap` on a connection of its own
27
- * (taken with `pg_try_advisory_lock` in a backoff loop that observes the signal, and closed
28
- * afterwards, so the lock never outlives the run): when several replicas start together only one
29
- * runs it; the others wait, then find it done. "Done" is a `bootstrap_runs` row for the
41
+ * - When the run is already done for the manifest nothing is read: no directory, no network, so a
42
+ * restart of an installed deployment never needs npm.
43
+ * - Otherwise, inside the lock and before anything is written, every entry's tgz is obtained
44
+ * ({@link resolveBootstrapPackages}): a `*.tgz` file of the optional offline directory whose
45
+ * sha512 equals the entry's `integrity` (the file name does not matter), else the npm download
46
+ * of a `source: "npm"` entry (`packages.npmRegistry` / `npmToken` / `maxBytes`, verified against
47
+ * the pin only). A workspace entry without a matching file is `bootstrap.missing_file`, a failed
48
+ * download `bootstrap.download_failed`, a download that differs from the pin
49
+ * `bootstrap.integrity_mismatch` (all name the plugin), and then nothing is written. Downloading
50
+ * inside the lock means a fleet starting together downloads once.
51
+ * - The whole run holds the Redis lock `lock:bootstrap` (`LockService`, decision R5 of the Nest
52
+ * kernel spec: TTL {@link BOOTSTRAP_LOCK_TTL_MS}, renewed every third of it, so a run longer than the TTL keeps
53
+ * it and a crashed holder's lock expires within it), taken by an unbounded wait that observes
54
+ * the signal: when several replicas (or `capybara bootstrap` and a starting kernel) run it
55
+ * together only one runs it; the others wait, then find it done. A lost lock (renewal failed
56
+ * until expiry) aborts the run at its next step. "Done" is a `bootstrap_runs` row for the
30
57
  * manifest's sha256 (written with the audit `bootstrap.completed` only when every entry
31
- * succeeded; otherwise the next start runs it again, which is idempotent). A lock connection
32
- * that drops mid-run is not detected (its errors are swallowed) and the run goes on without the
33
- * lock, so a second replica could run concurrently: accepted, since a concurrent import or
34
- * install degrades to `catalog.version_exists` and a deploy from the package store.
58
+ * succeeded; otherwise the next start runs it again, which is idempotent).
35
59
  * - Only entries new to the manifest are installed (Ruling 5): an optional entry that the last
36
60
  * completed run already handled and that is not installed now (an enterprise admin uninstalled
37
61
  * it) stays uninstalled -> `kept`. A required entry is always installed.
@@ -58,8 +82,8 @@ import { diffPermissions } from "./permission-set.js";
58
82
  * loses `required` -> `required_cleared`.
59
83
  * A failed entry does not stop the others; the run then throws {@link BootstrapFailedError} naming
60
84
  * them. The packages are kept in PG (`blob_store = 'pg'`), so installing an extension never needs
61
- * the object store (object-store-s3 is itself a bootstrap plugin); a declarative plugin's catalog
62
- * files do.
85
+ * the object store (object-store-s3 is itself a bootstrap plugin) and the directory and npm are
86
+ * never needed again; a declarative plugin's catalog files do need the object store.
63
87
  */
64
88
  /** The bootstrap manifest that ships with the kernel package. */
65
89
  export const BOOTSTRAP_MANIFEST_FILE = fileURLToPath(new URL("../../bootstrap.json", import.meta.url));
@@ -95,16 +119,149 @@ export async function readBootstrapManifest(file = BOOTSTRAP_MANIFEST_FILE) {
95
119
  return parsed;
96
120
  }
97
121
  const integrityOf = (bytes) => `sha512-${createHash("sha512").update(bytes).digest("base64")}`;
98
- /** The advisory lock around a whole run. */
99
- const LOCK_KEY = "capybara.bootstrap";
100
- export class BootstrapService {
101
- d;
102
- constructor(d) {
103
- this.d = d;
122
+ /**
123
+ * Obtains every entry's tgz, checked against its pinned sha512: from the offline directory when a
124
+ * file there has that sha512, else (a `source: "npm"` entry) downloaded from the npm registry and
125
+ * verified against the pin (the packument's `dist.integrity` is not consulted). Throws an
126
+ * {@link ApiError} naming the plugin for the first entry it cannot obtain
127
+ * (`bootstrap.missing_file`, `bootstrap.download_failed`, `bootstrap.integrity_mismatch`).
128
+ */
129
+ export async function resolveBootstrapPackages(manifest, o) {
130
+ const out = new Map();
131
+ if (manifest.plugins.length === 0)
132
+ return out;
133
+ const { npmRegistry, npmToken, maxBytes } = o.config.packages;
134
+ const offline = o.dir !== undefined ? await scanOfflineDir(o.dir, maxBytes, o.log) : new Map();
135
+ const fetchPackage = o.fetch ?? fetchNpmPackage;
136
+ const signal = o.signal ?? new AbortController().signal;
137
+ const where = o.dir !== undefined ? o.dir : "the bootstrap directory (config bootstrap.dir)";
138
+ for (const e of manifest.plugins) {
139
+ signal.throwIfAborted();
140
+ const found = offline.get(e.integrity);
141
+ if (found !== undefined) {
142
+ out.set(e.name, found);
143
+ continue;
144
+ }
145
+ if (e.source === "workspace") {
146
+ throw new ApiError("bootstrap.missing_file", `Bootstrap plugin ${e.name} ${e.version}: no file in ${where} has its pinned sha512 (${e.integrity.slice(0, 19)}…), and a workspace entry cannot be downloaded; put its package tgz (pnpm pack-plugin ${e.path}) in that directory`);
147
+ }
148
+ const registry = registryOrigin(npmRegistry);
149
+ const offlineHint = `to install offline, put the package tgz (npm pack ${e.npm}@${e.version}, any file name) in ${where}`;
150
+ try {
151
+ const r = await fetchPackage({ registry: npmRegistry, ...(npmToken !== undefined && { token: npmToken }), maxBytes }, e.npm, e.version, signal, { expectedIntegrity: e.integrity });
152
+ out.set(e.name, r.bytes);
153
+ }
154
+ catch (err) {
155
+ if (signal.aborted)
156
+ throw err;
157
+ if (err instanceof IntegrityMismatchError) {
158
+ throw new ApiError("bootstrap.integrity_mismatch", `Bootstrap plugin ${e.name} ${e.version}: the package ${e.npm}@${e.version} downloaded from ${registry} does not match its pinned sha512 (expected ${e.integrity.slice(0, 19)}…, got ${err.actual.slice(0, 19)}…); refusing to install anything`);
159
+ }
160
+ const reason = err instanceof NpmFetchError || err instanceof PackageTooLargeError
161
+ ? err.message
162
+ : err instanceof Error
163
+ ? err.message
164
+ : String(err);
165
+ throw new ApiError("bootstrap.download_failed", `Bootstrap plugin ${e.name} ${e.version}: cannot download ${e.npm}@${e.version} from ${registry} (${reason}); ${offlineHint}, or set packages.npmRegistry to a reachable mirror`);
166
+ }
167
+ }
168
+ return out;
169
+ }
170
+ /** The registry's origin, for messages (never its credentials or path). */
171
+ function registryOrigin(registry) {
172
+ try {
173
+ return new URL(registry).origin;
174
+ }
175
+ catch {
176
+ return "the configured npm registry";
177
+ }
178
+ }
179
+ /**
180
+ * The `*.tgz` files directly in `dir` by their sha512 integrity. A missing directory is an empty
181
+ * one; a file larger than `maxBytes` is skipped with a warning.
182
+ */
183
+ async function scanOfflineDir(dir, maxBytes, log) {
184
+ const out = new Map();
185
+ let names;
186
+ try {
187
+ names = await readdir(dir);
188
+ }
189
+ catch (err) {
190
+ const code = err.code;
191
+ if (code === "ENOENT" || code === "ENOTDIR")
192
+ return out;
193
+ throw err;
194
+ }
195
+ for (const name of names.sort()) {
196
+ if (!name.endsWith(".tgz"))
197
+ continue;
198
+ const file = join(dir, name);
199
+ const st = await stat(file).catch(() => undefined);
200
+ if (!st?.isFile())
201
+ continue;
202
+ if (st.size > maxBytes) {
203
+ log?.warn("bootstrap: a file in the bootstrap directory exceeds packages.maxBytes; skipped", {
204
+ file,
205
+ size: st.size,
206
+ maxBytes,
207
+ });
208
+ continue;
209
+ }
210
+ const bytes = new Uint8Array(await readFile(file));
211
+ const integrity = integrityOf(bytes);
212
+ if (!out.has(integrity))
213
+ out.set(integrity, bytes);
214
+ }
215
+ return out;
216
+ }
217
+ /** The lock around a whole run (`lock:bootstrap`). */
218
+ export const BOOTSTRAP_LOCK_KEY = "bootstrap";
219
+ /** Its lifetime without renewal; a run keeps it by renewal, a crashed holder's expires. */
220
+ export const BOOTSTRAP_LOCK_TTL_MS = 120_000;
221
+ /** Optional provider: the lock's lifetime (ms) instead of {@link BOOTSTRAP_LOCK_TTL_MS} (tests shorten it). */
222
+ export const BOOTSTRAP_LOCK_TTL = Symbol("BOOTSTRAP_LOCK_TTL");
223
+ /** The pause between attempts while another holder runs the step. */
224
+ const LOCK_RETRY_MS = 500;
225
+ let BootstrapService = class BootstrapService {
226
+ kdb;
227
+ txHost;
228
+ locks;
229
+ approveLock;
230
+ installs;
231
+ ops;
232
+ registry;
233
+ configService;
234
+ log;
235
+ lockTtlMs;
236
+ constructor(kdb, txHost, locks, approveLock, installs, ops,
237
+ /**
238
+ * Config-declared extension names (an entry of the same name is kept, config wins, and no
239
+ * install record is created): the start sequence records them before the bootstrap step, the
240
+ * CLI from its inspection.
241
+ */
242
+ registry, configService, log,
243
+ /** The lock's lifetime without renewal. */
244
+ lockTtlMs = BOOTSTRAP_LOCK_TTL_MS) {
245
+ this.kdb = kdb;
246
+ this.txHost = txHost;
247
+ this.locks = locks;
248
+ this.approveLock = approveLock;
249
+ this.installs = installs;
250
+ this.ops = ops;
251
+ this.registry = registry;
252
+ this.configService = configService;
253
+ this.log = log;
254
+ this.lockTtlMs = lockTtlMs;
255
+ }
256
+ get db() {
257
+ return this.kdb.db;
258
+ }
259
+ config() {
260
+ return this.configService.get();
104
261
  }
105
262
  /** Whether the bootstrap step completed for the manifest with this sha256. */
106
263
  async isDone(manifestSha256) {
107
- const row = await this.d.db
264
+ const row = await this.db
108
265
  .selectFrom("bootstrap_runs")
109
266
  .select("manifest_sha256")
110
267
  .where("manifest_sha256", "=", manifestSha256)
@@ -120,27 +277,41 @@ export class BootstrapService {
120
277
  */
121
278
  async run(o) {
122
279
  const manifestSha256 = bootstrapManifestSha256(o.manifest);
123
- const files = await this.verifyFiles(o.manifest, o.dir);
124
- return this.locked(o.signal, async () => {
125
- const done = await this.d.db
280
+ const recorded = async () => {
281
+ const done = await this.db
126
282
  .selectFrom("bootstrap_runs")
127
283
  .select("results")
128
284
  .where("manifest_sha256", "=", manifestSha256)
129
285
  .executeTakeFirst();
130
- if (done) {
131
- return { manifestSha256, results: done.results };
132
- }
286
+ return done && { manifestSha256, results: done.results };
287
+ };
288
+ // Done: no lock, no directory, no network
289
+ const before = await recorded();
290
+ if (before)
291
+ return before;
292
+ return this.locked(o.signal, async (signal) => {
293
+ // Another replica may have finished it while this one waited for the lock
294
+ const done = await recorded();
295
+ if (done)
296
+ return done;
297
+ // Every package is obtained and checked before the first write
298
+ const files = await resolveBootstrapPackages(o.manifest, {
299
+ ...(o.dir !== undefined && { dir: o.dir }),
300
+ config: this.config(),
301
+ signal,
302
+ log: this.log,
303
+ });
133
304
  const handled = await this.lastRunNames();
134
305
  const results = [];
135
306
  const failures = [];
136
307
  for (const e of o.manifest.plugins) {
137
- o.signal?.throwIfAborted();
308
+ signal.throwIfAborted();
138
309
  try {
139
- const r = await this.entry(e, files.get(e.name), handled);
310
+ const r = await this.entry(e, files.get(e.name), handled, o.imports);
140
311
  results.push(carried(r, o.carry));
141
312
  }
142
313
  catch (err) {
143
- this.d.log.error("bootstrap: a plugin could not be installed", {
314
+ this.log.error("bootstrap: a plugin could not be installed", {
144
315
  plugin: e.name,
145
316
  version: e.version,
146
317
  required: e.required,
@@ -157,63 +328,53 @@ export class BootstrapService {
157
328
  results.push(...(await this.clearRemoved(o.manifest)));
158
329
  if (failures.length > 0)
159
330
  throw new BootstrapFailedError(failures, results);
160
- await this.d.db.transaction().execute(async (trx) => {
161
- await trx
162
- .insertInto("bootstrap_runs")
163
- .values({
164
- manifest_sha256: manifestSha256,
165
- completed_at: sql `now()`,
166
- results: JSON.stringify(results),
167
- })
168
- .execute();
169
- await audit(trx, {
170
- action: "bootstrap.completed",
171
- target: manifestSha256,
172
- detail: { manifestSha256, results },
173
- });
174
- });
175
- this.d.log.info("bootstrap completed", { manifestSha256, results });
331
+ signal.throwIfAborted();
332
+ await this.recordDone(manifestSha256, results);
333
+ this.log.info("bootstrap completed", { manifestSha256, results });
176
334
  return { manifestSha256, results };
177
335
  });
178
336
  }
337
+ /** The `bootstrap_runs` row and the `bootstrap.completed` audit, in one transaction. */
338
+ async recordDone(manifestSha256, results) {
339
+ await this.db
340
+ .insertInto("bootstrap_runs")
341
+ .values({
342
+ manifest_sha256: manifestSha256,
343
+ completed_at: sql `now()`,
344
+ results: JSON.stringify(results),
345
+ })
346
+ .execute();
347
+ await audit(this.db, {
348
+ action: "bootstrap.completed",
349
+ target: manifestSha256,
350
+ detail: { manifestSha256, results },
351
+ });
352
+ }
179
353
  /**
180
- * Runs `fn` holding the session advisory lock on a connection of its own: `pg_try_advisory_lock`
181
- * retried with a backoff (100 ms doubling to 1 s) that stops when `signal` aborts. The connection
182
- * is closed afterwards in every case, which releases the lock even when the unlock failed.
354
+ * Runs `fn` holding `lock:bootstrap`: waits without bound while another replica holds it
355
+ * (until `signal` aborts), renews it while `fn` runs and releases it afterwards. `fn` gets a
356
+ * signal that also aborts when the lock is lost.
183
357
  */
184
358
  async locked(signal, fn) {
185
- const client = new pg.Client({
186
- connectionString: this.d.dbUrl,
187
- ...pgConnectOptions({ connectTimeoutMs: this.d.connectTimeoutMs }),
359
+ const handle = await this.locks.acquire(BOOTSTRAP_LOCK_KEY, {
360
+ ttlMs: this.lockTtlMs,
361
+ waitMs: Number.POSITIVE_INFINITY,
362
+ retryMs: LOCK_RETRY_MS,
363
+ ...(signal !== undefined && { signal }),
188
364
  });
189
- client.on("error", () => { });
365
+ // An unbounded wait returns a handle or throws the abort reason
366
+ if (!handle)
367
+ throw new Error("bootstrap: the lock could not be taken");
190
368
  try {
191
- await client.connect();
192
- for (let wait = 100;; wait = Math.min(wait * 2, 1_000)) {
193
- signal?.throwIfAborted();
194
- const r = await client.query("SELECT pg_try_advisory_lock(hashtext($1)) AS ok", [LOCK_KEY]);
195
- if (r.rows[0]?.ok === true)
196
- break;
197
- await sleep(wait, signal);
198
- }
199
- try {
200
- return await fn();
201
- }
202
- finally {
203
- await client
204
- .query("SELECT pg_advisory_unlock(hashtext($1))", [LOCK_KEY])
205
- .catch((err) => this.d.log.warn("bootstrap: cannot release the advisory lock; closing its connection", {
206
- err,
207
- }));
208
- }
369
+ return await fn(signal ? AbortSignal.any([signal, handle.lost]) : handle.lost);
209
370
  }
210
371
  finally {
211
- await client.end().catch(() => { });
372
+ await handle.release();
212
373
  }
213
374
  }
214
375
  /** The entry names the last completed run handled (undefined before any run completed). */
215
376
  async lastRunNames() {
216
- const row = await this.d.db
377
+ const row = await this.db
217
378
  .selectFrom("bootstrap_runs")
218
379
  .select("results")
219
380
  .orderBy("completed_at", "desc")
@@ -225,31 +386,9 @@ export class BootstrapService {
225
386
  .filter((r) => r.action !== "required_cleared")
226
387
  .map((r) => r.name));
227
388
  }
228
- /** Reads every entry's file and checks its sha512 (before the lock: nothing is written yet). */
229
- async verifyFiles(manifest, dir) {
230
- const out = new Map();
231
- for (const e of manifest.plugins) {
232
- const file = join(dir, bootstrapFileName(e));
233
- let bytes;
234
- try {
235
- bytes = new Uint8Array(await readFile(file));
236
- }
237
- catch (err) {
238
- if (err.code !== "ENOENT")
239
- throw err;
240
- throw new ApiError("bootstrap.missing_file", `Bootstrap plugin ${e.name} ${e.version}: ${file} is missing; the image must carry every package bootstrap.json pins`);
241
- }
242
- const actual = integrityOf(bytes);
243
- if (actual !== e.integrity) {
244
- throw new ApiError("bootstrap.integrity_mismatch", `Bootstrap plugin ${e.name} ${e.version}: ${file} does not match its pinned sha512 (expected ${e.integrity.slice(0, 19)}…, got ${actual.slice(0, 19)}…); refusing to install anything`);
245
- }
246
- out.set(e.name, bytes);
247
- }
248
- return out;
249
- }
250
- async entry(e, bytes, handled) {
389
+ async entry(e, bytes, handled, imports) {
251
390
  const pkg = await readPluginPackage(bytes, {
252
- maxBytes: this.d.config().packages.maxBytes,
391
+ maxBytes: this.config().packages.maxBytes,
253
392
  hostSdkVersion: SDK_VERSION,
254
393
  }).catch((err) => {
255
394
  throw err instanceof PluginPackageError ? catalogPackageError(err) : err;
@@ -263,32 +402,32 @@ export class BootstrapService {
263
402
  if (!pkg.manifest.extension) {
264
403
  if (!isNew)
265
404
  return { name: e.name, action: "kept", version: e.version };
266
- const imported = await this.importOnly(e, bytes, ref);
405
+ const imported = await this.importOnly(e, bytes, ref, imports);
267
406
  return { name: e.name, action: imported ? "imported" : "kept", version: e.version };
268
407
  }
269
- if (this.d.declared?.().has(e.name)) {
270
- this.d.log.warn("bootstrap: the plugin is declared in the extensions config list; the config plugin is used", { plugin: e.name });
408
+ if (this.registry.declared().has(e.name)) {
409
+ this.log.warn("bootstrap: the plugin is declared in the extensions config list; the config plugin is used", { plugin: e.name });
271
410
  return { name: e.name, action: "kept", version: e.version };
272
411
  }
273
- const row = await this.d.db
412
+ const row = await this.db
274
413
  .selectFrom("extension_installs")
275
414
  .select(["version", "source", "required", "desired_state", "sha256"])
276
415
  .where("name", "=", e.name)
277
416
  .executeTakeFirst();
278
417
  if (!row && !isNew && !e.required) {
279
- this.d.log.info("bootstrap: an optional plugin that is not installed stays uninstalled", {
418
+ this.log.info("bootstrap: an optional plugin that is not installed stays uninstalled", {
280
419
  plugin: e.name,
281
420
  });
282
421
  return { name: e.name, action: "kept", version: e.version };
283
422
  }
284
423
  let result;
285
424
  if (!row) {
286
- await this.deploy(e, bytes, ref, true);
425
+ await this.deploy(e, bytes, ref, true, imports);
287
426
  result = { name: e.name, action: "installed", version: e.version };
288
427
  }
289
428
  else if (row.source === "bootstrap" && isLower(row.version, e.version)) {
290
429
  // The desired state the admin chose is kept; a required plugin is enabled below anyway
291
- await this.deploy(e, bytes, ref, row.desired_state === "enabled");
430
+ await this.deploy(e, bytes, ref, row.desired_state === "enabled", imports);
292
431
  result = { name: e.name, action: "upgraded", version: e.version };
293
432
  }
294
433
  else {
@@ -297,12 +436,12 @@ export class BootstrapService {
297
436
  row.sha256 !== createHash("sha256").update(bytes).digest("hex")) {
298
437
  // The pin changed bytes without a version bump (an image built from main between
299
438
  // releases): the installed package stays, so say so instead of keeping it silently
300
- this.d.log.warn("bootstrap: the image's package differs from the installed one at the same version; the installed package is kept (bump the version to roll it out)", { plugin: e.name, version: e.version });
439
+ this.log.warn("bootstrap: the image's package differs from the installed one at the same version; the installed package is kept (bump the version to roll it out)", { plugin: e.name, version: e.version });
301
440
  }
302
441
  result = { name: e.name, action: "kept", version: row.version };
303
442
  }
304
443
  if (row?.required !== e.required) {
305
- await this.d.db
444
+ await this.db
306
445
  .updateTable("extension_installs")
307
446
  .set({ required: e.required })
308
447
  .where("name", "=", e.name)
@@ -310,19 +449,19 @@ export class BootstrapService {
310
449
  }
311
450
  // A required install must run on the deployment (an org cannot use it otherwise)
312
451
  if (e.required && row?.desired_state === "disabled") {
313
- await this.d.ops.enable(e.name, null);
452
+ await this.ops.enable(e.name, null);
314
453
  }
315
454
  return result;
316
455
  }
317
456
  /** A declarative plugin: catalog only. Returns false when that version is already imported. */
318
- async importOnly(e, bytes, ref) {
457
+ async importOnly(e, bytes, ref, imports) {
319
458
  try {
320
- const { stagingId, review } = await this.d.imports.prepare(null, bytes, {
459
+ const { stagingId, review } = await imports.prepare(null, bytes, {
321
460
  kind: "bootstrap",
322
461
  ref,
323
462
  integrity: e.integrity,
324
463
  });
325
- await this.d.imports.confirm(null, stagingId, {
464
+ await imports.confirm(null, stagingId, {
326
465
  reviewHash: review.reviewHash,
327
466
  deployExtension: false,
328
467
  });
@@ -339,10 +478,10 @@ export class BootstrapService {
339
478
  * the catalog already has this version (an earlier run stopped after importing, or the same
340
479
  * package came from a marketplace), the extension is deployed from the package store instead.
341
480
  */
342
- async deploy(e, bytes, ref, enable) {
481
+ async deploy(e, bytes, ref, enable, imports) {
343
482
  let staged;
344
483
  try {
345
- staged = await this.d.imports.prepare(null, bytes, {
484
+ staged = await imports.prepare(null, bytes, {
346
485
  kind: "bootstrap",
347
486
  ref,
348
487
  integrity: e.integrity,
@@ -355,7 +494,7 @@ export class BootstrapService {
355
494
  }
356
495
  throw err;
357
496
  }
358
- const r = await this.d.imports.confirm(null, staged.stagingId, {
497
+ const r = await imports.confirm(null, staged.stagingId, {
359
498
  reviewHash: staged.review.reviewHash,
360
499
  deployExtension: true,
361
500
  enable,
@@ -366,45 +505,47 @@ export class BootstrapService {
366
505
  }
367
506
  /** The extension of a catalog version already imported: ingest, approve, install (, enable). */
368
507
  async deployFromStore(e, bytes, ref, enable) {
369
- const review = await this.d.installs.ingest(null, bytes, { source: "bootstrap", ref }, { store: "pg" });
508
+ const review = await this.installs.ingest(null, bytes, { source: "bootstrap", ref }, { store: "pg" });
370
509
  let set;
371
510
  try {
372
511
  set = permissionSetOfPackage(await readExtensionPackage(bytes, {
373
- maxBytes: this.d.config().packages.maxBytes,
512
+ maxBytes: this.config().packages.maxBytes,
374
513
  hostSdkVersion: SDK_VERSION,
375
514
  }));
376
515
  }
377
516
  catch (err) {
378
517
  throw err instanceof ExtensionPackageError ? catalogPackageError(err) : err;
379
518
  }
380
- await this.d.db.transaction().execute(async (trx) => {
381
- await sql `SELECT pg_advisory_xact_lock(hashtext(${`capybara.plugin-approve:${e.name}`}))`.execute(trx);
382
- const snap = await trx
383
- .selectFrom("extension_permission_snapshots")
384
- .select("permissions")
385
- .where("plugin", "=", e.name)
386
- .forUpdate()
387
- .executeTakeFirst();
388
- const { added, removed } = diffPermissions(snap?.permissions, set);
389
- await writeSnapshot(trx, e.name, e.version, set, {
390
- source: "bootstrap",
391
- audit: { added, removed, sha256: review.sha256 },
392
- });
393
- });
394
- const item = await this.d.db
519
+ await this.approveStored(e, set, review.sha256);
520
+ const item = await this.db
395
521
  .selectFrom("catalog_items")
396
522
  .select("id")
397
523
  .where("name", "=", e.name)
398
524
  .where("deleted_at", "is", null)
399
525
  .executeTakeFirst();
400
- await this.d.ops.install(e.name, review.sha256, null, undefined, item ? { catalogItemId: item.id } : {});
526
+ await this.ops.install(e.name, review.sha256, null, undefined, item ? { catalogItemId: item.id } : {});
401
527
  if (enable)
402
- await this.d.ops.enable(e.name, null);
528
+ await this.ops.enable(e.name, null);
529
+ }
530
+ /** The permission snapshot of a stored package (source `bootstrap`), under the approve lock. */
531
+ async approveStored(e, set, sha256) {
532
+ await this.approveLock.lock(e.name);
533
+ const snap = await this.db
534
+ .selectFrom("extension_permission_snapshots")
535
+ .select("permissions")
536
+ .where("plugin", "=", e.name)
537
+ .forUpdate()
538
+ .executeTakeFirst();
539
+ const { added, removed } = diffPermissions(snap?.permissions, set);
540
+ await writeSnapshot(this.db, e.name, e.version, set, {
541
+ source: "bootstrap",
542
+ audit: { added, removed, sha256 },
543
+ });
403
544
  }
404
545
  /** Install records still `required` whose entry left the manifest lose `required`. */
405
546
  async clearRemoved(manifest) {
406
547
  const names = manifest.plugins.map((p) => p.name);
407
- let q = this.d.db
548
+ let q = this.db
408
549
  .updateTable("extension_installs")
409
550
  .set({ required: false })
410
551
  .where("required", "=", true);
@@ -413,7 +554,28 @@ export class BootstrapService {
413
554
  const rows = await q.returning(["name", "version"]).execute();
414
555
  return rows.map((r) => ({ name: r.name, action: "required_cleared", version: r.version }));
415
556
  }
416
- }
557
+ };
558
+ __decorate([
559
+ Transactional()
560
+ ], BootstrapService.prototype, "recordDone", null);
561
+ __decorate([
562
+ Transactional()
563
+ ], BootstrapService.prototype, "approveStored", null);
564
+ BootstrapService = __decorate([
565
+ Injectable(),
566
+ __param(0, Inject(KernelDb)),
567
+ __param(1, Inject(TransactionHost)),
568
+ __param(2, Inject(LockService)),
569
+ __param(3, Inject(PluginApproveLock)),
570
+ __param(4, Inject(ExtensionInstalls)),
571
+ __param(5, Inject(ExtensionAdminOps)),
572
+ __param(6, Inject(ExtensionRegistry)),
573
+ __param(7, Inject(KernelConfigService)),
574
+ __param(8, Inject(KERNEL_LOGGER)),
575
+ __param(9, Optional()),
576
+ __param(9, Inject(BOOTSTRAP_LOCK_TTL))
577
+ ], BootstrapService);
578
+ export { BootstrapService };
417
579
  /** A `kept` result whose entry an earlier pass of the same start installed / upgraded / imported. */
418
580
  function carried(r, carry) {
419
581
  if (r.action !== "kept")
@@ -423,19 +585,5 @@ function carried(r, carry) {
423
585
  ? before
424
586
  : r;
425
587
  }
426
- /** Resolves after `ms`; rejects with the abort reason when `signal` aborts first. */
427
- function sleep(ms, signal) {
428
- return new Promise((resolve, reject) => {
429
- const onAbort = () => {
430
- clearTimeout(timer);
431
- reject(signal?.reason);
432
- };
433
- const timer = setTimeout(() => {
434
- signal?.removeEventListener("abort", onAbort);
435
- resolve();
436
- }, ms);
437
- signal?.addEventListener("abort", onAbort, { once: true });
438
- });
439
- }
440
588
  /** `installed` is below `pinned` (a version that is not semver is never upgraded). */
441
589
  const isLower = (installed, pinned) => semver.valid(installed) !== null && semver.valid(pinned) !== null && semver.lt(installed, pinned);