@bevel-software/platform-core-backend 0.20.0 → 0.22.0

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 (666) hide show
  1. package/dist/core/catalog-cache-invalidation.d.ts +7 -2
  2. package/dist/core/catalog-cache-invalidation.d.ts.map +1 -1
  3. package/dist/core/catalog-cache-invalidation.js +8 -9
  4. package/dist/core/catalog-cache-invalidation.js.map +1 -1
  5. package/dist/core/core-ports.d.ts +19 -0
  6. package/dist/core/core-ports.d.ts.map +1 -1
  7. package/dist/core/core-ports.js.map +1 -1
  8. package/dist/core/create-core-server.d.ts +2 -0
  9. package/dist/core/create-core-server.d.ts.map +1 -1
  10. package/dist/core/create-core-server.js +55 -107
  11. package/dist/core/create-core-server.js.map +1 -1
  12. package/dist/core/create-core-services.d.ts +41 -4
  13. package/dist/core/create-core-services.d.ts.map +1 -1
  14. package/dist/core/create-core-services.js +183 -82
  15. package/dist/core/create-core-services.js.map +1 -1
  16. package/dist/core/lifecycle.d.ts +74 -28
  17. package/dist/core/lifecycle.d.ts.map +1 -1
  18. package/dist/core/lifecycle.js +157 -20
  19. package/dist/core/lifecycle.js.map +1 -1
  20. package/dist/core/public-config.d.ts +5 -1
  21. package/dist/core/public-config.d.ts.map +1 -1
  22. package/dist/core/public-config.js +7 -5
  23. package/dist/core/public-config.js.map +1 -1
  24. package/dist/core-config.d.ts +95 -1
  25. package/dist/core-config.d.ts.map +1 -1
  26. package/dist/core-config.js +24 -8
  27. package/dist/core-config.js.map +1 -1
  28. package/dist/index.d.ts +5 -3
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +6 -3
  31. package/dist/index.js.map +1 -1
  32. package/dist/modules/access/access-control.service.d.ts +18 -1
  33. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  34. package/dist/modules/access/access-control.service.js +19 -8
  35. package/dist/modules/access/access-control.service.js.map +1 -1
  36. package/dist/modules/access/access-requests.contract.d.ts +75 -0
  37. package/dist/modules/access/access-requests.contract.d.ts.map +1 -0
  38. package/dist/modules/access/access-requests.contract.js +20 -0
  39. package/dist/modules/access/access-requests.contract.js.map +1 -0
  40. package/dist/modules/access/access-requests.routes.d.ts +35 -0
  41. package/dist/modules/access/access-requests.routes.d.ts.map +1 -0
  42. package/dist/modules/access/access-requests.routes.js +237 -0
  43. package/dist/modules/access/access-requests.routes.js.map +1 -0
  44. package/dist/modules/access/access-requests.service.d.ts +123 -0
  45. package/dist/modules/access/access-requests.service.d.ts.map +1 -0
  46. package/dist/modules/access/access-requests.service.js +337 -0
  47. package/dist/modules/access/access-requests.service.js.map +1 -0
  48. package/dist/modules/access/access.routes.d.ts +2 -1
  49. package/dist/modules/access/access.routes.d.ts.map +1 -1
  50. package/dist/modules/access/access.routes.js +10 -10
  51. package/dist/modules/access/access.routes.js.map +1 -1
  52. package/dist/modules/access/change-read-gate.d.ts +6 -3
  53. package/dist/modules/access/change-read-gate.d.ts.map +1 -1
  54. package/dist/modules/access/change-read-gate.js +9 -6
  55. package/dist/modules/access/change-read-gate.js.map +1 -1
  56. package/dist/modules/access/creator-access.d.ts +4 -2
  57. package/dist/modules/access/creator-access.d.ts.map +1 -1
  58. package/dist/modules/access/creator-access.js +7 -4
  59. package/dist/modules/access/creator-access.js.map +1 -1
  60. package/dist/modules/access-model/access-grammar.d.ts +12 -0
  61. package/dist/modules/access-model/access-grammar.d.ts.map +1 -1
  62. package/dist/modules/access-model/access-grammar.js +24 -0
  63. package/dist/modules/access-model/access-grammar.js.map +1 -1
  64. package/dist/modules/agent-instructions/read-preamble.d.ts +2 -1
  65. package/dist/modules/agent-instructions/read-preamble.d.ts.map +1 -1
  66. package/dist/modules/agent-instructions/read-preamble.js +6 -9
  67. package/dist/modules/agent-instructions/read-preamble.js.map +1 -1
  68. package/dist/modules/auth/account-admission.d.ts +40 -0
  69. package/dist/modules/auth/account-admission.d.ts.map +1 -0
  70. package/dist/modules/auth/account-admission.js +17 -0
  71. package/dist/modules/auth/account-admission.js.map +1 -0
  72. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  73. package/dist/modules/auth/account.routes.js +4 -1
  74. package/dist/modules/auth/account.routes.js.map +1 -1
  75. package/dist/modules/auth/auth.service.d.ts +45 -2
  76. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  77. package/dist/modules/auth/auth.service.js +44 -3
  78. package/dist/modules/auth/auth.service.js.map +1 -1
  79. package/dist/modules/auth/oidc-auth-provider.d.ts.map +1 -1
  80. package/dist/modules/auth/oidc-auth-provider.js +9 -0
  81. package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
  82. package/dist/modules/connection-probe/connection-probe.service.d.ts +13 -1
  83. package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
  84. package/dist/modules/connection-probe/connection-probe.service.js +10 -2
  85. package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
  86. package/dist/modules/database/advisory-lock.d.ts +17 -0
  87. package/dist/modules/database/advisory-lock.d.ts.map +1 -1
  88. package/dist/modules/database/advisory-lock.js +24 -3
  89. package/dist/modules/database/advisory-lock.js.map +1 -1
  90. package/dist/modules/database/connection.d.ts +67 -2
  91. package/dist/modules/database/connection.d.ts.map +1 -1
  92. package/dist/modules/database/connection.js +118 -12
  93. package/dist/modules/database/connection.js.map +1 -1
  94. package/dist/modules/database/migrate.d.ts +1 -1
  95. package/dist/modules/database/migrate.d.ts.map +1 -1
  96. package/dist/modules/database/migrate.js +27 -3
  97. package/dist/modules/database/migrate.js.map +1 -1
  98. package/dist/modules/github-app/github-app.client.d.ts +101 -0
  99. package/dist/modules/github-app/github-app.client.d.ts.map +1 -0
  100. package/dist/modules/github-app/github-app.client.js +222 -0
  101. package/dist/modules/github-app/github-app.client.js.map +1 -0
  102. package/dist/modules/github-app/github-app.connection.d.ts +102 -0
  103. package/dist/modules/github-app/github-app.connection.d.ts.map +1 -0
  104. package/dist/modules/github-app/github-app.connection.js +185 -0
  105. package/dist/modules/github-app/github-app.connection.js.map +1 -0
  106. package/dist/modules/github-app/github-app.routes.d.ts +59 -0
  107. package/dist/modules/github-app/github-app.routes.d.ts.map +1 -0
  108. package/dist/modules/github-app/github-app.routes.js +323 -0
  109. package/dist/modules/github-app/github-app.routes.js.map +1 -0
  110. package/dist/modules/github-app/index.d.ts +4 -0
  111. package/dist/modules/github-app/index.d.ts.map +1 -0
  112. package/dist/modules/github-app/index.js +4 -0
  113. package/dist/modules/github-app/index.js.map +1 -0
  114. package/dist/modules/kb-fs/branch-name.d.ts +0 -1
  115. package/dist/modules/kb-fs/branch-name.d.ts.map +1 -1
  116. package/dist/modules/kb-fs/branch-name.js +3 -3
  117. package/dist/modules/kb-fs/branch-name.js.map +1 -1
  118. package/dist/modules/kb-fs/clone-config.d.ts +9 -8
  119. package/dist/modules/kb-fs/clone-config.d.ts.map +1 -1
  120. package/dist/modules/kb-fs/clone-config.js +14 -12
  121. package/dist/modules/kb-fs/clone-config.js.map +1 -1
  122. package/dist/modules/kb-fs/remote-url.d.ts +22 -0
  123. package/dist/modules/kb-fs/remote-url.d.ts.map +1 -0
  124. package/dist/modules/kb-fs/remote-url.js +35 -0
  125. package/dist/modules/kb-fs/remote-url.js.map +1 -0
  126. package/dist/modules/mcp/mcp.service.d.ts +7 -0
  127. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  128. package/dist/modules/mcp/mcp.service.js +4 -4
  129. package/dist/modules/mcp/mcp.service.js.map +1 -1
  130. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts +4 -4
  131. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts.map +1 -1
  132. package/dist/modules/plugins/compile/marketplace-compiler.service.js +7 -10
  133. package/dist/modules/plugins/compile/marketplace-compiler.service.js.map +1 -1
  134. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts +4 -1
  135. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts.map +1 -1
  136. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js +5 -3
  137. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js.map +1 -1
  138. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts +6 -1
  139. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts.map +1 -1
  140. package/dist/modules/plugins/discovery/kb-plugin-source.js +14 -9
  141. package/dist/modules/plugins/discovery/kb-plugin-source.js.map +1 -1
  142. package/dist/modules/plugins/discovery/native.source.d.ts +4 -1
  143. package/dist/modules/plugins/discovery/native.source.d.ts.map +1 -1
  144. package/dist/modules/plugins/discovery/native.source.js +4 -2
  145. package/dist/modules/plugins/discovery/native.source.js.map +1 -1
  146. package/dist/modules/plugins/index.d.ts +1 -1
  147. package/dist/modules/plugins/index.d.ts.map +1 -1
  148. package/dist/modules/plugins/index.js +1 -1
  149. package/dist/modules/plugins/index.js.map +1 -1
  150. package/dist/modules/plugins/join-proposals.d.ts +17 -5
  151. package/dist/modules/plugins/join-proposals.d.ts.map +1 -1
  152. package/dist/modules/plugins/join-proposals.js +76 -22
  153. package/dist/modules/plugins/join-proposals.js.map +1 -1
  154. package/dist/modules/plugins/join-request-jobs.service.d.ts +3 -1
  155. package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -1
  156. package/dist/modules/plugins/join-request-jobs.service.js +6 -6
  157. package/dist/modules/plugins/join-request-jobs.service.js.map +1 -1
  158. package/dist/modules/plugins/join-requests.service.d.ts +113 -18
  159. package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
  160. package/dist/modules/plugins/join-requests.service.js +178 -33
  161. package/dist/modules/plugins/join-requests.service.js.map +1 -1
  162. package/dist/modules/plugins/plugin-links.d.ts +65 -10
  163. package/dist/modules/plugins/plugin-links.d.ts.map +1 -1
  164. package/dist/modules/plugins/plugin-links.js +136 -31
  165. package/dist/modules/plugins/plugin-links.js.map +1 -1
  166. package/dist/modules/plugins/plugin-links.service.d.ts +107 -5
  167. package/dist/modules/plugins/plugin-links.service.d.ts.map +1 -1
  168. package/dist/modules/plugins/plugin-links.service.js +151 -21
  169. package/dist/modules/plugins/plugin-links.service.js.map +1 -1
  170. package/dist/modules/plugins/plugin-provision.service.d.ts +10 -3
  171. package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
  172. package/dist/modules/plugins/plugin-provision.service.js +33 -26
  173. package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
  174. package/dist/modules/plugins/plugin-rename.service.d.ts +4 -2
  175. package/dist/modules/plugins/plugin-rename.service.d.ts.map +1 -1
  176. package/dist/modules/plugins/plugin-rename.service.js +10 -12
  177. package/dist/modules/plugins/plugin-rename.service.js.map +1 -1
  178. package/dist/modules/plugins/plugins.routes.d.ts +3 -0
  179. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  180. package/dist/modules/plugins/plugins.routes.js +48 -17
  181. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  182. package/dist/modules/plugins/plugins.service.d.ts +4 -4
  183. package/dist/modules/plugins/plugins.service.d.ts.map +1 -1
  184. package/dist/modules/plugins/plugins.service.js +7 -10
  185. package/dist/modules/plugins/plugins.service.js.map +1 -1
  186. package/dist/modules/plugins/teams.routes.d.ts +4 -1
  187. package/dist/modules/plugins/teams.routes.d.ts.map +1 -1
  188. package/dist/modules/plugins/teams.routes.js +11 -9
  189. package/dist/modules/plugins/teams.routes.js.map +1 -1
  190. package/dist/modules/secrets-vault/index.d.ts +1 -1
  191. package/dist/modules/secrets-vault/index.d.ts.map +1 -1
  192. package/dist/modules/secrets-vault/index.js +1 -1
  193. package/dist/modules/secrets-vault/index.js.map +1 -1
  194. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts +29 -11
  195. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts.map +1 -1
  196. package/dist/modules/secrets-vault/secrets-variable-loader.js +46 -21
  197. package/dist/modules/secrets-vault/secrets-variable-loader.js.map +1 -1
  198. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +3 -0
  199. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  200. package/dist/modules/secrets-vault/secrets-vault.routes.js +4 -6
  201. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  202. package/dist/modules/settings/deployment-settings.service.d.ts +34 -9
  203. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  204. package/dist/modules/settings/deployment-settings.service.js +113 -26
  205. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  206. package/dist/modules/settings/managed-repository.d.ts +43 -0
  207. package/dist/modules/settings/managed-repository.d.ts.map +1 -0
  208. package/dist/modules/settings/managed-repository.js +60 -0
  209. package/dist/modules/settings/managed-repository.js.map +1 -0
  210. package/dist/modules/settings/repository-source.d.ts +128 -0
  211. package/dist/modules/settings/repository-source.d.ts.map +1 -0
  212. package/dist/modules/settings/repository-source.js +150 -0
  213. package/dist/modules/settings/repository-source.js.map +1 -0
  214. package/dist/modules/settings/setup.routes.d.ts +34 -4
  215. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  216. package/dist/modules/settings/setup.routes.js +198 -18
  217. package/dist/modules/settings/setup.routes.js.map +1 -1
  218. package/dist/modules/skills/allowed-tools-check.d.ts +4 -3
  219. package/dist/modules/skills/allowed-tools-check.d.ts.map +1 -1
  220. package/dist/modules/skills/allowed-tools-check.js +8 -8
  221. package/dist/modules/skills/allowed-tools-check.js.map +1 -1
  222. package/dist/modules/skills/pending-skills.service.d.ts +3 -1
  223. package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
  224. package/dist/modules/skills/pending-skills.service.js +9 -6
  225. package/dist/modules/skills/pending-skills.service.js.map +1 -1
  226. package/dist/modules/skills/skill-access-requests.routes.d.ts +8 -9
  227. package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
  228. package/dist/modules/skills/skill-access-requests.routes.js +26 -65
  229. package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
  230. package/dist/modules/skills/skills.routes.d.ts +4 -1
  231. package/dist/modules/skills/skills.routes.d.ts.map +1 -1
  232. package/dist/modules/skills/skills.routes.js +4 -4
  233. package/dist/modules/skills/skills.routes.js.map +1 -1
  234. package/dist/modules/skills/skills.service.d.ts +4 -2
  235. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  236. package/dist/modules/skills/skills.service.js +13 -11
  237. package/dist/modules/skills/skills.service.js.map +1 -1
  238. package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
  239. package/dist/modules/tool-helpers/tool-context.js +15 -0
  240. package/dist/modules/tool-helpers/tool-context.js.map +1 -1
  241. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +2 -1
  242. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
  243. package/dist/modules/tool-manuals/mcp-json-discovery.js +6 -5
  244. package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
  245. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts +4 -2
  246. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -1
  247. package/dist/modules/tool-manuals/mcp-server-edit.service.js +12 -10
  248. package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -1
  249. package/dist/modules/tool-manuals/pending-tools.service.d.ts +3 -1
  250. package/dist/modules/tool-manuals/pending-tools.service.d.ts.map +1 -1
  251. package/dist/modules/tool-manuals/pending-tools.service.js +19 -16
  252. package/dist/modules/tool-manuals/pending-tools.service.js.map +1 -1
  253. package/dist/modules/tool-manuals/tool-delete.service.d.ts +4 -2
  254. package/dist/modules/tool-manuals/tool-delete.service.d.ts.map +1 -1
  255. package/dist/modules/tool-manuals/tool-delete.service.js +14 -12
  256. package/dist/modules/tool-manuals/tool-delete.service.js.map +1 -1
  257. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +3 -1
  258. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
  259. package/dist/modules/tool-manuals/tool-manuals.routes.js +7 -7
  260. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
  261. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +4 -2
  262. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  263. package/dist/modules/tool-manuals/tool-manuals.service.js +15 -12
  264. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  265. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +3 -0
  266. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  267. package/dist/modules/tool-manuals/tool-manuals.tools.js +4 -6
  268. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  269. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +3 -2
  270. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  271. package/dist/modules/workflow/agent-tools/workflow.tools.js +47 -11
  272. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  273. package/dist/modules/workflow/git/git.service.d.ts +14 -6
  274. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  275. package/dist/modules/workflow/git/git.service.js +40 -18
  276. package/dist/modules/workflow/git/git.service.js.map +1 -1
  277. package/dist/modules/workflow/git/node-git-runner.d.ts +26 -2
  278. package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
  279. package/dist/modules/workflow/git/node-git-runner.js +40 -5
  280. package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
  281. package/dist/modules/workflow/git/pull-request.service.d.ts +45 -0
  282. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
  283. package/dist/modules/workflow/git/pull-request.service.js +99 -0
  284. package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
  285. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
  286. package/dist/modules/workflow/review-workflow/review-workflow.service.js +9 -4
  287. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
  288. package/dist/modules/workflow/session-ontology.service.d.ts +6 -1
  289. package/dist/modules/workflow/session-ontology.service.d.ts.map +1 -1
  290. package/dist/modules/workflow/session-ontology.service.js +6 -2
  291. package/dist/modules/workflow/session-ontology.service.js.map +1 -1
  292. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
  293. package/dist/modules/workflow/workflow.routes.js +3 -1
  294. package/dist/modules/workflow/workflow.routes.js.map +1 -1
  295. package/dist/modules/workflow/workflow.service.d.ts +42 -10
  296. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  297. package/dist/modules/workflow/workflow.service.js +181 -71
  298. package/dist/modules/workflow/workflow.service.js.map +1 -1
  299. package/dist/modules/workspace/session-ontology.gate.d.ts +3 -1
  300. package/dist/modules/workspace/session-ontology.gate.d.ts.map +1 -1
  301. package/dist/modules/workspace/session-ontology.gate.js +3 -3
  302. package/dist/modules/workspace/session-ontology.gate.js.map +1 -1
  303. package/dist/modules/workspace/startup/kb-git.d.ts +4 -3
  304. package/dist/modules/workspace/startup/kb-git.d.ts.map +1 -1
  305. package/dist/modules/workspace/startup/kb-git.js +15 -13
  306. package/dist/modules/workspace/startup/kb-git.js.map +1 -1
  307. package/dist/modules/workspace/startup/kb-startup-runner.d.ts +70 -7
  308. package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
  309. package/dist/modules/workspace/startup/kb-startup-runner.js +183 -38
  310. package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
  311. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts +7 -1
  312. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts.map +1 -1
  313. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js +23 -16
  314. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js.map +1 -1
  315. package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts +7 -1
  316. package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts.map +1 -1
  317. package/dist/modules/workspace/startup/steps/personal-spaces.step.js +12 -5
  318. package/dist/modules/workspace/startup/steps/personal-spaces.step.js.map +1 -1
  319. package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts +7 -1
  320. package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts.map +1 -1
  321. package/dist/modules/workspace/startup/steps/plugin-display-names.step.js +12 -5
  322. package/dist/modules/workspace/startup/steps/plugin-display-names.step.js.map +1 -1
  323. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts +7 -1
  324. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts.map +1 -1
  325. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js +12 -5
  326. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js.map +1 -1
  327. package/dist/modules/workspace/startup/steps/seed-tree.d.ts +4 -1
  328. package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
  329. package/dist/modules/workspace/startup/steps/seed-tree.js +14 -11
  330. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  331. package/dist/modules/workspace/startup/steps/template-files.step.d.ts +17 -3
  332. package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
  333. package/dist/modules/workspace/startup/steps/template-files.step.js +36 -30
  334. package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
  335. package/dist/modules/workspace/startup/steps/template-source.d.ts +6 -1
  336. package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -1
  337. package/dist/modules/workspace/startup/steps/template-source.js +10 -6
  338. package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
  339. package/dist/modules/workspace/workspace.routes.d.ts +2 -1
  340. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  341. package/dist/modules/workspace/workspace.routes.js +8 -7
  342. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  343. package/dist/modules/workspace/workspace.service.d.ts +18 -12
  344. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  345. package/dist/modules/workspace/workspace.service.js +49 -29
  346. package/dist/modules/workspace/workspace.service.js.map +1 -1
  347. package/dist/modules/workspace/workspace.tools.d.ts +2 -1
  348. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  349. package/dist/modules/workspace/workspace.tools.js +48 -20
  350. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  351. package/dist/modules/workspace/write-denial.d.ts +3 -2
  352. package/dist/modules/workspace/write-denial.d.ts.map +1 -1
  353. package/dist/modules/workspace/write-denial.js +6 -5
  354. package/dist/modules/workspace/write-denial.js.map +1 -1
  355. package/dist/shared/domain-errors.d.ts +39 -0
  356. package/dist/shared/domain-errors.d.ts.map +1 -1
  357. package/dist/shared/domain-errors.js +55 -0
  358. package/dist/shared/domain-errors.js.map +1 -1
  359. package/dist/shared/git.contract.d.ts +62 -7
  360. package/dist/shared/git.contract.d.ts.map +1 -1
  361. package/dist/shared/git.contract.js +30 -8
  362. package/dist/shared/git.contract.js.map +1 -1
  363. package/dist/shared/kb-context.d.ts +76 -0
  364. package/dist/shared/kb-context.d.ts.map +1 -0
  365. package/dist/shared/kb-context.js +108 -0
  366. package/dist/shared/kb-context.js.map +1 -0
  367. package/dist/shared/kb-layout.d.ts +3 -2
  368. package/dist/shared/kb-layout.d.ts.map +1 -1
  369. package/dist/shared/kb-layout.js +4 -3
  370. package/dist/shared/kb-layout.js.map +1 -1
  371. package/dist/shared/kb-layout.test.js +35 -27
  372. package/dist/shared/kb-layout.test.js.map +1 -1
  373. package/dist/shared/pending-proposals.d.ts +4 -1
  374. package/dist/shared/pending-proposals.d.ts.map +1 -1
  375. package/dist/shared/pending-proposals.js +3 -4
  376. package/dist/shared/pending-proposals.js.map +1 -1
  377. package/dist/shared/redact-secret.d.ts +5 -5
  378. package/dist/shared/redact-secret.js +5 -5
  379. package/dist/tenancy/index.d.ts +13 -0
  380. package/dist/tenancy/index.d.ts.map +1 -0
  381. package/dist/tenancy/index.js +13 -0
  382. package/dist/tenancy/index.js.map +1 -0
  383. package/dist/tenancy/static-tenant-source.d.ts +98 -0
  384. package/dist/tenancy/static-tenant-source.d.ts.map +1 -0
  385. package/dist/tenancy/static-tenant-source.js +220 -0
  386. package/dist/tenancy/static-tenant-source.js.map +1 -0
  387. package/dist/tenancy/tenant-host.d.ts +80 -0
  388. package/dist/tenancy/tenant-host.d.ts.map +1 -0
  389. package/dist/tenancy/tenant-host.js +217 -0
  390. package/dist/tenancy/tenant-host.js.map +1 -0
  391. package/dist/tenancy/tenant-runtime.d.ts +91 -0
  392. package/dist/tenancy/tenant-runtime.d.ts.map +1 -0
  393. package/dist/tenancy/tenant-runtime.js +174 -0
  394. package/dist/tenancy/tenant-runtime.js.map +1 -0
  395. package/dist/tenancy/tenant-secrets.d.ts +24 -0
  396. package/dist/tenancy/tenant-secrets.d.ts.map +1 -0
  397. package/dist/tenancy/tenant-secrets.js +30 -0
  398. package/dist/tenancy/tenant-secrets.js.map +1 -0
  399. package/dist/tenancy/tenant-source.contract.d.ts +45 -0
  400. package/dist/tenancy/tenant-source.contract.d.ts.map +1 -0
  401. package/dist/tenancy/tenant-source.contract.js +21 -0
  402. package/dist/tenancy/tenant-source.contract.js.map +1 -0
  403. package/migrations/0000_core_init.sql +14 -14
  404. package/migrations/0003_deployment_settings.sql +1 -1
  405. package/migrations/0005_github_facade.sql +1 -1
  406. package/migrations/0012_agent_audit.sql +6 -6
  407. package/package.json +3 -3
  408. package/src/__tests__/branch-model.test.ts +7 -6
  409. package/src/__tests__/kb-context.ts +30 -0
  410. package/src/__tests__/kb-layout-config.test.ts +35 -30
  411. package/src/core/__tests__/catalog-cache-invalidation.test.ts +2 -1
  412. package/src/core/__tests__/lifecycle.test.ts +78 -1
  413. package/src/core/__tests__/public-config.test.ts +5 -1
  414. package/src/core/catalog-cache-invalidation.ts +16 -11
  415. package/src/core/core-ports.ts +19 -0
  416. package/src/core/create-core-server.ts +64 -107
  417. package/src/core/create-core-services.ts +238 -96
  418. package/src/core/lifecycle.ts +214 -29
  419. package/src/core/public-config.ts +8 -5
  420. package/src/core-config.ts +107 -8
  421. package/src/index.ts +25 -2
  422. package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +2 -1
  423. package/src/modules/access/__tests__/access-requests.recut.test.ts +134 -0
  424. package/src/modules/access/__tests__/access-requests.routes.test.ts +610 -0
  425. package/src/modules/access/__tests__/access.routes.batch.test.ts +2 -1
  426. package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +2 -1
  427. package/src/modules/access/__tests__/access.routes.group-grant.test.ts +2 -1
  428. package/src/modules/access/__tests__/access.routes.overrides.test.ts +2 -1
  429. package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +2 -1
  430. package/src/modules/access/__tests__/access.routes.prospective.test.ts +2 -1
  431. package/src/modules/access/__tests__/access.routes.revoke.test.ts +2 -1
  432. package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +2 -1
  433. package/src/modules/access/__tests__/change-read-gate.test.ts +13 -11
  434. package/src/modules/access/__tests__/creator-access.test.ts +3 -2
  435. package/src/modules/access/__tests__/roles.routes.test.ts +2 -1
  436. package/src/modules/access/access-control.service.ts +20 -6
  437. package/src/modules/access/access-requests.contract.ts +93 -0
  438. package/src/modules/access/access-requests.routes.ts +286 -0
  439. package/src/modules/access/access-requests.service.ts +420 -0
  440. package/src/modules/access/access.routes.ts +10 -13
  441. package/src/modules/access/change-read-gate.ts +10 -4
  442. package/src/modules/access/creator-access.ts +7 -2
  443. package/src/modules/access-model/access-grammar.ts +22 -0
  444. package/src/modules/agent-instructions/__tests__/read-preamble.test.ts +13 -12
  445. package/src/modules/agent-instructions/read-preamble.ts +10 -12
  446. package/src/modules/auth/__tests__/account.routes.test.ts +15 -0
  447. package/src/modules/auth/__tests__/auth.service.test.ts +98 -0
  448. package/src/modules/auth/account-admission.ts +44 -0
  449. package/src/modules/auth/account.routes.ts +4 -1
  450. package/src/modules/auth/auth.service.ts +61 -2
  451. package/src/modules/auth/oidc-auth-provider.ts +9 -0
  452. package/src/modules/connection-probe/connection-probe.service.ts +7 -1
  453. package/src/modules/database/__tests__/advisory-lock.test.ts +23 -1
  454. package/src/modules/database/__tests__/connection.test.ts +98 -0
  455. package/src/modules/database/__tests__/migrations-unqualified.test.ts +32 -0
  456. package/src/modules/database/advisory-lock.ts +28 -4
  457. package/src/modules/database/connection.ts +143 -13
  458. package/src/modules/database/migrate.ts +48 -14
  459. package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +2 -1
  460. package/src/modules/diff/__tests__/diff.service.test.ts +2 -1
  461. package/src/modules/github-app/__tests__/github-app.test.ts +848 -0
  462. package/src/modules/github-app/github-app.client.ts +268 -0
  463. package/src/modules/github-app/github-app.connection.ts +204 -0
  464. package/src/modules/github-app/github-app.routes.ts +359 -0
  465. package/src/modules/github-app/index.ts +19 -0
  466. package/src/modules/kb-fs/__tests__/branch-name.test.ts +6 -6
  467. package/src/modules/kb-fs/__tests__/clone-config.test.ts +24 -20
  468. package/src/modules/kb-fs/__tests__/remote-url.test.ts +38 -0
  469. package/src/modules/kb-fs/branch-name.ts +3 -3
  470. package/src/modules/kb-fs/clone-config.ts +15 -12
  471. package/src/modules/kb-fs/remote-url.ts +35 -0
  472. package/src/modules/marketplace/__tests__/marketplace-repo.head.test.ts +2 -1
  473. package/src/modules/mcp/mcp.service.ts +11 -4
  474. package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +12 -11
  475. package/src/modules/plugins/__tests__/bundle-dialect.test.ts +2 -1
  476. package/src/modules/plugins/__tests__/compile-marketplace.test.ts +6 -4
  477. package/src/modules/plugins/__tests__/join-proposals.test.ts +100 -19
  478. package/src/modules/plugins/__tests__/join-request-jobs.service.test.ts +2 -1
  479. package/src/modules/plugins/__tests__/join-requests.service.test.ts +28 -11
  480. package/src/modules/plugins/__tests__/join-requests.settlement.test.ts +371 -0
  481. package/src/modules/plugins/__tests__/plugin-creation-display-name.test.ts +4 -3
  482. package/src/modules/plugins/__tests__/plugin-index.service.test.ts +6 -4
  483. package/src/modules/plugins/__tests__/plugin-links.service.test.ts +220 -5
  484. package/src/modules/plugins/__tests__/plugin-provision.service.test.ts +3 -1
  485. package/src/modules/plugins/__tests__/plugin-rename.service.test.ts +7 -6
  486. package/src/modules/plugins/__tests__/plugins.routes.test.ts +12 -3
  487. package/src/modules/plugins/__tests__/teams.routes.test.ts +2 -1
  488. package/src/modules/plugins/compile/marketplace-compiler.service.ts +7 -9
  489. package/src/modules/plugins/discovery/__tests__/kb-plugin-source.test.ts +20 -16
  490. package/src/modules/plugins/discovery/bundle-dialect/bundle.source.ts +9 -2
  491. package/src/modules/plugins/discovery/kb-plugin-source.ts +15 -8
  492. package/src/modules/plugins/discovery/native.source.ts +4 -1
  493. package/src/modules/plugins/index.ts +1 -1
  494. package/src/modules/plugins/join-proposals.ts +87 -19
  495. package/src/modules/plugins/join-request-jobs.service.ts +8 -7
  496. package/src/modules/plugins/join-requests.service.ts +203 -43
  497. package/src/modules/plugins/plugin-links.service.ts +192 -19
  498. package/src/modules/plugins/plugin-links.ts +147 -27
  499. package/src/modules/plugins/plugin-provision.service.ts +54 -27
  500. package/src/modules/plugins/plugin-rename.service.ts +10 -10
  501. package/src/modules/plugins/plugins.routes.ts +48 -17
  502. package/src/modules/plugins/plugins.service.ts +7 -11
  503. package/src/modules/plugins/teams.routes.ts +16 -8
  504. package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +7 -0
  505. package/src/modules/secrets-vault/__tests__/secrets-variable-loader.test.ts +40 -0
  506. package/src/modules/secrets-vault/__tests__/tool-owner-gate.route.test.ts +2 -0
  507. package/src/modules/secrets-vault/index.ts +2 -0
  508. package/src/modules/secrets-vault/secrets-variable-loader.ts +51 -21
  509. package/src/modules/secrets-vault/secrets-vault.routes.ts +7 -6
  510. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +24 -11
  511. package/src/modules/settings/__tests__/git-root-folders.test.ts +2 -1
  512. package/src/modules/settings/__tests__/repository-source.test.ts +191 -0
  513. package/src/modules/settings/__tests__/setup.routes.boot-failure.test.ts +2 -1
  514. package/src/modules/settings/__tests__/setup.routes.git-mode.test.ts +353 -0
  515. package/src/modules/settings/__tests__/setup.routes.github-app.test.ts +282 -0
  516. package/src/modules/settings/__tests__/setup.routes.layout-phase.test.ts +7 -4
  517. package/src/modules/settings/__tests__/setup.routes.managed-phase.test.ts +233 -0
  518. package/src/modules/settings/__tests__/setup.routes.oidc.test.ts +2 -0
  519. package/src/modules/settings/__tests__/setup.routes.sync-status.test.ts +2 -0
  520. package/src/modules/settings/__tests__/setup.routes.test.ts +33 -52
  521. package/src/modules/settings/deployment-settings.service.ts +130 -23
  522. package/src/modules/settings/managed-repository.ts +68 -0
  523. package/src/modules/settings/repository-source.ts +197 -0
  524. package/src/modules/settings/setup.routes.ts +233 -19
  525. package/src/modules/skills/__tests__/allowed-tools-check.test.ts +11 -10
  526. package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +4 -3
  527. package/src/modules/skills/__tests__/pending-skills.service.test.ts +3 -1
  528. package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +7 -2
  529. package/src/modules/skills/__tests__/skills.routes.warnings.test.ts +2 -1
  530. package/src/modules/skills/__tests__/skills.service.test.ts +3 -2
  531. package/src/modules/skills/allowed-tools-check.ts +7 -6
  532. package/src/modules/skills/pending-skills.service.ts +9 -8
  533. package/src/modules/skills/skill-access-requests.routes.ts +29 -79
  534. package/src/modules/skills/skills.routes.ts +4 -3
  535. package/src/modules/skills/skills.service.ts +13 -9
  536. package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +3 -2
  537. package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +3 -2
  538. package/src/modules/tool-helpers/tool-context.ts +15 -0
  539. package/src/modules/tool-manuals/__tests__/mcp-json-discovery.test.ts +17 -12
  540. package/src/modules/tool-manuals/__tests__/mcp-server-edit.service.test.ts +2 -1
  541. package/src/modules/tool-manuals/__tests__/pending-tools.service.test.ts +4 -1
  542. package/src/modules/tool-manuals/__tests__/tool-delete.service.test.ts +2 -1
  543. package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +2 -1
  544. package/src/modules/tool-manuals/__tests__/tool-manuals.cli.test.ts +5 -4
  545. package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +2 -1
  546. package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.routes.test.ts +4 -2
  547. package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.test.ts +13 -5
  548. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +2 -1
  549. package/src/modules/tool-manuals/__tests__/tool-manuals.restart.test.ts +9 -1
  550. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +3 -2
  551. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +2 -0
  552. package/src/modules/tool-manuals/mcp-json-discovery.ts +6 -4
  553. package/src/modules/tool-manuals/mcp-server-edit.service.ts +13 -11
  554. package/src/modules/tool-manuals/pending-tools.service.ts +19 -16
  555. package/src/modules/tool-manuals/tool-delete.service.ts +13 -10
  556. package/src/modules/tool-manuals/tool-manuals.routes.ts +10 -8
  557. package/src/modules/tool-manuals/tool-manuals.service.ts +15 -13
  558. package/src/modules/tool-manuals/tool-manuals.tools.ts +7 -6
  559. package/src/modules/workflow/__tests__/apply-failure.test.ts +11 -2
  560. package/src/modules/workflow/__tests__/merge-announces-tree.test.ts +14 -26
  561. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +2 -1
  562. package/src/modules/workflow/__tests__/session-ontology.service.test.ts +3 -2
  563. package/src/modules/workflow/__tests__/workflow.routes.lock-path.test.ts +2 -1
  564. package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +3 -10
  565. package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +2 -1
  566. package/src/modules/workflow/__tests__/workflow.service.deleted-branch-sweep.test.ts +3 -10
  567. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +187 -35
  568. package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +2 -1
  569. package/src/modules/workflow/__tests__/workflow.service.platform-restore.test.ts +2 -1
  570. package/src/modules/workflow/__tests__/workflow.service.read-gate.test.ts +3 -2
  571. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +2 -1
  572. package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +5 -4
  573. package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +148 -41
  574. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +143 -2
  575. package/src/modules/workflow/agent-tools/workflow.tools.ts +60 -12
  576. package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +5 -4
  577. package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +12 -11
  578. package/src/modules/workflow/git/__tests__/git.service.commitChanges.test.ts +9 -8
  579. package/src/modules/workflow/git/__tests__/git.service.commitFile.strayPath.test.ts +8 -7
  580. package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +6 -5
  581. package/src/modules/workflow/git/__tests__/git.service.createBranch.test.ts +3 -2
  582. package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +3 -2
  583. package/src/modules/workflow/git/__tests__/git.service.diffFileAtCommit.test.ts +7 -6
  584. package/src/modules/workflow/git/__tests__/git.service.diffFileBetweenBranches.test.ts +16 -15
  585. package/src/modules/workflow/git/__tests__/git.service.fileContentsAtCommit.test.ts +3 -2
  586. package/src/modules/workflow/git/__tests__/git.service.forkPoint.test.ts +2 -1
  587. package/src/modules/workflow/git/__tests__/git.service.history-guards.test.ts +2 -1
  588. package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +10 -9
  589. package/src/modules/workflow/git/__tests__/git.service.listTrackedFiles.test.ts +2 -1
  590. package/src/modules/workflow/git/__tests__/git.service.logForFile.test.ts +6 -5
  591. package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +9 -8
  592. package/src/modules/workflow/git/__tests__/git.service.pendingChanges.test.ts +2 -1
  593. package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +4 -3
  594. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +130 -8
  595. package/src/modules/workflow/git/__tests__/git.service.readFileAtRef.test.ts +2 -1
  596. package/src/modules/workflow/git/__tests__/git.service.revertPathsAndPush.test.ts +2 -1
  597. package/src/modules/workflow/git/__tests__/git.service.status.test.ts +4 -3
  598. package/src/modules/workflow/git/__tests__/git.service.syncFromRemote.test.ts +8 -7
  599. package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +41 -3
  600. package/src/modules/workflow/git/__tests__/pull-request.service.getPrDetail.test.ts +145 -2
  601. package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-delete.test.ts +166 -0
  602. package/src/modules/workflow/git/git.service.ts +49 -17
  603. package/src/modules/workflow/git/node-git-runner.ts +43 -4
  604. package/src/modules/workflow/git/pull-request.service.ts +119 -0
  605. package/src/modules/workflow/review-workflow/review-workflow.service.ts +9 -6
  606. package/src/modules/workflow/session-ontology.service.ts +7 -2
  607. package/src/modules/workflow/workflow.routes.ts +3 -1
  608. package/src/modules/workflow/workflow.service.ts +201 -76
  609. package/src/modules/workspace/__tests__/file-stat-access.test.ts +3 -2
  610. package/src/modules/workspace/__tests__/git-internals.security.test.ts +10 -9
  611. package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +4 -2
  612. package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -2
  613. package/src/modules/workspace/__tests__/workspace.routes.branch-errors.test.ts +2 -1
  614. package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +2 -1
  615. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +2 -1
  616. package/src/modules/workspace/__tests__/workspace.routes.download-implies-read.test.ts +2 -1
  617. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +2 -1
  618. package/src/modules/workspace/__tests__/workspace.routes.file-writes.test.ts +2 -1
  619. package/src/modules/workspace/__tests__/workspace.routes.folders.test.ts +5 -4
  620. package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +2 -1
  621. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +2 -1
  622. package/src/modules/workspace/__tests__/workspace.service.ensure-remotes-fetched.test.ts +2 -2
  623. package/src/modules/workspace/__tests__/workspace.service.list-cloned.test.ts +6 -5
  624. package/src/modules/workspace/__tests__/workspace.service.move-never-overwrites.test.ts +2 -1
  625. package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +2 -1
  626. package/src/modules/workspace/__tests__/workspace.service.test.ts +84 -50
  627. package/src/modules/workspace/__tests__/workspace.service.unknown-branch.test.ts +45 -1
  628. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +10 -7
  629. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +237 -10
  630. package/src/modules/workspace/__tests__/workspace.tools.test.ts +44 -11
  631. package/src/modules/workspace/__tests__/write-denial.test.ts +5 -4
  632. package/src/modules/workspace/session-ontology.gate.ts +6 -4
  633. package/src/modules/workspace/startup/__tests__/kb-startup-runner.degraded.test.ts +6 -2
  634. package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +240 -21
  635. package/src/modules/workspace/startup/kb-git.ts +15 -22
  636. package/src/modules/workspace/startup/kb-startup-runner.ts +198 -45
  637. package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +104 -98
  638. package/src/modules/workspace/startup/steps/groups-to-plugins.step.ts +24 -16
  639. package/src/modules/workspace/startup/steps/personal-spaces.step.ts +14 -5
  640. package/src/modules/workspace/startup/steps/plugin-display-names.step.ts +13 -5
  641. package/src/modules/workspace/startup/steps/plugin-manifests.step.ts +14 -5
  642. package/src/modules/workspace/startup/steps/seed-tree.ts +11 -9
  643. package/src/modules/workspace/startup/steps/template-files.step.ts +43 -34
  644. package/src/modules/workspace/startup/steps/template-source.ts +8 -5
  645. package/src/modules/workspace/workspace.routes.ts +8 -7
  646. package/src/modules/workspace/workspace.service.ts +47 -28
  647. package/src/modules/workspace/workspace.tools.ts +56 -20
  648. package/src/modules/workspace/write-denial.ts +7 -5
  649. package/src/shared/__tests__/kb-layout.plugin.test.ts +19 -16
  650. package/src/shared/domain-errors.ts +58 -0
  651. package/src/shared/git.contract.ts +80 -8
  652. package/src/shared/kb-context.ts +130 -0
  653. package/src/shared/kb-layout.test.ts +37 -27
  654. package/src/shared/kb-layout.ts +4 -3
  655. package/src/shared/pending-proposals.ts +7 -4
  656. package/src/shared/redact-secret.ts +5 -5
  657. package/src/tenancy/__tests__/static-tenant-source.test.ts +177 -0
  658. package/src/tenancy/__tests__/tenant-host.test.ts +372 -0
  659. package/src/tenancy/__tests__/tenant-runtime.test.ts +221 -0
  660. package/src/tenancy/__tests__/tenant-secrets.test.ts +35 -0
  661. package/src/tenancy/index.ts +35 -0
  662. package/src/tenancy/static-tenant-source.ts +296 -0
  663. package/src/tenancy/tenant-host.ts +261 -0
  664. package/src/tenancy/tenant-runtime.ts +208 -0
  665. package/src/tenancy/tenant-secrets.ts +41 -0
  666. package/src/tenancy/tenant-source.contract.ts +59 -0
@@ -1,7 +1,11 @@
1
1
  import { describe, test, expect } from 'vitest';
2
+ import { UtcpClientConfigSerializer } from '@utcp/sdk';
2
3
  import {
3
4
  BevelSecretsVariableLoader,
5
+ DEFAULT_SECRETS_SCOPE,
6
+ bevelSecretsLoaderConfig,
4
7
  registerBevelSecretsVariableLoader,
8
+ unregisterBevelSecretsVariableLoader,
5
9
  } from '../secrets-variable-loader.js';
6
10
  import type { ISecretsVaultService } from '../secrets-vault.contract.js';
7
11
 
@@ -51,4 +55,40 @@ describe('BevelSecretsVariableLoader', () => {
51
55
  const loader = new BevelSecretsVariableLoader('');
52
56
  expect(await loader.get('m_X')).toBeNull();
53
57
  });
58
+
59
+ test('two knowledge bases in one process resolve the same user and key from their own vaults', async () => {
60
+ // One process, two vaults, one user id in each (ids are only unique
61
+ // within a knowledge base): a loader reads the vault registered under
62
+ // ITS scope, and a scope nobody registered resolves nothing.
63
+ registerBevelSecretsVariableLoader(fakeVault('user-1', { weather_WEATHER_KEY: 'sk-acme' }), 'acme');
64
+ registerBevelSecretsVariableLoader(fakeVault('user-1', { weather_WEATHER_KEY: 'sk-globex' }), 'globex');
65
+ expect(await new BevelSecretsVariableLoader('user-1', 'acme').get('weather_WEATHER_KEY')).toBe('sk-acme');
66
+ expect(await new BevelSecretsVariableLoader('user-1', 'globex').get('weather_WEATHER_KEY')).toBe('sk-globex');
67
+ expect(await new BevelSecretsVariableLoader('user-1', 'nobody').get('weather_WEATHER_KEY')).toBeNull();
68
+ });
69
+
70
+ test('the descriptor round-trips the scope through the serializer registry', async () => {
71
+ registerBevelSecretsVariableLoader(fakeVault('user-1', { weather_WEATHER_KEY: 'sk-acme' }), 'acme');
72
+ const config = new UtcpClientConfigSerializer().validateDict({
73
+ variables: {},
74
+ load_variables_from: [bevelSecretsLoaderConfig('user-1', 'acme')],
75
+ });
76
+ const [loader] = config.load_variables_from as BevelSecretsVariableLoader[];
77
+ expect(loader.scope).toBe('acme');
78
+ expect(await loader.get('weather_WEATHER_KEY')).toBe('sk-acme');
79
+ // Without a scope the descriptor names the single knowledge base's.
80
+ const [plain] = new UtcpClientConfigSerializer().validateDict({
81
+ variables: {},
82
+ load_variables_from: [bevelSecretsLoaderConfig('user-1')],
83
+ }).load_variables_from as BevelSecretsVariableLoader[];
84
+ expect(plain.scope).toBe(DEFAULT_SECRETS_SCOPE);
85
+ });
86
+
87
+ test('unregistering a scope makes its loaders resolve nothing', async () => {
88
+ registerBevelSecretsVariableLoader(fakeVault('user-1', { weather_WEATHER_KEY: 'sk-acme' }), 'evicted');
89
+ const loader = new BevelSecretsVariableLoader('user-1', 'evicted');
90
+ expect(await loader.get('weather_WEATHER_KEY')).toBe('sk-acme');
91
+ unregisterBevelSecretsVariableLoader('evicted');
92
+ expect(await loader.get('weather_WEATHER_KEY')).toBeNull();
93
+ });
54
94
  });
@@ -2,6 +2,7 @@ import type { Server as HttpServer } from 'node:http';
2
2
  import express from 'express';
3
3
  import { afterEach, describe, expect, it, vi } from 'vitest';
4
4
  import { createSecretsVaultRoutes } from '../secrets-vault.routes.js';
5
+ import { testKbContext } from '../../../__tests__/kb-context.js';
5
6
 
6
7
  /**
7
8
  * THE OWNER GATE: a tool's shared (admin) secrets — plain values and OAuth
@@ -91,6 +92,7 @@ async function baseUrlAs(email: string): Promise<string> {
91
92
  app.use(
92
93
  '/api',
93
94
  createSecretsVaultRoutes({
95
+ kb: testKbContext(),
94
96
  secretsVault,
95
97
  toolManualService,
96
98
  accessControl,
@@ -21,6 +21,8 @@ export {
21
21
  } from './secrets-vault.contract.js';
22
22
  export {
23
23
  registerBevelSecretsVariableLoader,
24
+ unregisterBevelSecretsVariableLoader,
24
25
  bevelSecretsLoaderConfig,
25
26
  BEVEL_SECRETS_LOADER_TYPE,
27
+ DEFAULT_SECRETS_SCOPE,
26
28
  } from './secrets-variable-loader.js';
@@ -18,29 +18,43 @@ const log = logger('secrets-vault');
18
18
  * The `UtcpClient.create` path re-validates the whole config through the
19
19
  * serializer registry, so a loader can't be handed in as a bare live object — it
20
20
  * must round-trip through a registered serializer. We therefore put a plain
21
- * descriptor `{ variable_loader_type, user_id }` in `load_variables_from` (via
22
- * {@link bevelSecretsLoaderConfig}) and let the registered serializer rebuild a
23
- * live loader bound to the process-wide vault. Swapping the vault backend (e.g.
24
- * to a client's external secret manager) is just a different
25
- * `ISecretsVaultService` passed to {@link registerBevelSecretsVariableLoader}.
21
+ * descriptor `{ variable_loader_type, user_id, scope }` in `load_variables_from`
22
+ * (via {@link bevelSecretsLoaderConfig}) and let the registered serializer
23
+ * rebuild a live loader bound to the vault registered under that scope.
24
+ *
25
+ * ONE VAULT PER SCOPE, NOT PER PROCESS. The serializer registry is UTCP's and
26
+ * process-wide, but a process can host several knowledge bases, each with a
27
+ * vault of its own, and a user id is only unique within one of them. So the
28
+ * descriptor names the scope its vault was registered under, and a loader
29
+ * reads through that vault alone: two knowledge bases whose users both stored
30
+ * `weather_WEATHER_KEY` never see each other's value. A single-tenant
31
+ * deployment registers under {@link DEFAULT_SECRETS_SCOPE} and names nothing.
32
+ * Swapping the vault backend (e.g. to a client's external secret manager) is
33
+ * just a different `ISecretsVaultService` passed to
34
+ * {@link registerBevelSecretsVariableLoader}.
26
35
  */
27
36
  export const BEVEL_SECRETS_LOADER_TYPE = 'bevel_secrets';
28
37
 
38
+ /** The scope a deployment that hosts one knowledge base registers under. */
39
+ export const DEFAULT_SECRETS_SCOPE = 'default';
40
+
29
41
  /**
30
- * Process-wide vault the reconstructed loaders read through. Set once at
31
- * composition time (before any client is built) so the serializer — which only
32
- * receives a plain dict — can bind live loaders to it.
42
+ * The vaults the reconstructed loaders read through, by scope. A composition
43
+ * root registers its vault before any client is built; a graph that is torn
44
+ * down unregisters it so a stale descriptor resolves nothing.
33
45
  */
34
- let sharedSecretsVault: ISecretsVaultService | null = null;
46
+ const vaults = new Map<string, ISecretsVaultService>();
35
47
 
36
48
  export class BevelSecretsVariableLoader implements VariableLoader {
37
49
  readonly variable_loader_type = BEVEL_SECRETS_LOADER_TYPE;
38
50
  readonly user_id: string;
51
+ readonly scope: string;
39
52
  // VariableLoader is an open shape; allow arbitrary extra props.
40
53
  [key: string]: unknown;
41
54
 
42
- constructor(userId: string) {
55
+ constructor(userId: string, scope: string = DEFAULT_SECRETS_SCOPE) {
43
56
  this.user_id = userId;
57
+ this.scope = scope;
44
58
  }
45
59
 
46
60
  /**
@@ -52,9 +66,10 @@ export class BevelSecretsVariableLoader implements VariableLoader {
52
66
  * harvest a secret the user configured for a different manual.
53
67
  */
54
68
  async get(effectiveKey: string): Promise<string | null> {
55
- if (!sharedSecretsVault || !this.user_id) return null;
69
+ const vault = vaults.get(this.scope);
70
+ if (!vault || !this.user_id) return null;
56
71
  try {
57
- return await sharedSecretsVault.resolve(this.user_id, effectiveKey);
72
+ return await vault.resolve(this.user_id, effectiveKey);
58
73
  } catch (err) {
59
74
  // Log the fault so a backend failure is distinguishable from a merely
60
75
  // unset secret (resolve returning null) when troubleshooting.
@@ -66,15 +81,18 @@ export class BevelSecretsVariableLoader implements VariableLoader {
66
81
 
67
82
  class BevelSecretsVariableLoaderSerializer extends Serializer<VariableLoader> {
68
83
  toDict(obj: VariableLoader): Record<string, unknown> {
84
+ const loader = obj as BevelSecretsVariableLoader;
69
85
  return {
70
86
  variable_loader_type: BEVEL_SECRETS_LOADER_TYPE,
71
- user_id: (obj as BevelSecretsVariableLoader).user_id ?? '',
87
+ user_id: loader.user_id ?? '',
88
+ scope: loader.scope ?? DEFAULT_SECRETS_SCOPE,
72
89
  };
73
90
  }
74
91
 
75
92
  validateDict(obj: Record<string, unknown>): VariableLoader {
76
93
  const userId = typeof obj.user_id === 'string' ? obj.user_id : '';
77
- return new BevelSecretsVariableLoader(userId);
94
+ const scope = typeof obj.scope === 'string' && obj.scope ? obj.scope : DEFAULT_SECRETS_SCOPE;
95
+ return new BevelSecretsVariableLoader(userId, scope);
78
96
  }
79
97
  }
80
98
 
@@ -91,14 +109,26 @@ VariableLoaderSerializer.registerVariableLoader(
91
109
  );
92
110
 
93
111
  /**
94
- * Bind the process-wide vault the reconstructed loaders read through. Called
95
- * once at composition time; before it runs, loaders resolve to null.
112
+ * Bind the vault the loaders of `scope` read through. Called once per
113
+ * knowledge base at composition time; before it runs, loaders of that scope
114
+ * resolve to null.
96
115
  */
97
- export function registerBevelSecretsVariableLoader(secretsVault: ISecretsVaultService): void {
98
- sharedSecretsVault = secretsVault;
116
+ export function registerBevelSecretsVariableLoader(
117
+ secretsVault: ISecretsVaultService,
118
+ scope: string = DEFAULT_SECRETS_SCOPE,
119
+ ): void {
120
+ vaults.set(scope, secretsVault);
121
+ }
122
+
123
+ /** Forget a scope's vault — the last step of tearing a knowledge base's graph down. */
124
+ export function unregisterBevelSecretsVariableLoader(scope: string = DEFAULT_SECRETS_SCOPE): void {
125
+ vaults.delete(scope);
99
126
  }
100
127
 
101
- /** The plain descriptor to place in a `UtcpClientConfig.load_variables_from` for a given user. */
102
- export function bevelSecretsLoaderConfig(userId: string): Record<string, unknown> {
103
- return { variable_loader_type: BEVEL_SECRETS_LOADER_TYPE, user_id: userId };
128
+ /**
129
+ * The plain descriptor to place in a `UtcpClientConfig.load_variables_from`
130
+ * for a given user of the knowledge base registered under `scope`.
131
+ */
132
+ export function bevelSecretsLoaderConfig(userId: string, scope: string = DEFAULT_SECRETS_SCOPE): Record<string, unknown> {
133
+ return { variable_loader_type: BEVEL_SECRETS_LOADER_TYPE, user_id: userId, scope };
104
134
  }
@@ -3,7 +3,6 @@ import { logger } from '../../shared/logging.js';
3
3
 
4
4
  const log = logger('secrets');
5
5
  import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
6
- import { DEFAULT_BRANCH } from '@bevel-software/platform-shared';
7
6
  import {
8
7
  InvalidSecretError,
9
8
  SecretNotFoundError,
@@ -17,11 +16,13 @@ import type { IToolManualService, ToolManualSummary, ToolVariable } from '../too
17
16
  import type { IConnectionProbeService } from '../connection-probe/connection-probe.contract.js';
18
17
  import { utcpNamespacedKey } from '../../shared/utcp-namespace.js';
19
18
  import type { IAccessControl } from '../access/access-control.interface.js';
20
- import { workspaceIdForBranch } from '../../shared/workspace-id.js';
19
+ import type { KbContext } from '../../shared/kb-context.js';
21
20
  import '../auth/auth.middleware.js'; // Express Request augmentation (req.userId / req.userEmail)
22
21
 
23
22
  export interface SecretsVaultRoutesDeps {
24
23
  secretsVault: ISecretsVaultService;
24
+ /** The released branch's clone — where the `.tool` files the access verdicts are read from live. */
25
+ kb: Pick<KbContext, 'defaultWorkspaceId'>;
25
26
  /** Source of `.tool` manuals + their declared variable scopes (default-branch catalog). */
26
27
  toolManualService: IToolManualService;
27
28
  /** Gates who may set a tool's ADMIN (shared) secrets — writers of the `.tool` file. */
@@ -79,16 +80,16 @@ export function isSafeReturnPath(returnTo: unknown): returnTo is string {
79
80
  * `req.userId` — secrets are private per user. Mounted behind the JWT middleware.
80
81
  */
81
82
  export function createSecretsVaultRoutes(deps: SecretsVaultRoutesDeps): express.Router {
82
- const { secretsVault, toolManualService, accessControl, connectionProbe } = deps;
83
+ const { secretsVault, toolManualService, accessControl, connectionProbe, kb } = deps;
83
84
  const router = express.Router();
84
85
  // A FUNCTION, not a constant. Routers are constructed at boot, and on a
85
86
  // deployment configured through the setup screen the branch model does not
86
- // exist yet at that moment — `DEFAULT_BRANCH` is still ''. The live binding
87
- // updates when setup applies the model, but only reads INSIDE a function
87
+ // exist yet at that moment — the default branch is still ''. The context
88
+ // learns it when setup applies the model, but only reads INSIDE a function
88
89
  // body see it; a construction-time capture would keep handing an empty
89
90
  // workspace id to the access resolver until the next restart ("Invalid
90
91
  // workspace ID" on every /secrets/tools call).
91
- const defaultWs = () => workspaceIdForBranch(DEFAULT_BRANCH);
92
+ const defaultWs = () => kb.defaultWorkspaceId();
92
93
 
93
94
  // The vault key = the exact key UTCP looks the var up under (doubles underscores
94
95
  // in the manual namespace), so storage and resolution agree for snake_case ids.
@@ -149,20 +149,12 @@ describe('DeploymentSettingsService — secrets', () => {
149
149
  expect(token).not.toHaveProperty('value');
150
150
  });
151
151
 
152
- it('publishes a stored token as GITHUB_TOKEN, which is what git reads', async () => {
152
+ it('keeps a stored token out of the process environment: git reads it per call', async () => {
153
153
  const { db } = makeDb();
154
154
  const settings = new DeploymentSettingsService(db, ENC_KEY);
155
155
  await settings.save({ gitToken: 'ghp_fromsetup' }, null);
156
- expect(process.env.GITHUB_TOKEN).toBe('ghp_fromsetup');
157
- });
158
-
159
- it('does not overwrite a git token the environment supplied', async () => {
160
- process.env.GIT_TOKEN = 'ghp_fromenv';
161
- process.env.GITHUB_TOKEN = 'ghp_fromenv';
162
- const { db } = makeDb();
163
- const settings = new DeploymentSettingsService(db, ENC_KEY);
164
- settings.syncGitTokenEnv();
165
- expect(process.env.GITHUB_TOKEN).toBe('ghp_fromenv');
156
+ expect(process.env.GITHUB_TOKEN).toBeUndefined();
157
+ expect(settings.resolve('gitToken')).toBe('ghp_fromsetup');
166
158
  });
167
159
 
168
160
  it('refuses to store a secret with no encryption key rather than writing plaintext', async () => {
@@ -528,3 +520,24 @@ describe('DeploymentSettingsService — validation', () => {
528
520
  ).toEqual([]);
529
521
  });
530
522
  });
523
+
524
+ describe('DeploymentSettingsService — an environment of its own', () => {
525
+ it('resolves the env-first layer from the environment it was given, not the process\'s', async () => {
526
+ process.env.KB_REPO_URL = 'https://host.example/leaks-into-every-tenant.git';
527
+ const { db } = makeDb();
528
+ const own = new DeploymentSettingsService(db, ENC_KEY, undefined, {
529
+ env: { KB_REPO_URL: 'https://github.com/acme/kb.git', GIT_USERNAME: 'oauth2' },
530
+ });
531
+ await own.load();
532
+ expect(own.resolve('kbRepoUrl')).toBe('https://github.com/acme/kb.git');
533
+ expect(own.sourceOf('kbRepoUrl')).toBe('env');
534
+ expect(own.resolve('gitUsername')).toBe('oauth2');
535
+ // What the given environment leaves out is not taken from the process either.
536
+ expect(own.resolve('gitToken')).toBe('');
537
+ expect(own.sourceOf('gitToken')).toBe('unset');
538
+ // A service built without one keeps reading the process, as before.
539
+ const shared = new DeploymentSettingsService(db, ENC_KEY);
540
+ await shared.load();
541
+ expect(shared.resolve('kbRepoUrl')).toBe('https://host.example/leaks-into-every-tenant.git');
542
+ });
543
+ });
@@ -10,7 +10,7 @@ import {
10
10
  rootFolderListerFor,
11
11
  type GitRunner,
12
12
  } from '../git-root-folders.js';
13
- import type { IGitRunner } from '../../../shared/git.contract.js';
13
+ import { NO_GIT_CREDENTIALS, type IGitRunner } from '../../../shared/git.contract.js';
14
14
 
15
15
  const LISTING = {
16
16
  url: 'https://example.com/acme/kb.git',
@@ -226,6 +226,7 @@ describe('rootFolderListerFor — the listing runs through the deployment git po
226
226
  const outcomes = ['', 'KnowledgeBase\0Plugins\0'];
227
227
  const port: IGitRunner = {
228
228
  defaultTimeoutMs: 1000,
229
+ credentials: NO_GIT_CREDENTIALS,
229
230
  run: (async (cwd: string, args: string[], opts: { env?: NodeJS.ProcessEnv; timeoutMs?: number } = {}) => {
230
231
  calls.push({ cwd, args, opts });
231
232
  return { stdout: outcomes.shift() ?? '', stderr: '' };
@@ -0,0 +1,191 @@
1
+ import fs from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { NodeGitRunner } from '../../workflow/git/node-git-runner.js';
6
+ import { ManagedRepository, MANAGED_REPOSITORY_DIR } from '../managed-repository.js';
7
+ import { RepositorySource, type GitHubAppRepository } from '../repository-source.js';
8
+
9
+ let root: string;
10
+
11
+ beforeEach(async () => {
12
+ root = await fs.mkdtemp(path.join(os.tmpdir(), 'hexis-managed-'));
13
+ });
14
+
15
+ afterEach(async () => {
16
+ await fs.rm(root, { recursive: true, force: true });
17
+ });
18
+
19
+ const reading = (values: Record<string, string>) => (key: string) => values[key] ?? '';
20
+
21
+ function source(values: Record<string, string>, extra: { fallbackToken?: string; githubApp?: GitHubAppRepository } = {}) {
22
+ const managed = new ManagedRepository(path.join(root, 'managed-repository'));
23
+ return {
24
+ managed,
25
+ source: new RepositorySource({
26
+ read: reading(values),
27
+ fallback: { username: 'x-access-token', token: extra.fallbackToken ?? '' },
28
+ managed,
29
+ ...(extra.githubApp ? { githubApp: extra.githubApp } : {}),
30
+ }),
31
+ };
32
+ }
33
+
34
+ const HOSTED = { kbRepoUrl: 'https://git.example.com/acme/kb.git', gitToken: 'the-token', gitUsername: 'oauth2' };
35
+
36
+ describe('RepositorySource: which way a deployment has its repository', () => {
37
+ it('has none while nothing is configured', () => {
38
+ const { source: s } = source({});
39
+ expect(s.mode()).toBeNull();
40
+ expect(s.url()).toBe('');
41
+ expect(s.answered()).toBe(false);
42
+ expect(s.credentials.token()).toBeNull();
43
+ });
44
+
45
+ it('reads a deployment configured before there was a choice as what it has: an address and a token', () => {
46
+ const { source: s } = source(HOSTED);
47
+ expect(s.mode()).toBe('token');
48
+ expect(s.url()).toBe(HOSTED.kbRepoUrl);
49
+ expect(s.credentials.token()).toBe('the-token');
50
+ expect(s.credentials.username()).toBe('oauth2');
51
+ expect(s.answered()).toBe(true);
52
+ });
53
+
54
+ it('reads a token the environment spells the old way', () => {
55
+ const { source: s } = source({ kbRepoUrl: HOSTED.kbRepoUrl }, { fallbackToken: 'from-GITHUB_TOKEN' });
56
+ expect(s.mode()).toBe('token');
57
+ expect(s.credentials.token()).toBe('from-GITHUB_TOKEN');
58
+ expect(s.answered()).toBe(true);
59
+ });
60
+
61
+ it('is not answered by half of an address and a token', () => {
62
+ expect(source({ kbRepoUrl: HOSTED.kbRepoUrl }).source.answered()).toBe(false);
63
+ expect(source({ gitToken: 'the-token' }).source.answered()).toBe(false);
64
+ });
65
+
66
+ it('ignores a mode it does not know, and reads what is configured', () => {
67
+ expect(source({ ...HOSTED, gitMode: 'carrier-pigeon' }).source.mode()).toBe('token');
68
+ });
69
+
70
+ it('answers for the values a save would put in effect, without the save', () => {
71
+ const { source: s, managed } = source(HOSTED);
72
+ const after = reading({ ...HOSTED, gitMode: 'managed' });
73
+ expect(s.mode(after)).toBe('managed');
74
+ expect(s.url(after)).toBe(managed.path);
75
+ // What is in effect has not moved.
76
+ expect(s.mode()).toBe('token');
77
+ });
78
+ });
79
+
80
+ describe('RepositorySource: a repository the deployment keeps', () => {
81
+ it('is reached by its path, and presented nothing', () => {
82
+ const { source: s, managed } = source({ gitMode: 'managed' });
83
+ expect(s.url()).toBe(managed.path);
84
+ expect(s.url()).toBe(path.join(root, 'managed-repository', MANAGED_REPOSITORY_DIR));
85
+ expect(s.answered()).toBe(true);
86
+ expect(s.credentials.token()).toBeNull();
87
+ });
88
+
89
+ /**
90
+ * One mode's credential is never presented to another mode's repository.
91
+ * A deployment that moved still has its old token stored, and it must not
92
+ * ride along in the environment of every git call made against a folder.
93
+ */
94
+ it('is never presented the token of the repository the deployment had before', () => {
95
+ const { source: s } = source({ ...HOSTED, gitMode: 'managed' }, { fallbackToken: 'from-the-environment' });
96
+ expect(s.credentials.token()).toBeNull();
97
+ expect(s.credentials.username()).toBe('x-access-token');
98
+ });
99
+ });
100
+
101
+ describe('RepositorySource: a repository reached through a GitHub App', () => {
102
+ const app = (overrides: Partial<GitHubAppRepository> = {}): GitHubAppRepository => ({
103
+ url: () => 'https://github.com/acme/kb.git',
104
+ token: () => 'an-installation-token',
105
+ prepare: async () => undefined,
106
+ answered: () => true,
107
+ ...overrides,
108
+ });
109
+
110
+ it('asks the app for the address and the token', () => {
111
+ const { source: s } = source({ gitMode: 'github-app', gitToken: 'a-leftover' }, { githubApp: app() });
112
+ expect(s.url()).toBe('https://github.com/acme/kb.git');
113
+ expect(s.credentials.token()).toBe('an-installation-token');
114
+ expect(s.credentials.username()).toBe('x-access-token');
115
+ expect(s.answered()).toBe(true);
116
+ });
117
+
118
+ it('renews the token before git is run, and only in this mode', async () => {
119
+ let renewed = 0;
120
+ const githubApp = app({ prepare: async () => void (renewed += 1) });
121
+ await source({ gitMode: 'github-app' }, { githubApp }).source.credentials.prepare?.();
122
+ await source(HOSTED, { githubApp }).source.credentials.prepare?.();
123
+ await source({ gitMode: 'managed' }, { githubApp }).source.credentials.prepare?.();
124
+ expect(renewed).toBe(1);
125
+ });
126
+
127
+ it('is unanswered on a deployment that has no such app', () => {
128
+ const { source: s } = source({ gitMode: 'github-app' });
129
+ expect(s.answered()).toBe(false);
130
+ expect(s.url()).toBe('');
131
+ expect(s.credentials.token()).toBeNull();
132
+ });
133
+ });
134
+
135
+ describe('ManagedRepository', () => {
136
+ const runner = new NodeGitRunner(30_000);
137
+ const git = async (cwd: string, ...args: string[]) => (await runner.run(cwd, args)).stdout.trim();
138
+
139
+ it('is created empty, bare, on the branch it is given', async () => {
140
+ const managed = new ManagedRepository(path.join(root, 'managed-repository'));
141
+ expect(await managed.exists()).toBe(false);
142
+ await managed.ensure(runner, 'trunk');
143
+ expect(await managed.exists()).toBe(true);
144
+ expect(await git(managed.path, 'rev-parse', '--is-bare-repository')).toBe('true');
145
+ expect(await git(managed.path, 'symbolic-ref', 'HEAD')).toBe('refs/heads/trunk');
146
+ expect(await git(managed.path, 'for-each-ref')).toBe('');
147
+ });
148
+
149
+ it('is cloned from, pushed to and fetched from like any remote', async () => {
150
+ const managed = new ManagedRepository(path.join(root, 'managed-repository'));
151
+ await managed.ensure(runner);
152
+ const one = path.join(root, 'one');
153
+ await fs.mkdir(one);
154
+ await git(one, 'init', '--initial-branch=main');
155
+ await fs.writeFile(path.join(one, 'README.md'), 'hello\n');
156
+ await git(one, 'add', '.');
157
+ await git(one, '-c', 'user.name=t', '-c', 'user.email=t@example.test', 'commit', '-m', 'first');
158
+ await git(one, 'push', managed.path, 'main');
159
+
160
+ const two = path.join(root, 'two');
161
+ await git(root, 'clone', '-b', 'main', managed.path, two);
162
+ // Whatever this machine's git makes of line endings on checkout.
163
+ expect((await fs.readFile(path.join(two, 'README.md'), 'utf8')).replace(/\r\n/g, '\n')).toBe('hello\n');
164
+ expect(await git(two, 'config', '--get', 'remote.origin.url')).toBe(managed.path);
165
+ });
166
+
167
+ it('is left exactly as it is when it already exists', async () => {
168
+ const managed = new ManagedRepository(path.join(root, 'managed-repository'));
169
+ await managed.ensure(runner);
170
+ const work = path.join(root, 'work');
171
+ await fs.mkdir(work);
172
+ await git(work, 'init', '--initial-branch=main');
173
+ await fs.writeFile(path.join(work, 'a.md'), 'a\n');
174
+ await git(work, 'add', '.');
175
+ await git(work, '-c', 'user.name=t', '-c', 'user.email=t@example.test', 'commit', '-m', 'first');
176
+ await git(work, 'push', managed.path, 'main');
177
+ const before = await git(managed.path, 'for-each-ref');
178
+
179
+ await managed.ensure(runner, 'another-branch');
180
+ expect(await git(managed.path, 'for-each-ref')).toBe(before);
181
+ expect(await git(managed.path, 'symbolic-ref', 'HEAD')).toBe('refs/heads/main');
182
+ });
183
+
184
+ it('refuses a folder that holds something that is not a repository', async () => {
185
+ const managed = new ManagedRepository(path.join(root, 'managed-repository'));
186
+ await fs.mkdir(managed.path, { recursive: true });
187
+ await fs.writeFile(path.join(managed.path, 'somebody.txt'), 'theirs');
188
+ await expect(managed.ensure(runner)).rejects.toThrow(/is not a git repository/);
189
+ expect(await fs.readFile(path.join(managed.path, 'somebody.txt'), 'utf8')).toBe('theirs');
190
+ });
191
+ });
@@ -6,6 +6,7 @@ import { createSetupRoutes } from '../setup.routes.js';
6
6
  import { DeploymentSettingsService } from '../deployment-settings.service.js';
7
7
  import type { Database } from '../../database/connection.js';
8
8
  import type { IAdminAccessService } from '../../admin/admin.interface.js';
9
+ import { testKbContext } from '../../../__tests__/kb-context.js';
9
10
 
10
11
  /**
11
12
  * A boot that survived an unreachable remote leaves the RUNNER standing on a
@@ -68,7 +69,7 @@ function listen(runner: { runAll(): Promise<void>; lastFailure(): string | null
68
69
  });
69
70
  app.use(
70
71
  '/api',
71
- createSetupRoutes(settings, { isAdmin: async () => true } as IAdminAccessService, runner),
72
+ createSetupRoutes(settings, { isAdmin: async () => true } as IAdminAccessService, runner, testKbContext()),
72
73
  );
73
74
  server = app.listen(0);
74
75
  const { port } = server.address() as AddressInfo;