@capybara-hq/kernel 0.0.0-stage → 0.1.0-rc.1

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 (637) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +2 -0
  3. package/README.md +20 -2
  4. package/bootstrap.json +26 -0
  5. package/dist/admin/admin.controller.d.ts +139 -0
  6. package/dist/admin/admin.controller.js +238 -0
  7. package/dist/admin/extensions.controller.d.ts +100 -0
  8. package/dist/admin/extensions.controller.js +226 -0
  9. package/dist/admin/setup.controller.d.ts +36 -0
  10. package/dist/admin/setup.controller.js +106 -0
  11. package/dist/admin/setup.service.d.ts +47 -0
  12. package/dist/admin/setup.service.js +90 -0
  13. package/dist/agents/agents.controller.d.ts +205 -0
  14. package/dist/agents/agents.controller.js +144 -0
  15. package/dist/agents/agents.service.d.ts +177 -0
  16. package/dist/agents/agents.service.js +677 -0
  17. package/dist/agents/definition.d.ts +198 -0
  18. package/dist/agents/definition.js +152 -0
  19. package/dist/agents/models.controller.d.ts +13 -0
  20. package/dist/agents/models.controller.js +31 -0
  21. package/dist/agents/templates.controller.d.ts +15 -0
  22. package/dist/agents/templates.controller.js +37 -0
  23. package/dist/agents/templates.d.ts +83 -0
  24. package/dist/agents/templates.js +173 -0
  25. package/dist/catalog/admin-catalog.controller.d.ts +143 -0
  26. package/dist/catalog/admin-catalog.controller.js +245 -0
  27. package/dist/catalog/catalog.service.d.ts +430 -0
  28. package/dist/catalog/catalog.service.js +882 -0
  29. package/dist/catalog/claude/agents.d.ts +27 -0
  30. package/dist/catalog/claude/agents.js +270 -0
  31. package/dist/catalog/claude/commands.d.ts +50 -0
  32. package/dist/catalog/claude/commands.js +179 -0
  33. package/dist/catalog/claude/manifest.d.ts +69 -0
  34. package/dist/catalog/claude/manifest.js +134 -0
  35. package/dist/catalog/claude/marketplace.d.ts +35 -0
  36. package/dist/catalog/claude/marketplace.js +194 -0
  37. package/dist/catalog/claude/mcp.d.ts +33 -0
  38. package/dist/catalog/claude/mcp.js +226 -0
  39. package/dist/catalog/claude/report.d.ts +86 -0
  40. package/dist/catalog/claude/report.js +121 -0
  41. package/dist/catalog/claude/translate.d.ts +56 -0
  42. package/dist/catalog/claude/translate.js +857 -0
  43. package/dist/catalog/cli.d.ts +46 -0
  44. package/dist/catalog/cli.js +211 -0
  45. package/dist/catalog/git-source.d.ts +127 -0
  46. package/dist/catalog/git-source.js +520 -0
  47. package/dist/catalog/marketplace-fetch.d.ts +99 -0
  48. package/dist/catalog/marketplace-fetch.js +203 -0
  49. package/dist/catalog/marketplaces.controller.d.ts +97 -0
  50. package/dist/catalog/marketplaces.controller.js +197 -0
  51. package/dist/catalog/marketplaces.service.d.ts +340 -0
  52. package/dist/catalog/marketplaces.service.js +1217 -0
  53. package/dist/catalog/org-catalog.controller.d.ts +128 -0
  54. package/dist/catalog/org-catalog.controller.js +277 -0
  55. package/dist/catalog/org-catalog.service.d.ts +246 -0
  56. package/dist/catalog/org-catalog.service.js +625 -0
  57. package/dist/catalog/plugin-import.d.ts +436 -0
  58. package/dist/catalog/plugin-import.js +1069 -0
  59. package/dist/catalog/plugin-install.d.ts +447 -0
  60. package/dist/catalog/plugin-install.js +1333 -0
  61. package/dist/catalog/plugin-package.d.ts +143 -0
  62. package/dist/catalog/plugin-package.js +382 -0
  63. package/dist/catalog/plugin-upgrade.d.ts +222 -0
  64. package/dist/catalog/plugin-upgrade.js +1219 -0
  65. package/dist/catalog/requests.service.d.ts +162 -0
  66. package/dist/catalog/requests.service.js +504 -0
  67. package/dist/catalog/schema-path.d.ts +7 -0
  68. package/dist/catalog/schema-path.js +63 -0
  69. package/dist/catalog/upgrade-targets.d.ts +59 -0
  70. package/dist/catalog/upgrade-targets.js +90 -0
  71. package/dist/catalog/versions.d.ts +31 -0
  72. package/dist/catalog/versions.js +44 -0
  73. package/dist/channels/actions.d.ts +37 -0
  74. package/dist/channels/actions.js +121 -0
  75. package/dist/channels/cards.d.ts +44 -0
  76. package/dist/channels/cards.js +156 -0
  77. package/dist/channels/connections.controller.d.ts +59 -0
  78. package/dist/channels/connections.controller.js +115 -0
  79. package/dist/channels/connections.service.d.ts +187 -0
  80. package/dist/channels/connections.service.js +534 -0
  81. package/dist/channels/features.d.ts +12 -0
  82. package/dist/channels/features.js +22 -0
  83. package/dist/channels/inbound.d.ts +120 -0
  84. package/dist/channels/inbound.js +332 -0
  85. package/dist/channels/outbound.d.ts +140 -0
  86. package/dist/channels/outbound.js +1126 -0
  87. package/dist/channels/phrases.d.ts +100 -0
  88. package/dist/channels/phrases.js +81 -0
  89. package/dist/channels/supervisor.d.ts +182 -0
  90. package/dist/channels/supervisor.js +625 -0
  91. package/dist/channels/threads.d.ts +29 -0
  92. package/dist/channels/threads.js +104 -0
  93. package/dist/channels/webhook-url.d.ts +16 -0
  94. package/dist/channels/webhook-url.js +34 -0
  95. package/dist/channels/webhook.controller.d.ts +19 -0
  96. package/dist/channels/webhook.controller.js +72 -0
  97. package/dist/channels/webhook.d.ts +73 -0
  98. package/dist/channels/webhook.js +274 -0
  99. package/dist/config/docs.d.ts +9 -0
  100. package/dist/config/docs.js +85 -0
  101. package/dist/config/env.d.ts +6 -0
  102. package/dist/config/env.js +73 -0
  103. package/dist/config/fields.d.ts +42 -0
  104. package/dist/config/fields.js +214 -0
  105. package/dist/config/file-source.d.ts +3 -0
  106. package/dist/config/file-source.js +31 -0
  107. package/dist/config/load.d.ts +20 -0
  108. package/dist/config/load.js +98 -0
  109. package/dist/config/nacos-source.d.ts +31 -0
  110. package/dist/config/nacos-source.js +229 -0
  111. package/dist/config/schema.d.ts +237 -0
  112. package/dist/config/schema.js +1192 -0
  113. package/dist/config/sources.d.ts +18 -0
  114. package/dist/config/sources.js +59 -0
  115. package/dist/config/types.d.ts +9 -0
  116. package/dist/config/types.js +7 -0
  117. package/dist/conversations/artifacts.d.ts +52 -0
  118. package/dist/conversations/artifacts.js +137 -0
  119. package/dist/conversations/attachments.controller.d.ts +28 -0
  120. package/dist/conversations/attachments.controller.js +96 -0
  121. package/dist/conversations/attachments.service.d.ts +180 -0
  122. package/dist/conversations/attachments.service.js +578 -0
  123. package/dist/conversations/conversations.controller.d.ts +288 -0
  124. package/dist/conversations/conversations.controller.js +607 -0
  125. package/dist/conversations/conversations.service.d.ts +321 -0
  126. package/dist/conversations/conversations.service.js +754 -0
  127. package/dist/conversations/event-log.d.ts +122 -0
  128. package/dist/conversations/event-log.js +259 -0
  129. package/dist/conversations/events.d.ts +856 -0
  130. package/dist/conversations/events.js +639 -0
  131. package/dist/conversations/files.d.ts +92 -0
  132. package/dist/conversations/files.js +213 -0
  133. package/dist/conversations/outputs-read.d.ts +34 -0
  134. package/dist/conversations/outputs-read.js +37 -0
  135. package/dist/conversations/queue.d.ts +169 -0
  136. package/dist/conversations/queue.js +527 -0
  137. package/dist/conversations/sandbox-status.d.ts +21 -0
  138. package/dist/conversations/sandbox-status.js +24 -0
  139. package/dist/conversations/selection.d.ts +46 -0
  140. package/dist/conversations/selection.js +75 -0
  141. package/dist/conversations/titles.d.ts +93 -0
  142. package/dist/conversations/titles.js +423 -0
  143. package/dist/ctx/bus.d.ts +16 -0
  144. package/dist/ctx/bus.js +101 -0
  145. package/dist/ctx/create-ctx.d.ts +109 -0
  146. package/dist/ctx/create-ctx.js +592 -0
  147. package/dist/ctx/kv.d.ts +4 -0
  148. package/dist/ctx/kv.js +31 -0
  149. package/dist/ctx/lock.d.ts +4 -0
  150. package/dist/ctx/lock.js +39 -0
  151. package/dist/ctx/namespace.d.ts +6 -0
  152. package/dist/ctx/namespace.js +12 -0
  153. package/dist/ctx/queue.d.ts +25 -0
  154. package/dist/ctx/queue.js +151 -0
  155. package/dist/ctx/secrets.d.ts +45 -0
  156. package/dist/ctx/secrets.js +175 -0
  157. package/dist/db/kernel-schema.d.ts +1122 -0
  158. package/dist/db/kernel-schema.js +5 -0
  159. package/dist/db/migrator.d.ts +28 -0
  160. package/dist/db/migrator.js +140 -0
  161. package/dist/db/pool.d.ts +21 -0
  162. package/dist/db/pool.js +28 -0
  163. package/dist/db/sql-statements.d.ts +34 -0
  164. package/dist/db/sql-statements.js +168 -0
  165. package/dist/errors.d.ts +211 -0
  166. package/dist/errors.js +213 -0
  167. package/dist/evals/budget.d.ts +61 -0
  168. package/dist/evals/budget.js +181 -0
  169. package/dist/evals/diff.d.ts +55 -0
  170. package/dist/evals/diff.js +133 -0
  171. package/dist/evals/judge.d.ts +53 -0
  172. package/dist/evals/judge.js +149 -0
  173. package/dist/evals/plan.d.ts +47 -0
  174. package/dist/evals/plan.js +77 -0
  175. package/dist/evals/reconstruct.d.ts +137 -0
  176. package/dist/evals/reconstruct.js +322 -0
  177. package/dist/evals/recorded-tools.d.ts +54 -0
  178. package/dist/evals/recorded-tools.js +167 -0
  179. package/dist/evals/run-replay.d.ts +86 -0
  180. package/dist/evals/run-replay.js +502 -0
  181. package/dist/evals/runs.controller.d.ts +100 -0
  182. package/dist/evals/runs.controller.js +199 -0
  183. package/dist/evals/runs.service.d.ts +275 -0
  184. package/dist/evals/runs.service.js +836 -0
  185. package/dist/evals/sets.controller.d.ts +61 -0
  186. package/dist/evals/sets.controller.js +183 -0
  187. package/dist/evals/sets.service.d.ts +128 -0
  188. package/dist/evals/sets.service.js +558 -0
  189. package/dist/evals/snapshot.d.ts +76 -0
  190. package/dist/evals/snapshot.js +207 -0
  191. package/dist/evals/step-replay.d.ts +113 -0
  192. package/dist/evals/step-replay.js +181 -0
  193. package/dist/evals/trajectory.controller.d.ts +41 -0
  194. package/dist/evals/trajectory.controller.js +88 -0
  195. package/dist/evals/trajectory.d.ts +144 -0
  196. package/dist/evals/trajectory.js +338 -0
  197. package/dist/evals/trajectory.service.d.ts +108 -0
  198. package/dist/evals/trajectory.service.js +323 -0
  199. package/dist/evals/worker.d.ts +101 -0
  200. package/dist/evals/worker.js +790 -0
  201. package/dist/extensions/admin-ops.d.ts +105 -0
  202. package/dist/extensions/admin-ops.js +353 -0
  203. package/dist/extensions/admin-view.d.ts +79 -0
  204. package/dist/extensions/admin-view.js +327 -0
  205. package/dist/extensions/approvals.d.ts +119 -0
  206. package/dist/extensions/approvals.js +205 -0
  207. package/dist/extensions/blobs.d.ts +45 -0
  208. package/dist/extensions/blobs.js +160 -0
  209. package/dist/extensions/bootstrap.d.ts +176 -0
  210. package/dist/extensions/bootstrap.js +535 -0
  211. package/dist/extensions/cli.d.ts +61 -0
  212. package/dist/extensions/cli.js +165 -0
  213. package/dist/extensions/config-json-schema.d.ts +9 -0
  214. package/dist/extensions/config-json-schema.js +73 -0
  215. package/dist/extensions/deployment-config.d.ts +138 -0
  216. package/dist/extensions/deployment-config.js +394 -0
  217. package/dist/extensions/enabled.d.ts +31 -0
  218. package/dist/extensions/enabled.js +55 -0
  219. package/dist/extensions/hooks.d.ts +161 -0
  220. package/dist/extensions/hooks.js +425 -0
  221. package/dist/extensions/host.d.ts +577 -0
  222. package/dist/extensions/host.js +2071 -0
  223. package/dist/extensions/inflight.d.ts +69 -0
  224. package/dist/extensions/inflight.js +277 -0
  225. package/dist/extensions/installs.d.ts +166 -0
  226. package/dist/extensions/installs.js +253 -0
  227. package/dist/extensions/instance.d.ts +167 -0
  228. package/dist/extensions/instance.js +329 -0
  229. package/dist/extensions/ledger.d.ts +30 -0
  230. package/dist/extensions/ledger.js +50 -0
  231. package/dist/extensions/lifecycle.d.ts +80 -0
  232. package/dist/extensions/lifecycle.js +152 -0
  233. package/dist/extensions/migrate-lock.d.ts +51 -0
  234. package/dist/extensions/migrate-lock.js +100 -0
  235. package/dist/extensions/org-config.controller.d.ts +24 -0
  236. package/dist/extensions/org-config.controller.js +59 -0
  237. package/dist/extensions/org-config.d.ts +169 -0
  238. package/dist/extensions/org-config.js +520 -0
  239. package/dist/extensions/package.d.ts +115 -0
  240. package/dist/extensions/package.js +246 -0
  241. package/dist/extensions/permission-set.d.ts +117 -0
  242. package/dist/extensions/permission-set.js +184 -0
  243. package/dist/extensions/permission-view.d.ts +194 -0
  244. package/dist/extensions/permission-view.js +284 -0
  245. package/dist/extensions/registry.d.ts +24 -0
  246. package/dist/extensions/registry.js +56 -0
  247. package/dist/extensions/resolve.d.ts +12 -0
  248. package/dist/extensions/resolve.js +71 -0
  249. package/dist/extensions/sources.d.ts +69 -0
  250. package/dist/extensions/sources.js +120 -0
  251. package/dist/extensions/sync.d.ts +40 -0
  252. package/dist/extensions/sync.js +242 -0
  253. package/dist/files/previewers.controller.d.ts +46 -0
  254. package/dist/files/previewers.controller.js +105 -0
  255. package/dist/files/previewers.d.ts +100 -0
  256. package/dist/files/previewers.js +250 -0
  257. package/dist/http/api.module.d.ts +114 -0
  258. package/dist/http/api.module.js +448 -0
  259. package/dist/http/app.d.ts +77 -0
  260. package/dist/http/app.js +220 -0
  261. package/dist/http/error.filter.d.ts +21 -0
  262. package/dist/http/error.filter.js +85 -0
  263. package/dist/http/gateway.module.d.ts +15 -0
  264. package/dist/http/gateway.module.js +13 -0
  265. package/dist/http/health.controller.d.ts +26 -0
  266. package/dist/http/health.controller.js +79 -0
  267. package/dist/http/nest-logger.d.ts +20 -0
  268. package/dist/http/nest-logger.js +28 -0
  269. package/dist/http/plugin-dispatch.d.ts +68 -0
  270. package/dist/http/plugin-dispatch.js +200 -0
  271. package/dist/http/tokens.d.ts +131 -0
  272. package/dist/http/tokens.js +131 -0
  273. package/dist/http/zod.pipe.d.ts +8 -0
  274. package/dist/http/zod.pipe.js +14 -0
  275. package/dist/identity/accounts.d.ts +93 -0
  276. package/dist/identity/accounts.js +367 -0
  277. package/dist/identity/api-tokens.d.ts +73 -0
  278. package/dist/identity/api-tokens.js +197 -0
  279. package/dist/identity/audit.d.ts +23 -0
  280. package/dist/identity/audit.js +41 -0
  281. package/dist/identity/auth.controller.d.ts +40 -0
  282. package/dist/identity/auth.controller.js +130 -0
  283. package/dist/identity/auth.guard.d.ts +41 -0
  284. package/dist/identity/auth.guard.js +162 -0
  285. package/dist/identity/binding.d.ts +47 -0
  286. package/dist/identity/binding.js +84 -0
  287. package/dist/identity/cookies.d.ts +16 -0
  288. package/dist/identity/cookies.js +32 -0
  289. package/dist/identity/credential-check.d.ts +17 -0
  290. package/dist/identity/credential-check.js +24 -0
  291. package/dist/identity/enterprise-admin.d.ts +14 -0
  292. package/dist/identity/enterprise-admin.js +27 -0
  293. package/dist/identity/external.d.ts +106 -0
  294. package/dist/identity/external.js +337 -0
  295. package/dist/identity/hash.d.ts +2 -0
  296. package/dist/identity/hash.js +3 -0
  297. package/dist/identity/login.d.ts +6 -0
  298. package/dist/identity/login.js +20 -0
  299. package/dist/identity/me.controller.d.ts +61 -0
  300. package/dist/identity/me.controller.js +159 -0
  301. package/dist/identity/passwords.d.ts +6 -0
  302. package/dist/identity/passwords.js +37 -0
  303. package/dist/identity/principal.d.ts +56 -0
  304. package/dist/identity/principal.js +38 -0
  305. package/dist/identity/rate-limit.d.ts +55 -0
  306. package/dist/identity/rate-limit.js +121 -0
  307. package/dist/identity/sessions.d.ts +84 -0
  308. package/dist/identity/sessions.js +306 -0
  309. package/dist/identity/settings.d.ts +121 -0
  310. package/dist/identity/settings.js +248 -0
  311. package/dist/identity/sso.controller.d.ts +59 -0
  312. package/dist/identity/sso.controller.js +192 -0
  313. package/dist/identity/sso.d.ts +83 -0
  314. package/dist/identity/sso.js +202 -0
  315. package/dist/inbox/inbox.service.d.ts +43 -0
  316. package/dist/inbox/inbox.service.js +57 -0
  317. package/dist/index.d.ts +69 -0
  318. package/dist/index.js +67 -0
  319. package/dist/kernel.d.ts +259 -0
  320. package/dist/kernel.js +1326 -0
  321. package/dist/log-config.d.ts +9 -0
  322. package/dist/log-config.js +27 -0
  323. package/dist/log-context.d.ts +32 -0
  324. package/dist/log-context.js +40 -0
  325. package/dist/log-loki.d.ts +34 -0
  326. package/dist/log-loki.js +145 -0
  327. package/dist/log.d.ts +79 -0
  328. package/dist/log.js +303 -0
  329. package/dist/models/prices.d.ts +53 -0
  330. package/dist/models/prices.js +121 -0
  331. package/dist/models/purposes.controller.d.ts +19 -0
  332. package/dist/models/purposes.controller.js +56 -0
  333. package/dist/models/purposes.d.ts +140 -0
  334. package/dist/models/purposes.js +267 -0
  335. package/dist/net/proxy.d.ts +44 -0
  336. package/dist/net/proxy.js +162 -0
  337. package/dist/net/public-address.d.ts +60 -0
  338. package/dist/net/public-address.js +272 -0
  339. package/dist/net/safe-fetch.d.ts +38 -0
  340. package/dist/net/safe-fetch.js +140 -0
  341. package/dist/orgs/directory-sync.controller.d.ts +14 -0
  342. package/dist/orgs/directory-sync.controller.js +40 -0
  343. package/dist/orgs/directory-sync.d.ts +166 -0
  344. package/dist/orgs/directory-sync.js +558 -0
  345. package/dist/orgs/invitations.controller.d.ts +58 -0
  346. package/dist/orgs/invitations.controller.js +137 -0
  347. package/dist/orgs/invitations.service.d.ts +80 -0
  348. package/dist/orgs/invitations.service.js +217 -0
  349. package/dist/orgs/members.service.d.ts +63 -0
  350. package/dist/orgs/members.service.js +234 -0
  351. package/dist/orgs/offboarding.d.ts +141 -0
  352. package/dist/orgs/offboarding.js +398 -0
  353. package/dist/orgs/org-lock.d.ts +32 -0
  354. package/dist/orgs/org-lock.js +46 -0
  355. package/dist/orgs/org.guard.d.ts +35 -0
  356. package/dist/orgs/org.guard.js +95 -0
  357. package/dist/orgs/orgs.controller.d.ts +78 -0
  358. package/dist/orgs/orgs.controller.js +192 -0
  359. package/dist/orgs/orgs.service.d.ts +61 -0
  360. package/dist/orgs/orgs.service.js +209 -0
  361. package/dist/orgs/roles.d.ts +13 -0
  362. package/dist/orgs/roles.js +58 -0
  363. package/dist/orgs/settings.controller.d.ts +20 -0
  364. package/dist/orgs/settings.controller.js +53 -0
  365. package/dist/orgs/settings.service.d.ts +120 -0
  366. package/dist/orgs/settings.service.js +178 -0
  367. package/dist/packages/npm.d.ts +50 -0
  368. package/dist/packages/npm.js +218 -0
  369. package/dist/packages/provenance.d.ts +47 -0
  370. package/dist/packages/provenance.js +147 -0
  371. package/dist/packages/tgz.d.ts +76 -0
  372. package/dist/packages/tgz.js +225 -0
  373. package/dist/runtime/abort.d.ts +32 -0
  374. package/dist/runtime/abort.js +71 -0
  375. package/dist/runtime/checkpointer.d.ts +32 -0
  376. package/dist/runtime/checkpointer.js +243 -0
  377. package/dist/runtime/context/build.d.ts +254 -0
  378. package/dist/runtime/context/build.js +693 -0
  379. package/dist/runtime/context/claude-tools.d.ts +11 -0
  380. package/dist/runtime/context/claude-tools.js +24 -0
  381. package/dist/runtime/context/compaction.d.ts +26 -0
  382. package/dist/runtime/context/compaction.js +195 -0
  383. package/dist/runtime/context/pairing.d.ts +11 -0
  384. package/dist/runtime/context/pairing.js +82 -0
  385. package/dist/runtime/context/reminders.d.ts +5 -0
  386. package/dist/runtime/context/reminders.js +11 -0
  387. package/dist/runtime/context/skills.d.ts +105 -0
  388. package/dist/runtime/context/skills.js +283 -0
  389. package/dist/runtime/context/tokens.d.ts +19 -0
  390. package/dist/runtime/context/tokens.js +104 -0
  391. package/dist/runtime/conversation-lock.d.ts +40 -0
  392. package/dist/runtime/conversation-lock.js +97 -0
  393. package/dist/runtime/hook-calls.d.ts +84 -0
  394. package/dist/runtime/hook-calls.js +136 -0
  395. package/dist/runtime/langgraph-loop.d.ts +52 -0
  396. package/dist/runtime/langgraph-loop.js +247 -0
  397. package/dist/runtime/loop.d.ts +93 -0
  398. package/dist/runtime/loop.js +7 -0
  399. package/dist/runtime/maintenance.d.ts +80 -0
  400. package/dist/runtime/maintenance.js +148 -0
  401. package/dist/runtime/media-cache.d.ts +21 -0
  402. package/dist/runtime/media-cache.js +51 -0
  403. package/dist/runtime/model-call.d.ts +176 -0
  404. package/dist/runtime/model-call.js +1049 -0
  405. package/dist/runtime/providers.d.ts +86 -0
  406. package/dist/runtime/providers.js +224 -0
  407. package/dist/runtime/quota.d.ts +29 -0
  408. package/dist/runtime/quota.js +70 -0
  409. package/dist/runtime/run-finish.d.ts +45 -0
  410. package/dist/runtime/run-finish.js +69 -0
  411. package/dist/runtime/run-queue.d.ts +121 -0
  412. package/dist/runtime/run-queue.js +493 -0
  413. package/dist/runtime/run-worker.d.ts +138 -0
  414. package/dist/runtime/run-worker.js +806 -0
  415. package/dist/runtime/stream.controller.d.ts +34 -0
  416. package/dist/runtime/stream.controller.js +122 -0
  417. package/dist/runtime/stream.d.ts +63 -0
  418. package/dist/runtime/stream.js +262 -0
  419. package/dist/runtime/subagents/child.d.ts +80 -0
  420. package/dist/runtime/subagents/child.js +225 -0
  421. package/dist/runtime/subagents/definition.d.ts +103 -0
  422. package/dist/runtime/subagents/definition.js +392 -0
  423. package/dist/runtime/subagents/dispatch.d.ts +69 -0
  424. package/dist/runtime/subagents/dispatch.js +502 -0
  425. package/dist/runtime/subagents/limits.d.ts +23 -0
  426. package/dist/runtime/subagents/limits.js +34 -0
  427. package/dist/runtime/subagents/org-agents.d.ts +50 -0
  428. package/dist/runtime/subagents/org-agents.js +70 -0
  429. package/dist/runtime/subagents/preamble.d.ts +7 -0
  430. package/dist/runtime/subagents/preamble.js +11 -0
  431. package/dist/runtime/subagents/progress.d.ts +26 -0
  432. package/dist/runtime/subagents/progress.js +36 -0
  433. package/dist/runtime/subagents/roster.d.ts +55 -0
  434. package/dist/runtime/subagents/roster.js +111 -0
  435. package/dist/runtime/subagents/skill-fork.d.ts +123 -0
  436. package/dist/runtime/subagents/skill-fork.js +259 -0
  437. package/dist/runtime/usage-report.d.ts +163 -0
  438. package/dist/runtime/usage-report.js +551 -0
  439. package/dist/runtime/waits.d.ts +233 -0
  440. package/dist/runtime/waits.js +883 -0
  441. package/dist/sandbox/leases.d.ts +169 -0
  442. package/dist/sandbox/leases.js +515 -0
  443. package/dist/sandbox/lifecycle.d.ts +21 -0
  444. package/dist/sandbox/lifecycle.js +68 -0
  445. package/dist/sandbox/sandbox.service.d.ts +249 -0
  446. package/dist/sandbox/sandbox.service.js +908 -0
  447. package/dist/skills/catalog.d.ts +149 -0
  448. package/dist/skills/catalog.js +405 -0
  449. package/dist/skills/changes.controller.d.ts +56 -0
  450. package/dist/skills/changes.controller.js +136 -0
  451. package/dist/skills/changes.service.d.ts +175 -0
  452. package/dist/skills/changes.service.js +805 -0
  453. package/dist/skills/invocable.controller.d.ts +23 -0
  454. package/dist/skills/invocable.controller.js +50 -0
  455. package/dist/skills/invocation-keys.d.ts +23 -0
  456. package/dist/skills/invocation-keys.js +44 -0
  457. package/dist/skills/invoke.d.ts +135 -0
  458. package/dist/skills/invoke.js +286 -0
  459. package/dist/skills/package.d.ts +87 -0
  460. package/dist/skills/package.js +227 -0
  461. package/dist/skills/skills.controller.d.ts +40 -0
  462. package/dist/skills/skills.controller.js +110 -0
  463. package/dist/skills/skills.service.d.ts +192 -0
  464. package/dist/skills/skills.service.js +567 -0
  465. package/dist/storage/prefix.d.ts +36 -0
  466. package/dist/storage/prefix.js +104 -0
  467. package/dist/storage/purge.d.ts +27 -0
  468. package/dist/storage/purge.js +75 -0
  469. package/dist/storage/storage.service.d.ts +44 -0
  470. package/dist/storage/storage.service.js +145 -0
  471. package/dist/text.d.ts +13 -0
  472. package/dist/text.js +13 -0
  473. package/dist/tools/approvals.controller.d.ts +53 -0
  474. package/dist/tools/approvals.controller.js +128 -0
  475. package/dist/tools/approvals.service.d.ts +172 -0
  476. package/dist/tools/approvals.service.js +568 -0
  477. package/dist/tools/breaker.d.ts +28 -0
  478. package/dist/tools/breaker.js +72 -0
  479. package/dist/tools/builtins/agent.d.ts +81 -0
  480. package/dist/tools/builtins/agent.js +223 -0
  481. package/dist/tools/builtins/ask-user.d.ts +28 -0
  482. package/dist/tools/builtins/ask-user.js +139 -0
  483. package/dist/tools/builtins/read-tool-output.d.ts +18 -0
  484. package/dist/tools/builtins/read-tool-output.js +108 -0
  485. package/dist/tools/builtins/sandbox/bash.d.ts +16 -0
  486. package/dist/tools/builtins/sandbox/bash.js +137 -0
  487. package/dist/tools/builtins/sandbox/common.d.ts +116 -0
  488. package/dist/tools/builtins/sandbox/common.js +306 -0
  489. package/dist/tools/builtins/sandbox/deliver.d.ts +5 -0
  490. package/dist/tools/builtins/sandbox/deliver.js +180 -0
  491. package/dist/tools/builtins/sandbox/edit.d.ts +4 -0
  492. package/dist/tools/builtins/sandbox/edit.js +98 -0
  493. package/dist/tools/builtins/sandbox/glob-match.d.ts +25 -0
  494. package/dist/tools/builtins/sandbox/glob-match.js +240 -0
  495. package/dist/tools/builtins/sandbox/glob.d.ts +4 -0
  496. package/dist/tools/builtins/sandbox/glob.js +104 -0
  497. package/dist/tools/builtins/sandbox/grep.d.ts +9 -0
  498. package/dist/tools/builtins/sandbox/grep.js +133 -0
  499. package/dist/tools/builtins/sandbox/index.d.ts +12 -0
  500. package/dist/tools/builtins/sandbox/index.js +27 -0
  501. package/dist/tools/builtins/sandbox/names.d.ts +7 -0
  502. package/dist/tools/builtins/sandbox/names.js +20 -0
  503. package/dist/tools/builtins/sandbox/read.d.ts +8 -0
  504. package/dist/tools/builtins/sandbox/read.js +121 -0
  505. package/dist/tools/builtins/sandbox/write.d.ts +4 -0
  506. package/dist/tools/builtins/sandbox/write.js +88 -0
  507. package/dist/tools/builtins/skill-load.d.ts +53 -0
  508. package/dist/tools/builtins/skill-load.js +446 -0
  509. package/dist/tools/builtins/skill-write.d.ts +59 -0
  510. package/dist/tools/builtins/skill-write.js +244 -0
  511. package/dist/tools/builtins/tool-search.d.ts +31 -0
  512. package/dist/tools/builtins/tool-search.js +171 -0
  513. package/dist/tools/connector-content.controller.d.ts +34 -0
  514. package/dist/tools/connector-content.controller.js +78 -0
  515. package/dist/tools/connector-content.d.ts +104 -0
  516. package/dist/tools/connector-content.js +267 -0
  517. package/dist/tools/connectors.controller.d.ts +210 -0
  518. package/dist/tools/connectors.controller.js +234 -0
  519. package/dist/tools/connectors.service.d.ts +303 -0
  520. package/dist/tools/connectors.service.js +1102 -0
  521. package/dist/tools/credentials.d.ts +139 -0
  522. package/dist/tools/credentials.js +351 -0
  523. package/dist/tools/drift.d.ts +141 -0
  524. package/dist/tools/drift.js +539 -0
  525. package/dist/tools/elicitation.d.ts +81 -0
  526. package/dist/tools/elicitation.js +266 -0
  527. package/dist/tools/endpoint.d.ts +18 -0
  528. package/dist/tools/endpoint.js +115 -0
  529. package/dist/tools/info.d.ts +67 -0
  530. package/dist/tools/info.js +113 -0
  531. package/dist/tools/naming.d.ts +27 -0
  532. package/dist/tools/naming.js +47 -0
  533. package/dist/tools/oauth/discovery.d.ts +65 -0
  534. package/dist/tools/oauth/discovery.js +307 -0
  535. package/dist/tools/oauth/flow.d.ts +63 -0
  536. package/dist/tools/oauth/flow.js +237 -0
  537. package/dist/tools/oauth/oauth.controller.d.ts +31 -0
  538. package/dist/tools/oauth/oauth.controller.js +95 -0
  539. package/dist/tools/oauth/tokens.d.ts +111 -0
  540. package/dist/tools/oauth/tokens.js +258 -0
  541. package/dist/tools/outputs.d.ts +61 -0
  542. package/dist/tools/outputs.js +156 -0
  543. package/dist/tools/pipeline.d.ts +322 -0
  544. package/dist/tools/pipeline.js +1236 -0
  545. package/dist/tools/policy.d.ts +60 -0
  546. package/dist/tools/policy.js +236 -0
  547. package/dist/tools/questions.controller.d.ts +24 -0
  548. package/dist/tools/questions.controller.js +58 -0
  549. package/dist/tools/questions.service.d.ts +103 -0
  550. package/dist/tools/questions.service.js +295 -0
  551. package/dist/tools/redact.d.ts +20 -0
  552. package/dist/tools/redact.js +60 -0
  553. package/dist/tools/registry.d.ts +246 -0
  554. package/dist/tools/registry.js +481 -0
  555. package/dist/tools/resources.d.ts +16 -0
  556. package/dist/tools/resources.js +76 -0
  557. package/dist/tools/specs.d.ts +14 -0
  558. package/dist/tools/specs.js +31 -0
  559. package/dist/tools/validate.d.ts +20 -0
  560. package/dist/tools/validate.js +183 -0
  561. package/dist/tools/view.d.ts +43 -0
  562. package/dist/tools/view.js +225 -0
  563. package/dist/ui/embed-token.d.ts +31 -0
  564. package/dist/ui/embed-token.js +132 -0
  565. package/dist/ui/registry.d.ts +58 -0
  566. package/dist/ui/registry.js +90 -0
  567. package/dist/ui/ui-stream.d.ts +37 -0
  568. package/dist/ui/ui-stream.js +162 -0
  569. package/dist/ui/views.controller.d.ts +81 -0
  570. package/dist/ui/views.controller.js +261 -0
  571. package/dist/ui/views.d.ts +155 -0
  572. package/dist/ui/views.js +306 -0
  573. package/dist/version.d.ts +5 -0
  574. package/dist/version.js +6 -0
  575. package/package.json +69 -3
  576. package/src/migrations/0001_init.sql +8 -0
  577. package/src/migrations/0002_secrets.sql +8 -0
  578. package/src/migrations/0003_identity.sql +117 -0
  579. package/src/migrations/0004_plugin_org_config_nullable.sql +3 -0
  580. package/src/migrations/0005_agents.sql +27 -0
  581. package/src/migrations/0006_conversations.sql +37 -0
  582. package/src/migrations/0007_checkpoints.sql +26 -0
  583. package/src/migrations/0008_runs_trigger_seq.sql +3 -0
  584. package/src/migrations/0009_runs_active_unique.sql +4 -0
  585. package/src/migrations/0010_tools.sql +125 -0
  586. package/src/migrations/0011_approvals_spec.sql +10 -0
  587. package/src/migrations/0012_run_waits.sql +24 -0
  588. package/src/migrations/0013_app_tools_source.sql +4 -0
  589. package/src/migrations/0014_tool_specs.sql +8 -0
  590. package/src/migrations/0015_tool_drift.sql +20 -0
  591. package/src/migrations/0016_plugin_permissions.sql +11 -0
  592. package/src/migrations/0017_identity_sources.sql +6 -0
  593. package/src/migrations/0018_channels.sql +74 -0
  594. package/src/migrations/0019_identity_trust.sql +17 -0
  595. package/src/migrations/0020_channel_card_lookup.sql +10 -0
  596. package/src/migrations/0021_org_storage_purge.sql +9 -0
  597. package/src/migrations/0022_attachments.sql +29 -0
  598. package/src/migrations/0023_sandboxes.sql +37 -0
  599. package/src/migrations/0024_skills.sql +46 -0
  600. package/src/migrations/0025_skills_catalog_idx.sql +6 -0
  601. package/src/migrations/0026_skill_changes.sql +34 -0
  602. package/src/migrations/0027_model_prices.sql +18 -0
  603. package/src/migrations/0028_evals.sql +105 -0
  604. package/src/migrations/0029_model_purposes.sql +18 -0
  605. package/src/migrations/0030_plugin_installs.sql +73 -0
  606. package/src/migrations/0031_plugin_snapshot_source.sql +6 -0
  607. package/src/migrations/0032_plugin_deployment_configs.sql +10 -0
  608. package/src/migrations/0033_rename_apps_to_connectors.sql +25 -0
  609. package/src/migrations/0034_directory.sql +49 -0
  610. package/src/migrations/0035_catalogs.sql +40 -0
  611. package/src/migrations/0036_app_import_staging.sql +17 -0
  612. package/src/migrations/0037_directory_installs.sql +92 -0
  613. package/src/migrations/0038_channel_inbound_mode.sql +6 -0
  614. package/src/migrations/0039_channel_card_pending.sql +8 -0
  615. package/src/migrations/0040_usage_report_sweep.sql +10 -0
  616. package/src/migrations/0041_rename_plugins_to_extensions.sql +38 -0
  617. package/src/migrations/0042_rename_directory_to_catalog.sql +80 -0
  618. package/src/migrations/0043_rename_app_installs_to_plugin_installs.sql +20 -0
  619. package/src/migrations/0044_catalog_one_kind.sql +90 -0
  620. package/src/migrations/0045_plugin_dependencies.sql +9 -0
  621. package/src/migrations/0046_git_sources.sql +25 -0
  622. package/src/migrations/0047_marketplace_entry_heads.sql +7 -0
  623. package/src/migrations/0048_marketplace_entry_trees.sql +8 -0
  624. package/src/migrations/0049_plugin_upgrades.sql +37 -0
  625. package/src/migrations/0050_bootstrap.sql +53 -0
  626. package/src/migrations/0051_claude_compat.sql +26 -0
  627. package/src/migrations/0052_conversations_account_agent_idx.sql +5 -0
  628. package/src/migrations/0053_subagents.sql +73 -0
  629. package/src/migrations/0054_subagent_wait_expiry.sql +7 -0
  630. package/src/migrations/0055_subagent_parent_indexes.sql +10 -0
  631. package/src/migrations/0056_approval_reason.sql +3 -0
  632. package/src/migrations/0057_conversation_titles.sql +11 -0
  633. package/src/migrations/0058_conversation_selection.sql +4 -0
  634. package/src/migrations/0059_conversation_queue.sql +22 -0
  635. package/src/migrations/0060_file_previewers.sql +10 -0
  636. package/src/migrations/0061_queue_selection.sql +5 -0
  637. package/src/migrations/0062_queued_skill.sql +8 -0
@@ -0,0 +1,535 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readdir, readFile, stat } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { parseBootstrapManifest, SDK_VERSION, } from "@capybara-hq/plugin-sdk";
6
+ import { sql } from "kysely";
7
+ import pg from "pg";
8
+ import semver from "semver";
9
+ import { catalogPackageError } from "../catalog/plugin-import.js";
10
+ import { PluginPackageError, readPluginPackage } from "../catalog/plugin-package.js";
11
+ import { pgConnectOptions } from "../db/pool.js";
12
+ import { ApiError } from "../errors.js";
13
+ import { audit } from "../identity/audit.js";
14
+ import { fetchNpmPackage, IntegrityMismatchError, NpmFetchError, PackageTooLargeError, } from "../packages/npm.js";
15
+ import { writeSnapshot } from "./approvals.js";
16
+ import { ExtensionPackageError, permissionSetOfPackage, readExtensionPackage } from "./package.js";
17
+ import { diffPermissions } from "./permission-set.js";
18
+ /**
19
+ * The bootstrap step (package ecosystem spec §7, startup bootstrap spec): installs the plugins
20
+ * pinned by the bootstrap manifest (`packages/kernel/bootstrap.json`). It replaced the builtin
21
+ * extensions.
22
+ *
23
+ * - When the run is already done for the manifest nothing is read: no directory, no network, so a
24
+ * restart of an installed deployment never needs npm.
25
+ * - Otherwise, inside the lock and before anything is written, every entry's tgz is obtained
26
+ * ({@link resolveBootstrapPackages}): a `*.tgz` file of the optional offline directory whose
27
+ * sha512 equals the entry's `integrity` (the file name does not matter), else the npm download
28
+ * of a `source: "npm"` entry (`packages.npmRegistry` / `npmToken` / `maxBytes`, verified against
29
+ * the pin only). A workspace entry without a matching file is `bootstrap.missing_file`, a failed
30
+ * download `bootstrap.download_failed`, a download that differs from the pin
31
+ * `bootstrap.integrity_mismatch` (all name the plugin), and then nothing is written. Downloading
32
+ * inside the lock means a fleet starting together downloads once.
33
+ * - The whole run holds the session advisory lock `capybara.bootstrap` on a connection of its own
34
+ * (taken with `pg_try_advisory_lock` in a backoff loop that observes the signal, and closed
35
+ * afterwards, so the lock never outlives the run): when several replicas start together only one
36
+ * runs it; the others wait, then find it done. "Done" is a `bootstrap_runs` row for the
37
+ * manifest's sha256 (written with the audit `bootstrap.completed` only when every entry
38
+ * succeeded; otherwise the next start runs it again, which is idempotent). A lock connection
39
+ * that drops mid-run is not detected (its errors are swallowed) and the run goes on without the
40
+ * lock, so a second replica could run concurrently: accepted, since a concurrent import or
41
+ * install degrades to `catalog.version_exists` and a deploy from the package store.
42
+ * - Only entries new to the manifest are installed (Ruling 5): an optional entry that the last
43
+ * completed run already handled and that is not installed now (an enterprise admin uninstalled
44
+ * it) stays uninstalled -> `kept`. A required entry is always installed.
45
+ * - Per entry, by the installed state of its extension:
46
+ * - not installed (and new, or required): imported into the catalog (source `bootstrap`, ref
47
+ * `bootstrap:<name>@<version>`, like a marketplace import), installed, approved (snapshot
48
+ * source `bootstrap`, audited `extension.permissions_approved` with `source: "bootstrap"`)
49
+ * and enabled -> `installed`;
50
+ * - installed from `bootstrap` at a lower version: upgraded the same way (core's release vouched
51
+ * for the version, so new permissions are pre-approved and audited), keeping the desired state
52
+ * an enterprise admin chose (a disabled optional plugin stays disabled) -> `upgraded`;
53
+ * - installed at a higher version, or from another source (an enterprise admin upgraded it), or
54
+ * the name is config-declared (`declared`: config wins, no install record is created):
55
+ * untouched, never downgraded -> `kept`;
56
+ * - a declarative plugin (no extension): imported into the catalog only -> `imported` (`kept`
57
+ * when that version is already there, or when the entry is not new).
58
+ * Every extension entry gets `extension_installs.required` from the manifest, and a required one
59
+ * is enabled on the deployment.
60
+ * - Package bytes are content-addressed: when the very same tgz was ingested before with another
61
+ * source (e.g. imported from a marketplace), its `extension_packages` row keeps that source and
62
+ * so does the install record, which is then not a bootstrap install and never upgraded by a
63
+ * later manifest (`kept`, like a plugin the admin installed).
64
+ * - An install record still `required` whose entry left the manifest is not uninstalled; it only
65
+ * loses `required` -> `required_cleared`.
66
+ * A failed entry does not stop the others; the run then throws {@link BootstrapFailedError} naming
67
+ * them. The packages are kept in PG (`blob_store = 'pg'`), so installing an extension never needs
68
+ * the object store (object-store-s3 is itself a bootstrap plugin) and the directory and npm are
69
+ * never needed again; a declarative plugin's catalog files do need the object store.
70
+ */
71
+ /** The bootstrap manifest that ships with the kernel package. */
72
+ export const BOOTSTRAP_MANIFEST_FILE = fileURLToPath(new URL("../../bootstrap.json", import.meta.url));
73
+ /** Some entries failed (the others were done); the run is not recorded as done. */
74
+ export class BootstrapFailedError extends Error {
75
+ failures;
76
+ results;
77
+ /**
78
+ * @param results what the entries that did not fail did (pass them as `carry` to a later run in
79
+ * the same start, so its record keeps `installed` instead of `kept`).
80
+ */
81
+ constructor(failures, results = []) {
82
+ super(`bootstrap failed for ${failures.map((f) => `${f.name}${f.required ? " (required)" : ""}: ${f.message}`).join("; ")}`);
83
+ this.failures = failures;
84
+ this.results = results;
85
+ this.name = "BootstrapFailedError";
86
+ }
87
+ /** A required entry failed: the kernel must not serve without it. */
88
+ get requiredFailed() {
89
+ return this.failures.some((f) => f.required);
90
+ }
91
+ }
92
+ /** sha256 (hex) of a manifest: of its JSON text as parsed (key order kept). */
93
+ export function bootstrapManifestSha256(manifest) {
94
+ return createHash("sha256").update(JSON.stringify(manifest)).digest("hex");
95
+ }
96
+ /** Reads and parses a bootstrap manifest file; an invalid one throws with its problems. */
97
+ export async function readBootstrapManifest(file = BOOTSTRAP_MANIFEST_FILE) {
98
+ const parsed = parseBootstrapManifest(JSON.parse(await readFile(file, "utf8")));
99
+ if ("errors" in parsed) {
100
+ throw new Error(`invalid bootstrap manifest ${file}: ${parsed.errors.join("; ")}`);
101
+ }
102
+ return parsed;
103
+ }
104
+ const integrityOf = (bytes) => `sha512-${createHash("sha512").update(bytes).digest("base64")}`;
105
+ /**
106
+ * Obtains every entry's tgz, checked against its pinned sha512: from the offline directory when a
107
+ * file there has that sha512, else (a `source: "npm"` entry) downloaded from the npm registry and
108
+ * verified against the pin (the packument's `dist.integrity` is not consulted). Throws an
109
+ * {@link ApiError} naming the plugin for the first entry it cannot obtain
110
+ * (`bootstrap.missing_file`, `bootstrap.download_failed`, `bootstrap.integrity_mismatch`).
111
+ */
112
+ export async function resolveBootstrapPackages(manifest, o) {
113
+ const out = new Map();
114
+ if (manifest.plugins.length === 0)
115
+ return out;
116
+ const { npmRegistry, npmToken, maxBytes } = o.config.packages;
117
+ const offline = o.dir !== undefined ? await scanOfflineDir(o.dir, maxBytes, o.log) : new Map();
118
+ const fetchPackage = o.fetch ?? fetchNpmPackage;
119
+ const signal = o.signal ?? new AbortController().signal;
120
+ const where = o.dir !== undefined ? o.dir : "the bootstrap directory (config bootstrap.dir)";
121
+ for (const e of manifest.plugins) {
122
+ signal.throwIfAborted();
123
+ const found = offline.get(e.integrity);
124
+ if (found !== undefined) {
125
+ out.set(e.name, found);
126
+ continue;
127
+ }
128
+ if (e.source === "workspace") {
129
+ 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`);
130
+ }
131
+ const registry = registryOrigin(npmRegistry);
132
+ const offlineHint = `to install offline, put the package tgz (npm pack ${e.npm}@${e.version}, any file name) in ${where}`;
133
+ try {
134
+ const r = await fetchPackage({ registry: npmRegistry, ...(npmToken !== undefined && { token: npmToken }), maxBytes }, e.npm, e.version, signal, { expectedIntegrity: e.integrity });
135
+ out.set(e.name, r.bytes);
136
+ }
137
+ catch (err) {
138
+ if (signal.aborted)
139
+ throw err;
140
+ if (err instanceof IntegrityMismatchError) {
141
+ 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`);
142
+ }
143
+ const reason = err instanceof NpmFetchError || err instanceof PackageTooLargeError
144
+ ? err.message
145
+ : err instanceof Error
146
+ ? err.message
147
+ : String(err);
148
+ 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`);
149
+ }
150
+ }
151
+ return out;
152
+ }
153
+ /** The registry's origin, for messages (never its credentials or path). */
154
+ function registryOrigin(registry) {
155
+ try {
156
+ return new URL(registry).origin;
157
+ }
158
+ catch {
159
+ return "the configured npm registry";
160
+ }
161
+ }
162
+ /**
163
+ * The `*.tgz` files directly in `dir` by their sha512 integrity. A missing directory is an empty
164
+ * one; a file larger than `maxBytes` is skipped with a warning.
165
+ */
166
+ async function scanOfflineDir(dir, maxBytes, log) {
167
+ const out = new Map();
168
+ let names;
169
+ try {
170
+ names = await readdir(dir);
171
+ }
172
+ catch (err) {
173
+ const code = err.code;
174
+ if (code === "ENOENT" || code === "ENOTDIR")
175
+ return out;
176
+ throw err;
177
+ }
178
+ for (const name of names.sort()) {
179
+ if (!name.endsWith(".tgz"))
180
+ continue;
181
+ const file = join(dir, name);
182
+ const st = await stat(file).catch(() => undefined);
183
+ if (!st?.isFile())
184
+ continue;
185
+ if (st.size > maxBytes) {
186
+ log?.warn("bootstrap: a file in the bootstrap directory exceeds packages.maxBytes; skipped", {
187
+ file,
188
+ size: st.size,
189
+ maxBytes,
190
+ });
191
+ continue;
192
+ }
193
+ const bytes = new Uint8Array(await readFile(file));
194
+ const integrity = integrityOf(bytes);
195
+ if (!out.has(integrity))
196
+ out.set(integrity, bytes);
197
+ }
198
+ return out;
199
+ }
200
+ /** The advisory lock around a whole run. */
201
+ const LOCK_KEY = "capybara.bootstrap";
202
+ export class BootstrapService {
203
+ d;
204
+ constructor(d) {
205
+ this.d = d;
206
+ }
207
+ /** Whether the bootstrap step completed for the manifest with this sha256. */
208
+ async isDone(manifestSha256) {
209
+ const row = await this.d.db
210
+ .selectFrom("bootstrap_runs")
211
+ .select("manifest_sha256")
212
+ .where("manifest_sha256", "=", manifestSha256)
213
+ .executeTakeFirst();
214
+ return row !== undefined;
215
+ }
216
+ /**
217
+ * Runs the bootstrap step (see the file header); when it is already done for this manifest
218
+ * (also when another replica finished it while this one waited for the lock) returns the
219
+ * recorded result without doing anything. `carry`: the results of an earlier, failed run in the
220
+ * same start ({@link BootstrapFailedError.results}); an entry it installed, upgraded or imported
221
+ * keeps that action instead of `kept` in this run's record.
222
+ */
223
+ async run(o) {
224
+ const manifestSha256 = bootstrapManifestSha256(o.manifest);
225
+ const recorded = async () => {
226
+ const done = await this.d.db
227
+ .selectFrom("bootstrap_runs")
228
+ .select("results")
229
+ .where("manifest_sha256", "=", manifestSha256)
230
+ .executeTakeFirst();
231
+ return done && { manifestSha256, results: done.results };
232
+ };
233
+ // Done: no lock, no directory, no network
234
+ const before = await recorded();
235
+ if (before)
236
+ return before;
237
+ return this.locked(o.signal, async () => {
238
+ // Another replica may have finished it while this one waited for the lock
239
+ const done = await recorded();
240
+ if (done)
241
+ return done;
242
+ // Every package is obtained and checked before the first write
243
+ const files = await resolveBootstrapPackages(o.manifest, {
244
+ ...(o.dir !== undefined && { dir: o.dir }),
245
+ config: this.d.config(),
246
+ ...(o.signal !== undefined && { signal: o.signal }),
247
+ log: this.d.log,
248
+ });
249
+ const handled = await this.lastRunNames();
250
+ const results = [];
251
+ const failures = [];
252
+ for (const e of o.manifest.plugins) {
253
+ o.signal?.throwIfAborted();
254
+ try {
255
+ const r = await this.entry(e, files.get(e.name), handled);
256
+ results.push(carried(r, o.carry));
257
+ }
258
+ catch (err) {
259
+ this.d.log.error("bootstrap: a plugin could not be installed", {
260
+ plugin: e.name,
261
+ version: e.version,
262
+ required: e.required,
263
+ err,
264
+ });
265
+ failures.push({
266
+ name: e.name,
267
+ required: e.required,
268
+ code: err instanceof ApiError ? err.code : "internal",
269
+ message: err instanceof Error ? err.message : String(err),
270
+ });
271
+ }
272
+ }
273
+ results.push(...(await this.clearRemoved(o.manifest)));
274
+ if (failures.length > 0)
275
+ throw new BootstrapFailedError(failures, results);
276
+ await this.d.db.transaction().execute(async (trx) => {
277
+ await trx
278
+ .insertInto("bootstrap_runs")
279
+ .values({
280
+ manifest_sha256: manifestSha256,
281
+ completed_at: sql `now()`,
282
+ results: JSON.stringify(results),
283
+ })
284
+ .execute();
285
+ await audit(trx, {
286
+ action: "bootstrap.completed",
287
+ target: manifestSha256,
288
+ detail: { manifestSha256, results },
289
+ });
290
+ });
291
+ this.d.log.info("bootstrap completed", { manifestSha256, results });
292
+ return { manifestSha256, results };
293
+ });
294
+ }
295
+ /**
296
+ * Runs `fn` holding the session advisory lock on a connection of its own: `pg_try_advisory_lock`
297
+ * retried with a backoff (100 ms doubling to 1 s) that stops when `signal` aborts. The connection
298
+ * is closed afterwards in every case, which releases the lock even when the unlock failed.
299
+ */
300
+ async locked(signal, fn) {
301
+ const client = new pg.Client({
302
+ connectionString: this.d.dbUrl,
303
+ ...pgConnectOptions({ connectTimeoutMs: this.d.connectTimeoutMs }),
304
+ });
305
+ client.on("error", () => { });
306
+ try {
307
+ await client.connect();
308
+ for (let wait = 100;; wait = Math.min(wait * 2, 1_000)) {
309
+ signal?.throwIfAborted();
310
+ const r = await client.query("SELECT pg_try_advisory_lock(hashtext($1)) AS ok", [LOCK_KEY]);
311
+ if (r.rows[0]?.ok === true)
312
+ break;
313
+ await sleep(wait, signal);
314
+ }
315
+ try {
316
+ return await fn();
317
+ }
318
+ finally {
319
+ await client
320
+ .query("SELECT pg_advisory_unlock(hashtext($1))", [LOCK_KEY])
321
+ .catch((err) => this.d.log.warn("bootstrap: cannot release the advisory lock; closing its connection", {
322
+ err,
323
+ }));
324
+ }
325
+ }
326
+ finally {
327
+ await client.end().catch(() => { });
328
+ }
329
+ }
330
+ /** The entry names the last completed run handled (undefined before any run completed). */
331
+ async lastRunNames() {
332
+ const row = await this.d.db
333
+ .selectFrom("bootstrap_runs")
334
+ .select("results")
335
+ .orderBy("completed_at", "desc")
336
+ .limit(1)
337
+ .executeTakeFirst();
338
+ if (!row)
339
+ return undefined;
340
+ return new Set(row.results
341
+ .filter((r) => r.action !== "required_cleared")
342
+ .map((r) => r.name));
343
+ }
344
+ async entry(e, bytes, handled) {
345
+ const pkg = await readPluginPackage(bytes, {
346
+ maxBytes: this.d.config().packages.maxBytes,
347
+ hostSdkVersion: SDK_VERSION,
348
+ }).catch((err) => {
349
+ throw err instanceof PluginPackageError ? catalogPackageError(err) : err;
350
+ });
351
+ if (pkg.manifest.name !== e.name || pkg.manifest.version !== e.version) {
352
+ throw new ApiError("catalog.invalid_manifest", `The package for bootstrap entry ${e.name} ${e.version} contains plugin ${pkg.manifest.name} ${pkg.manifest.version}`);
353
+ }
354
+ const ref = `bootstrap:${e.name}@${e.version}`;
355
+ // Not new to the manifest: an optional entry left out on purpose stays out (Ruling 5)
356
+ const isNew = handled === undefined || !handled.has(e.name);
357
+ if (!pkg.manifest.extension) {
358
+ if (!isNew)
359
+ return { name: e.name, action: "kept", version: e.version };
360
+ const imported = await this.importOnly(e, bytes, ref);
361
+ return { name: e.name, action: imported ? "imported" : "kept", version: e.version };
362
+ }
363
+ if (this.d.declared?.().has(e.name)) {
364
+ this.d.log.warn("bootstrap: the plugin is declared in the extensions config list; the config plugin is used", { plugin: e.name });
365
+ return { name: e.name, action: "kept", version: e.version };
366
+ }
367
+ const row = await this.d.db
368
+ .selectFrom("extension_installs")
369
+ .select(["version", "source", "required", "desired_state", "sha256"])
370
+ .where("name", "=", e.name)
371
+ .executeTakeFirst();
372
+ if (!row && !isNew && !e.required) {
373
+ this.d.log.info("bootstrap: an optional plugin that is not installed stays uninstalled", {
374
+ plugin: e.name,
375
+ });
376
+ return { name: e.name, action: "kept", version: e.version };
377
+ }
378
+ let result;
379
+ if (!row) {
380
+ await this.deploy(e, bytes, ref, true);
381
+ result = { name: e.name, action: "installed", version: e.version };
382
+ }
383
+ else if (row.source === "bootstrap" && isLower(row.version, e.version)) {
384
+ // The desired state the admin chose is kept; a required plugin is enabled below anyway
385
+ await this.deploy(e, bytes, ref, row.desired_state === "enabled");
386
+ result = { name: e.name, action: "upgraded", version: e.version };
387
+ }
388
+ else {
389
+ if (row.source === "bootstrap" &&
390
+ row.version === e.version &&
391
+ row.sha256 !== createHash("sha256").update(bytes).digest("hex")) {
392
+ // The pin changed bytes without a version bump (an image built from main between
393
+ // releases): the installed package stays, so say so instead of keeping it silently
394
+ 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 });
395
+ }
396
+ result = { name: e.name, action: "kept", version: row.version };
397
+ }
398
+ if (row?.required !== e.required) {
399
+ await this.d.db
400
+ .updateTable("extension_installs")
401
+ .set({ required: e.required })
402
+ .where("name", "=", e.name)
403
+ .execute();
404
+ }
405
+ // A required install must run on the deployment (an org cannot use it otherwise)
406
+ if (e.required && row?.desired_state === "disabled") {
407
+ await this.d.ops.enable(e.name, null);
408
+ }
409
+ return result;
410
+ }
411
+ /** A declarative plugin: catalog only. Returns false when that version is already imported. */
412
+ async importOnly(e, bytes, ref) {
413
+ try {
414
+ const { stagingId, review } = await this.d.imports.prepare(null, bytes, {
415
+ kind: "bootstrap",
416
+ ref,
417
+ integrity: e.integrity,
418
+ });
419
+ await this.d.imports.confirm(null, stagingId, {
420
+ reviewHash: review.reviewHash,
421
+ deployExtension: false,
422
+ });
423
+ return true;
424
+ }
425
+ catch (err) {
426
+ if (err instanceof ApiError && err.code === "catalog.version_exists")
427
+ return false;
428
+ throw err;
429
+ }
430
+ }
431
+ /**
432
+ * Imports, approves, installs and enables (one review, confirmed with `deployExtension`). When
433
+ * the catalog already has this version (an earlier run stopped after importing, or the same
434
+ * package came from a marketplace), the extension is deployed from the package store instead.
435
+ */
436
+ async deploy(e, bytes, ref, enable) {
437
+ let staged;
438
+ try {
439
+ staged = await this.d.imports.prepare(null, bytes, {
440
+ kind: "bootstrap",
441
+ ref,
442
+ integrity: e.integrity,
443
+ });
444
+ }
445
+ catch (err) {
446
+ if (err instanceof ApiError && err.code === "catalog.version_exists") {
447
+ await this.deployFromStore(e, bytes, ref, enable);
448
+ return;
449
+ }
450
+ throw err;
451
+ }
452
+ const r = await this.d.imports.confirm(null, staged.stagingId, {
453
+ reviewHash: staged.review.reviewHash,
454
+ deployExtension: true,
455
+ enable,
456
+ });
457
+ if (r.deploy?.result === "failed") {
458
+ throw new ApiError((r.deploy.code ?? "internal"), r.deploy.message ?? `installing extension ${e.name} failed`);
459
+ }
460
+ }
461
+ /** The extension of a catalog version already imported: ingest, approve, install (, enable). */
462
+ async deployFromStore(e, bytes, ref, enable) {
463
+ const review = await this.d.installs.ingest(null, bytes, { source: "bootstrap", ref }, { store: "pg" });
464
+ let set;
465
+ try {
466
+ set = permissionSetOfPackage(await readExtensionPackage(bytes, {
467
+ maxBytes: this.d.config().packages.maxBytes,
468
+ hostSdkVersion: SDK_VERSION,
469
+ }));
470
+ }
471
+ catch (err) {
472
+ throw err instanceof ExtensionPackageError ? catalogPackageError(err) : err;
473
+ }
474
+ await this.d.db.transaction().execute(async (trx) => {
475
+ await sql `SELECT pg_advisory_xact_lock(hashtext(${`capybara.plugin-approve:${e.name}`}))`.execute(trx);
476
+ const snap = await trx
477
+ .selectFrom("extension_permission_snapshots")
478
+ .select("permissions")
479
+ .where("plugin", "=", e.name)
480
+ .forUpdate()
481
+ .executeTakeFirst();
482
+ const { added, removed } = diffPermissions(snap?.permissions, set);
483
+ await writeSnapshot(trx, e.name, e.version, set, {
484
+ source: "bootstrap",
485
+ audit: { added, removed, sha256: review.sha256 },
486
+ });
487
+ });
488
+ const item = await this.d.db
489
+ .selectFrom("catalog_items")
490
+ .select("id")
491
+ .where("name", "=", e.name)
492
+ .where("deleted_at", "is", null)
493
+ .executeTakeFirst();
494
+ await this.d.ops.install(e.name, review.sha256, null, undefined, item ? { catalogItemId: item.id } : {});
495
+ if (enable)
496
+ await this.d.ops.enable(e.name, null);
497
+ }
498
+ /** Install records still `required` whose entry left the manifest lose `required`. */
499
+ async clearRemoved(manifest) {
500
+ const names = manifest.plugins.map((p) => p.name);
501
+ let q = this.d.db
502
+ .updateTable("extension_installs")
503
+ .set({ required: false })
504
+ .where("required", "=", true);
505
+ if (names.length > 0)
506
+ q = q.where("name", "not in", names);
507
+ const rows = await q.returning(["name", "version"]).execute();
508
+ return rows.map((r) => ({ name: r.name, action: "required_cleared", version: r.version }));
509
+ }
510
+ }
511
+ /** A `kept` result whose entry an earlier pass of the same start installed / upgraded / imported. */
512
+ function carried(r, carry) {
513
+ if (r.action !== "kept")
514
+ return r;
515
+ const before = carry?.find((c) => c.name === r.name && c.version === r.version);
516
+ return before !== undefined && before.action !== "kept" && before.action !== "required_cleared"
517
+ ? before
518
+ : r;
519
+ }
520
+ /** Resolves after `ms`; rejects with the abort reason when `signal` aborts first. */
521
+ function sleep(ms, signal) {
522
+ return new Promise((resolve, reject) => {
523
+ const onAbort = () => {
524
+ clearTimeout(timer);
525
+ reject(signal?.reason);
526
+ };
527
+ const timer = setTimeout(() => {
528
+ signal?.removeEventListener("abort", onAbort);
529
+ resolve();
530
+ }, ms);
531
+ signal?.addEventListener("abort", onAbort, { once: true });
532
+ });
533
+ }
534
+ /** `installed` is below `pinned` (a version that is not semver is never upgraded). */
535
+ const isLower = (installed, pinned) => semver.valid(installed) !== null && semver.valid(pinned) !== null && semver.lt(installed, pinned);
@@ -0,0 +1,61 @@
1
+ import type { z } from "zod";
2
+ import type { KernelConfig } from "../config/schema.js";
3
+ import { type KernelDb } from "../db/kernel-schema.js";
4
+ import type { KernelLogger } from "../log.js";
5
+ import { ExtensionAdminOps } from "./admin-ops.js";
6
+ import { ExtensionAdmin } from "./admin-view.js";
7
+ import { ExtensionApprovals } from "./approvals.js";
8
+ import { type ConfigIssue } from "./deployment-config.js";
9
+ import { type InspectedExtension } from "./host.js";
10
+ import { ExtensionInstalls } from "./installs.js";
11
+ import type { PermissionSet } from "./permission-set.js";
12
+ /** {@link openExtensionCli} 的结果:CLI 的 `capybara extensions *` 共用。 */
13
+ export interface ExtensionCli {
14
+ config: KernelConfig;
15
+ db: KernelDb;
16
+ /** 配置声明的插件(导入、按依赖排序,不 setup)。 */
17
+ inspected: InspectedExtension[];
18
+ /**
19
+ * 配置声明插件的部署配置问题(启动配置与 PG 里保存的合并后按 schema 校验;只有路径与说明,不含值):
20
+ * 有问题的插件内核不加载(待配置)。没有问题的不在这里。
21
+ */
22
+ configIssues: ReadonlyMap<string, ConfigIssue[]>;
23
+ /** The valid merged deployment config (secrets decrypted) of the declared extensions that have one. */
24
+ deploymentConfigs: ReadonlyMap<string, unknown>;
25
+ /**
26
+ * The deployment config of any extension (an install record too) validated against `schema`: the
27
+ * startup config completed by the fields stored in PG, as the kernel merges it. No schema = `{}`.
28
+ */
29
+ deploymentConfigOf(name: string, schema: z.ZodTypeAny | undefined): Promise<{
30
+ ok: true;
31
+ value: unknown;
32
+ } | {
33
+ ok: false;
34
+ issues: ConfigIssue[];
35
+ }>;
36
+ installs: ExtensionInstalls;
37
+ admin: ExtensionAdmin;
38
+ ops: ExtensionAdminOps;
39
+ approvals: ExtensionApprovals;
40
+ /** CLI 本次刚导入的包字节(降级判断等读包时优先用它:包可能存在 CLI 读不到的对象存储里)。 */
41
+ remember(sha256: string, bytes: Uint8Array): void;
42
+ /** 安装记录包的权限集合(与后台审阅相同);包在对象存储里时 CLI 读不到,抛错。 */
43
+ packageSet(sha256: string): Promise<PermissionSet>;
44
+ /** The bytes of a stored package (this process's imports first, then the package store in PG). */
45
+ readPackage(sha256: string): Promise<Uint8Array>;
46
+ /** 写完 PG 后经 Redis 发布 `kernel.plugins.changed`(C18);失败只告警,返回是否发布成功。 */
47
+ publishChanged(plugin: string): Promise<boolean>;
48
+ close(): Promise<void>;
49
+ }
50
+ /**
51
+ * The CLI's extension management context (C18, F-Q): connects only to PG (and Redis for publishing),
52
+ * starts no extension host and runs no extension's `setup` (a catalog import sets up the declared
53
+ * object-store extension itself, see `openCatalogCli`). Packages the CLI imports are always
54
+ * stored in PG (`blob_store = 'pg'`); replicas read by `blob_store`. Install / enable / disable /
55
+ * uninstall share {@link ExtensionAdminOps} with the admin console (actor null, audits without an
56
+ * actor); after writing PG it publishes `kernel.plugins.changed` and running replicas reconcile; a
57
+ * failed publish only warns (the periodic reconcile catches up).
58
+ */
59
+ export declare function openExtensionCli(config: KernelConfig, log: KernelLogger, opts?: {
60
+ resolveFrom?: string;
61
+ }): Promise<ExtensionCli>;