@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
@@ -23,18 +23,34 @@ import {
23
23
  type RepositoryConnection,
24
24
  } from './connection-check.js';
25
25
  import {
26
- configureBranchModel,
27
- configureKbLayout,
28
- isBranchModelConfigured,
29
26
  isDefaultKbLayout,
30
27
  validateBranchModel,
31
28
  validateKbLayout,
32
29
  } from '@bevel-software/platform-shared';
30
+ import type { KbContext } from '../../shared/kb-context.js';
33
31
  import { failureOf, type GitFailure } from '../../shared/git-failure.js';
34
32
  import { redactSecret, urlQuerySecrets } from '../../shared/redact-secret.js';
35
33
  import { listRootFolders, pickListingBranch } from './git-root-folders.js';
34
+ import { MANAGED_DEFAULT_BRANCH } from './managed-repository.js';
35
+ import { GIT_MODES, type GitHubAppRepository, type RepositorySource } from './repository-source.js';
36
36
  import '../auth/auth.middleware.js'; // Express Request augmentation
37
37
 
38
+ /**
39
+ * What setup needs of the ways a deployment can be given its repository:
40
+ * the source every reader of the repository asks, and the one thing a mode
41
+ * has to have DONE before a save that chooses it may go through.
42
+ */
43
+ export interface RepositorySetup {
44
+ source: RepositorySource;
45
+ /** Create the repository the deployment keeps for itself, if it is not there. Never touches one that is. */
46
+ ensureManaged(initialBranch: string): Promise<void>;
47
+ /**
48
+ * The connection to GitHub through a GitHub App. Absent, that way is not
49
+ * offered, and a save that names it is refused.
50
+ */
51
+ githubApp?: Pick<GitHubAppRepository, 'url' | 'answered' | 'prepare' | 'token' | 'permits'>;
52
+ }
53
+
38
54
  /** Which name a host expects beside the token when none is configured. */
39
55
  const DEFAULT_GIT_USERNAME = 'x-access-token';
40
56
 
@@ -105,6 +121,12 @@ export function createSetupRoutes(
105
121
  /** That failure classified, for the setup screen; absent, the message is read instead. */
106
122
  lastFailureKind?(): GitFailure | null;
107
123
  },
124
+ /**
125
+ * The knowledge base's context as the running graph holds it: the save
126
+ * that completes setup applies the branch model and the layout to it, so
127
+ * every service reads the admin's answer without a restart.
128
+ */
129
+ kb: KbContext,
108
130
  /**
109
131
  * The remote-sync facts the Deployment page shows beside the sync secret:
110
132
  * the address a webhook or pipeline must call, and what the last call did.
@@ -134,8 +156,14 @@ export function createSetupRoutes(
134
156
  checkOidc: (config: OidcConfiguration) => Promise<OidcCheck> = checkOidcConfiguration,
135
157
  /** The issuer-only half, for a test with no application id or secret yet. */
136
158
  checkIssuer: (issuerUrl: string) => Promise<IssuerCheck> = (url) => checkOidcIssuer(url),
159
+ /**
160
+ * The ways a deployment can be given its repository. Absent, there is the
161
+ * one there always was: an address and a token, read from the settings.
162
+ */
163
+ repository?: RepositorySetup,
137
164
  ): express.Router {
138
165
  const router = express.Router();
166
+ const source = repository?.source;
139
167
 
140
168
  /**
141
169
  * Why the last setup-time run of the KB startup phase FAILED, or null. While
@@ -180,7 +208,30 @@ export function createSetupRoutes(
180
208
  };
181
209
  /** The app-gate answer: settings complete AND the KB phase settled clean, whoever ran it. */
182
210
  const kbReady = () =>
183
- isComplete(settings) && kbInit === null && kbInitInFlight === null && bootFailure() === null;
211
+ isComplete(settings, kb, source) && kbInit === null && kbInitInFlight === null && bootFailure() === null;
212
+
213
+ /**
214
+ * Which ways of having a repository this deployment offers and which one
215
+ * it is on, for the setup screen. `mode` is the one IN EFFECT, inferred
216
+ * for a deployment that never chose; `chosen` is the one the settings
217
+ * say, which differs from it between a move and the restart the move
218
+ * owes. The screen opens on what was chosen, says a restart is pending
219
+ * when the two differ, and offers the first of `modes` to a deployment
220
+ * that has none. `pinned` names the variable that chose for the
221
+ * deployment, when one did. Nothing at all from a mount without the
222
+ * choice, which the screen reads as the one way there was.
223
+ */
224
+ const repositoryStatus = () =>
225
+ source
226
+ ? {
227
+ repository: {
228
+ mode: source.mode(),
229
+ chosen: source.chosen(),
230
+ ...(settings.sourceOf('gitMode') === 'env' ? { pinned: 'GIT_MODE' } : {}),
231
+ modes: GIT_MODES.filter((mode) => mode !== 'github-app' || repository?.githubApp !== undefined),
232
+ },
233
+ }
234
+ : {};
184
235
 
185
236
  const requireAdmin: express.RequestHandler = async (req, res, next) => {
186
237
  if (!(await adminAccess.isAdmin(req.userEmail))) {
@@ -215,9 +266,10 @@ export function createSetupRoutes(
215
266
  }
216
267
  res.json({
217
268
  complete: kbReady(),
218
- awaitingRestart: awaitingRestart(settings),
269
+ awaitingRestart: awaitingRestart(settings, kb, source),
219
270
  isAdmin: true,
220
271
  settings: settings.describe(),
272
+ ...repositoryStatus(),
221
273
  oidcVerification: await settings.oidcVerification(),
222
274
  ...(kbInit ? { kbInit } : bootFailure() !== null ? { kbInit: bootFailureKind() } : {}),
223
275
  ...(sync ? { sync: { url: sync.url, last: sync.lastSync() } } : {}),
@@ -261,7 +313,13 @@ export function createSetupRoutes(
261
313
  // save that flips it false→true — whichever field arrives last — is the
262
314
  // one that must run the KB startup phase, regardless of which save
263
315
  // configured the branch model.
264
- const wasComplete = isComplete(settings);
316
+ const wasComplete = isComplete(settings, kb, source);
317
+ // A different question, asked of the GATE: whether anyone is being
318
+ // served. Settings that are answered are not a deployment that works
319
+ // — one whose first clone failed has answered everything and serves
320
+ // nobody.
321
+ const wasServing = kbReady();
322
+ nameBranchesOfManagedRepository(entries);
265
323
  if (!(await connectionHoldsFor(entries, wasComplete, res))) return;
266
324
  const oidc = await signInHoldsFor(entries, res);
267
325
  if (!oidc) return;
@@ -273,7 +331,35 @@ export function createSetupRoutes(
273
331
  if (oidc.record) {
274
332
  await settings.recordOidcVerification(oidc.record.state, oidc.record.credentials);
275
333
  }
276
- const { restartRequired, restartKeys } = await settings.save(entries, req.userId ?? null);
334
+ const saved = await settings.save(entries, req.userId ?? null);
335
+ /**
336
+ * A deployment that was not serving has nothing on the mode it had:
337
+ * the mode chosen takes effect now, and the startup phase below is
338
+ * what a restart would have run. One that WAS serving stays on the
339
+ * mode it is on, working copies and credential alike, until it is
340
+ * started again.
341
+ *
342
+ * SERVING, not answered. The pin protects what is running on the
343
+ * mode in effect, and behind a shut gate nothing is: a first run
344
+ * whose initialisation failed, a boot that found its repository
345
+ * unreachable. Pinned there, the way out of a repository that does
346
+ * not work would be closed — the admin chooses another, the retry
347
+ * below runs against the one that just failed, and the screen asks
348
+ * for a restart that changes nothing.
349
+ */
350
+ if (source && !wasServing) source.takeEffect();
351
+ /**
352
+ * The restart the mode owes is read off the two modes themselves, not
353
+ * off what this save wrote: it is owed for as long as the mode chosen
354
+ * is not the one in effect, whichever save chose it, and no longer
355
+ * once a save chooses the mode in effect back.
356
+ */
357
+ const modePending = source !== undefined && source.chosen() !== source.mode();
358
+ const restartKeys = [
359
+ ...saved.restartKeys.filter((key) => key !== 'gitMode'),
360
+ ...(modePending ? ['gitMode'] : []),
361
+ ];
362
+ const restartRequired = restartKeys.length > 0;
277
363
  /** Whether this save put the stored folder names into the running process. */
278
364
  let layoutApplied = false;
279
365
  /** Whether this save put the stored branch model into the running process. */
@@ -292,13 +378,13 @@ export function createSetupRoutes(
292
378
  * capturing it at construction, which is what makes applying it here
293
379
  * enough.
294
380
  */
295
- if (!isBranchModelConfigured()) {
381
+ if (!kb.isBranchModelConfigured()) {
296
382
  const model = {
297
383
  defaultBranch: settings.resolve('defaultBranch'),
298
384
  protectedBranches: settings.resolve('protectedBranches'),
299
385
  };
300
386
  if (!validateBranchModel(model)) {
301
- configureBranchModel(model);
387
+ kb.applyBranchModel(model);
302
388
  branchModelApplied = true;
303
389
  }
304
390
  }
@@ -316,7 +402,7 @@ export function createSetupRoutes(
316
402
  * on a re-save of a complete, healthy setup: with the gate open,
317
403
  * sessions may be live and that is no longer a quiet moment.
318
404
  */
319
- if ((!wasComplete || kbInit !== null || bootFailure() !== null) && isComplete(settings)) {
405
+ if ((!wasComplete || kbInit !== null || bootFailure() !== null) && isComplete(settings, kb, source)) {
320
406
  /**
321
407
  * The folder names, applied BEFORE the phase for the same reason as
322
408
  * the branch model above: they are otherwise applied once at boot, so
@@ -327,10 +413,10 @@ export function createSetupRoutes(
327
413
  * the names an earlier setup save applied before a run that failed:
328
414
  * the gate never opened, so the retry initializes what is saved now.
329
415
  */
330
- if (isDefaultKbLayout() || (kbInit !== null && layoutAppliedBySetup)) {
416
+ if (isDefaultKbLayout(kb.layout) || (kbInit !== null && layoutAppliedBySetup)) {
331
417
  const layout = settings.resolveKbLayout();
332
418
  if (!validateKbLayout(layout)) {
333
- configureKbLayout(layout);
419
+ kb.applyLayout(layout);
334
420
  layoutApplied = true;
335
421
  layoutAppliedBySetup = true;
336
422
  }
@@ -356,6 +442,7 @@ export function createSetupRoutes(
356
442
  const raw = initErr instanceof Error ? initErr.message : String(initErr);
357
443
  const msg = redactSecret(raw, [
358
444
  settings.resolve('gitToken'),
445
+ source?.credentials.token() ?? '',
359
446
  ...urlQuerySecrets(settings.resolve('kbRepoUrl')),
360
447
  ]);
361
448
  log.error(`KB initialization failed after setup completed: ${msg}`);
@@ -382,8 +469,9 @@ export function createSetupRoutes(
382
469
  )
383
470
  : restartRequired,
384
471
  complete: kbReady(),
385
- awaitingRestart: awaitingRestart(settings),
472
+ awaitingRestart: awaitingRestart(settings, kb, source),
386
473
  settings: settings.describe(),
474
+ ...repositoryStatus(),
387
475
  oidcVerification: await settings.oidcVerification(),
388
476
  });
389
477
  } catch (err) {
@@ -398,6 +486,101 @@ export function createSetupRoutes(
398
486
  }
399
487
  }
400
488
 
489
+ /**
490
+ * A repository the deployment keeps for itself is new, and empty, and has
491
+ * no branches for anyone to look up: the branch model is ours to name. It
492
+ * is named only when nobody has — an admin's own answer, or one the
493
+ * environment supplies, stands. Every other mode has a repository that
494
+ * already exists, whose branches are asked for, never guessed.
495
+ */
496
+ function nameBranchesOfManagedRepository(entries: Record<string, string>): void {
497
+ if (!source) return;
498
+ const after = settings.resolveAfter(entries);
499
+ if (source.mode(after) !== 'managed') return;
500
+ if (after('defaultBranch') || after('protectedBranches')) return;
501
+ entries.defaultBranch = MANAGED_DEFAULT_BRANCH;
502
+ entries.protectedBranches = MANAGED_DEFAULT_BRANCH;
503
+ }
504
+
505
+ /**
506
+ * The same rule for a repository reached through a GitHub App: a saved
507
+ * connection is one GitHub has accepted for reading and writing, asked
508
+ * with the token git will present, which is the installation's.
509
+ *
510
+ * That token is also what keeps the repository's NAME honest. It is the
511
+ * one part of this connection an admin types, and a name the installation
512
+ * does not reach is refused here by GitHub, not by a list of ours.
513
+ *
514
+ * The repository has just said what it calls its trunk, so a deployment
515
+ * with no branch model is given that one: the same answer the setup
516
+ * screen fills in for a repository reached by its address.
517
+ */
518
+ async function githubConnectionHoldsFor(
519
+ setup: RepositorySetup,
520
+ entries: Record<string, string>,
521
+ after: (key: string) => string,
522
+ wasComplete: boolean,
523
+ res: express.Response,
524
+ ): Promise<boolean> {
525
+ const refuse = (problem: string, field = 'githubRepository') => {
526
+ res.status(400).json({ error: problem, problems: { [field]: problem } });
527
+ return false;
528
+ };
529
+ const app = setup.githubApp;
530
+ if (!app) return refuse('This deployment cannot connect to GitHub through a GitHub App.', 'gitMode');
531
+ if (!app.answered(after)) {
532
+ return refuse(
533
+ after('githubRepository')
534
+ ? 'Connect GitHub before choosing a repository.'
535
+ : 'Choose the repository the knowledge base lives in.',
536
+ );
537
+ }
538
+ const url = app.url(after);
539
+ const unanswered =
540
+ validateBranchModel({ defaultBranch: after('defaultBranch'), protectedBranches: after('protectedBranches') }) !== null;
541
+ // Against what is CHOSEN now, not what is in effect: a repository that
542
+ // was proven by the save that chose it is not proven again by the next.
543
+ const stored = (key: string) => settings.resolve(key);
544
+ const changes = setup.source.chosen() !== 'github-app' || url !== setup.source.url(stored);
545
+ if (!changes && (wasComplete || unanswered)) return true;
546
+ // BEFORE GitHub is asked anything with the installation token: that
547
+ // token reaches every repository the installation covers, and would
548
+ // answer for one the person connecting it could never have written to.
549
+ if (!app.permits(after('githubRepository'), after)) {
550
+ log.warn('a repository was named that the person who connected GitHub could not push to');
551
+ return refuse(
552
+ 'Choose a repository your own GitHub account can write to. If this one should be, press “Refresh the list” so it is brought up to date.',
553
+ );
554
+ }
555
+ try {
556
+ await app.prepare({ asked: true });
557
+ } catch (err) {
558
+ log.error('GitHub gave no token for the installation:', { detail: err instanceof Error ? err.message : String(err) });
559
+ }
560
+ const token = app.token();
561
+ if (!token) {
562
+ return refuse('GitHub gave this deployment no access. The app may have been uninstalled: connect it again.', 'gitMode');
563
+ }
564
+ const check = await checkConnection({ url, token, username: DEFAULT_GIT_USERNAME });
565
+ if (check.outcome !== 'connected') {
566
+ return refuse(
567
+ check.outcome === 'read-only'
568
+ ? 'The GitHub App can read that repository but not write to it. Grant it write access to the repository’s contents.'
569
+ : check.reason === 'unreachable'
570
+ ? 'GitHub could not be reached. Try again shortly.'
571
+ : 'The GitHub App cannot reach that repository. Add the repository to the app’s installation on GitHub.',
572
+ );
573
+ }
574
+ if (!after('defaultBranch') && !after('protectedBranches')) {
575
+ const trunk = check.defaultBranch || check.branches[0] || (check.empty ? MANAGED_DEFAULT_BRANCH : '');
576
+ if (trunk) {
577
+ entries.defaultBranch = trunk;
578
+ entries.protectedBranches = trunk;
579
+ }
580
+ }
581
+ return true;
582
+ }
583
+
401
584
  /**
402
585
  * A SAVED CONNECTION IS ONE THE HOST HAS ACCEPTED FOR READING AND WRITING.
403
586
  *
@@ -423,6 +606,25 @@ export function createSetupRoutes(
423
606
  res: express.Response,
424
607
  ): Promise<boolean> {
425
608
  const after = settings.resolveAfter(entries);
609
+ if (repository && repository.source.mode(after) === 'managed') {
610
+ // Nothing to prove to a host: the repository is the deployment's own.
611
+ // What has to hold is that it EXISTS before the save that points
612
+ // everything at it, so a disk that cannot take it refuses the choice
613
+ // instead of failing the first clone.
614
+ try {
615
+ await repository.ensureManaged(after('defaultBranch') || MANAGED_DEFAULT_BRANCH);
616
+ return true;
617
+ } catch (err) {
618
+ log.error('the managed repository could not be created:', { err });
619
+ const problem =
620
+ 'The repository could not be created on this deployment’s storage. Check that its backups folder is writable, or connect a repository of your own.';
621
+ res.status(400).json({ error: problem, problems: { gitMode: problem } });
622
+ return false;
623
+ }
624
+ }
625
+ if (repository && repository.source.mode(after) === 'github-app') {
626
+ return githubConnectionHoldsFor(repository, entries, after, wasComplete, res);
627
+ }
426
628
  const now: RepositoryConnection = {
427
629
  url: settings.resolve('kbRepoUrl'),
428
630
  token: settings.resolve('gitToken'),
@@ -759,8 +961,12 @@ export function createSetupRoutes(
759
961
  * deployment signs in perfectly well without it, and gating on it would lock
760
962
  * an admin out of the screen where they would set it up.
761
963
  */
762
- export function settingsAnswered(settings: DeploymentSettingsService): boolean {
763
- const kb = Boolean(settings.resolve('kbRepoUrl') && settings.resolve('gitToken'));
964
+ export function settingsAnswered(
965
+ settings: DeploymentSettingsService,
966
+ /** What answers for the repository. Absent: an address and a token, the one way there was. */
967
+ source?: Pick<RepositorySource, 'answered'>,
968
+ ): boolean {
969
+ const kb = source ? source.answered() : Boolean(settings.resolve('kbRepoUrl') && settings.resolve('gitToken'));
764
970
  const branches =
765
971
  validateBranchModel({
766
972
  defaultBranch: settings.resolve('defaultBranch'),
@@ -784,11 +990,19 @@ export function settingsAnswered(settings: DeploymentSettingsService): boolean {
784
990
  * that puts it there. {@link awaitingRestart} is what tells the screen to ask
785
991
  * for one rather than claim a field is missing.
786
992
  */
787
- export function isComplete(settings: DeploymentSettingsService): boolean {
788
- return settingsAnswered(settings) && isBranchModelConfigured();
993
+ export function isComplete(
994
+ settings: DeploymentSettingsService,
995
+ kb: Pick<KbContext, 'isBranchModelConfigured'>,
996
+ source?: Pick<RepositorySource, 'answered'>,
997
+ ): boolean {
998
+ return settingsAnswered(settings, source) && kb.isBranchModelConfigured();
789
999
  }
790
1000
 
791
1001
  /** Answered, but not yet in effect: everything is stored, the process is stale. */
792
- export function awaitingRestart(settings: DeploymentSettingsService): boolean {
793
- return settingsAnswered(settings) && !isBranchModelConfigured();
1002
+ export function awaitingRestart(
1003
+ settings: DeploymentSettingsService,
1004
+ kb: Pick<KbContext, 'isBranchModelConfigured'>,
1005
+ source?: Pick<RepositorySource, 'answered'>,
1006
+ ): boolean {
1007
+ return settingsAnswered(settings, source) && !kb.isBranchModelConfigured();
794
1008
  }
@@ -7,6 +7,7 @@ import {
7
7
  } from '../allowed-tools-check.js';
8
8
  import type { UtcpTool } from '../../tool-registry/tool.contract.js';
9
9
  import type { ToolManualDetail, ToolManualSummary } from '../../tool-manuals/tool-manuals.contract.js';
10
+ import { testKbContext } from '../../../__tests__/kb-context.js';
10
11
 
11
12
  const visible: VisibleTools = {
12
13
  core: ['read_file', 'get_skill', 'list_skills'],
@@ -110,10 +111,10 @@ describe('checkAllowedTools', () => {
110
111
 
111
112
  describe('skillFileRepoPath', () => {
112
113
  test('recognises skill files under the plugin and skills roots only', () => {
113
- expect(skillFileRepoPath('knowledge-base', 'knowledge-base/Plugins/Sales/rfi/SKILL.md')).toBe('Plugins/Sales/rfi/SKILL.md');
114
- expect(skillFileRepoPath('knowledge-base', './knowledge-base/Skills/triage/SKILL.md')).toBe('Skills/triage/SKILL.md');
115
- expect(skillFileRepoPath('knowledge-base', 'knowledge-base/Plugins/Sales/rfi/notes.md')).toBeNull();
116
- expect(skillFileRepoPath('knowledge-base', 'knowledge-base/Data/SKILL.md')).toBeNull();
114
+ expect(skillFileRepoPath(testKbContext(),'knowledge-base/Plugins/Sales/rfi/SKILL.md')).toBe('Plugins/Sales/rfi/SKILL.md');
115
+ expect(skillFileRepoPath(testKbContext(),'./knowledge-base/Skills/triage/SKILL.md')).toBe('Skills/triage/SKILL.md');
116
+ expect(skillFileRepoPath(testKbContext(),'knowledge-base/Plugins/Sales/rfi/notes.md')).toBeNull();
117
+ expect(skillFileRepoPath(testKbContext(),'knowledge-base/Data/SKILL.md')).toBeNull();
117
118
  });
118
119
  });
119
120
 
@@ -138,7 +139,7 @@ describe('AllowedToolsChecker', () => {
138
139
  }
139
140
  : null,
140
141
  };
141
- const checker = new AllowedToolsChecker(registry, manuals, 'knowledge-base');
142
+ const checker = new AllowedToolsChecker(registry, manuals, testKbContext());
142
143
 
143
144
  const skill = (tools: string) => `---\nname: rfi\ndescription: RFI.\nallowed-tools: ${tools}\n---\n\n# RFI\n`;
144
145
 
@@ -160,7 +161,7 @@ describe('AllowedToolsChecker', () => {
160
161
  const broken = new AllowedToolsChecker(
161
162
  { listExternal: async () => { throw new Error('down'); } },
162
163
  manuals,
163
- 'knowledge-base',
164
+ testKbContext(),
164
165
  );
165
166
  await expect(
166
167
  broken.checkSave('a@x.com', 'knowledge-base/Plugins/Sales/rfi/SKILL.md', skill('hubspot.serch')),
@@ -168,7 +169,7 @@ describe('AllowedToolsChecker', () => {
168
169
  });
169
170
 
170
171
  test('a capped capability list is treated as unknown, never as proof of absence', async () => {
171
- const capped = new AllowedToolsChecker(registry, manuals, 'knowledge-base', 1);
172
+ const capped = new AllowedToolsChecker(registry, manuals, testKbContext(), 1);
172
173
  expect(await capped.check('a@x.com', ['hubspot.whatever'])).toEqual([]);
173
174
  });
174
175
 
@@ -179,7 +180,7 @@ describe('AllowedToolsChecker', () => {
179
180
  const listExternal = vi.fn(registry.listExternal);
180
181
  const listAccessible = vi.fn(manuals.listAccessible);
181
182
  const getDetail = vi.fn(manuals.getDetail);
182
- const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail }, 'knowledge-base');
183
+ const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail }, testKbContext());
183
184
 
184
185
  expect(entries(await spying.check('alice@example.com', ['hubspot.serch']))).toEqual(['hubspot.serch']);
185
186
  expect(listExternal).toHaveBeenCalledWith({ userEmail: 'alice@example.com' });
@@ -193,7 +194,7 @@ describe('AllowedToolsChecker', () => {
193
194
  const listExternal = vi.fn(registry.listExternal);
194
195
  const listAccessible = vi.fn(manuals.listAccessible);
195
196
  const getDetail = vi.fn(manuals.getDetail);
196
- const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail }, 'knowledge-base');
197
+ const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail }, testKbContext());
197
198
 
198
199
  const results = await spying.checkSaves('a@x.com', [
199
200
  { path: 'knowledge-base/Plugins/Sales/rfi/SKILL.md', content: skill('hubspot.serch') },
@@ -214,7 +215,7 @@ describe('AllowedToolsChecker', () => {
214
215
  const listExternal = vi.fn(registry.listExternal);
215
216
  const listAccessible = vi.fn(manuals.listAccessible);
216
217
  const getDetail = vi.fn(manuals.getDetail);
217
- const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail }, 'knowledge-base');
218
+ const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail }, testKbContext());
218
219
 
219
220
  expect(await spying.check('a@x.com', ['Bash', 'Read', 'Bash(git:*)', 'mcp__github__create_issue', 'shell'])).toEqual([]);
220
221
  expect(listExternal).not.toHaveBeenCalled();
@@ -19,6 +19,7 @@ import type { ToolManualDetail, ToolManualSummary } from '../../tool-manuals/too
19
19
  import { registerSkillsTools } from '../skills.tools.js';
20
20
  import type { ISkillService } from '../skills.contract.js';
21
21
  import { AllowedToolsChecker } from '../allowed-tools-check.js';
22
+ import { testKbContext } from '../../../__tests__/kb-context.js';
22
23
 
23
24
  /**
24
25
  * The agent surfaces end to end: a SKILL.md written through the file tools
@@ -41,7 +42,7 @@ const checker = new AllowedToolsChecker(
41
42
  capabilities: [{ name: 'search', description: null }],
42
43
  }),
43
44
  },
44
- KB_DIR,
45
+ testKbContext({ kbDirName: KB_DIR }),
45
46
  );
46
47
 
47
48
  /** What the tool handed the service on its last `getSkill` — the tool's one job is to pass it on. */
@@ -109,8 +110,8 @@ async function start(): Promise<string> {
109
110
  const router = express.Router();
110
111
  registerWorkspaceTools(
111
112
  registry, router, fakeAuth, toolHandler,
112
- new SpillStore(join(tmpdir(), 'bevel-test-spills')), new DocExtractService(join(tmpdir(), 'bevel-test-doc-extract')), allowAll, KB_DIR,
113
- { service: {} as never, enabled: false, kbDirName: KB_DIR, recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
113
+ new SpillStore(join(tmpdir(), 'bevel-test-spills')), new DocExtractService(join(tmpdir(), 'bevel-test-doc-extract')), allowAll, testKbContext({ kbDirName: KB_DIR }),
114
+ { service: {} as never, enabled: false, kb: testKbContext({ kbDirName: KB_DIR }), recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
114
115
  new RoutineWritePolicyService(),
115
116
  {} as never,
116
117
  checker,
@@ -5,6 +5,7 @@ import { hashEmail } from '../../../shared/email-identity.js';
5
5
  import type { WorkspaceService } from '../../workspace/workspace.service.js';
6
6
  import type { IAccessControl } from '../../access/access-control.interface.js';
7
7
  import type { ISkillService, SkillSummary } from '../skills.contract.js';
8
+ import { testKbContext } from '../../../__tests__/kb-context.js';
8
9
 
9
10
  /**
10
11
  * The half of the catalog that is NOT on the default branch.
@@ -77,7 +78,7 @@ function harness(opts: {
77
78
  listChangeRequests: async () => opts.crs,
78
79
  } as unknown as IWorkflowService;
79
80
 
80
- return new PendingSkillsService(workspaceService, accessControl, skillService, workflow);
81
+ return new PendingSkillsService(workspaceService, accessControl, skillService, workflow, testKbContext());
81
82
  }
82
83
 
83
84
  const ADMIN_WRITES = {
@@ -210,6 +211,7 @@ describe('PendingSkillsService', () => {
210
211
  {} as unknown as IAccessControl,
211
212
  { listSkills: async () => [] } as unknown as ISkillService,
212
213
  workflow,
214
+ testKbContext(),
213
215
  );
214
216
  await expect(svc.listPendingSkills(AUTHOR)).resolves.toEqual([]);
215
217
  });
@@ -11,6 +11,7 @@ import type { IAccessControl } from '../../access/access-control.interface.js';
11
11
  import type { JoinRequestsService } from '../../plugins/join-requests.service.js';
12
12
  import type { ISkillService } from '../skills.contract.js';
13
13
  import { createSkillAccessRequestRoutes } from '../skill-access-requests.routes.js';
14
+ import { testKbContext } from '../../../__tests__/kb-context.js';
14
15
 
15
16
  /**
16
17
  * The branch probe behind an access request: the listing is used to PROVE a
@@ -26,15 +27,19 @@ const FOLDER = 'Skills/Eng/deploy';
26
27
 
27
28
  async function makeHarness(listBranches: IWorkflowService['listBranches']) {
28
29
  const workflow = {
29
- listChangeRequestsAuthoredBy: vi.fn(async () => []),
30
+ listChangeRequests: vi.fn(async () => []),
30
31
  listBranches: vi.fn(listBranches),
31
32
  createBranch: vi.fn(async () => ({ name: 'x', isDefault: false, isProtected: false })),
33
+ deleteBranch: vi.fn(async () => undefined),
32
34
  commitChanges: vi.fn(async () => null),
33
35
  openChangeRequest: vi.fn(async () => ({ number: 42 })),
36
+ getChangeRequestDetail: vi.fn(async () => ({ body: '' })),
34
37
  } as unknown as IWorkflowService;
35
38
  const workspaceService = {
36
39
  getOrCreateForBranch: vi.fn(async (branch: string) => ({ id: workspaceIdForBranch(branch) })),
37
40
  readFile: vi.fn(async () => '---\n---\nwrite:\n - Eve <eve@x.io>\n'),
41
+ readFileAtRef: vi.fn(async () => null),
42
+ ensureRemotesFetched: vi.fn(async () => undefined),
38
43
  writeFile: vi.fn(async () => undefined),
39
44
  } as unknown as WorkspaceService;
40
45
  const accessControl = { canWrite: vi.fn(async () => false) } as unknown as IAccessControl;
@@ -52,7 +57,7 @@ async function makeHarness(listBranches: IWorkflowService['listBranches']) {
52
57
  workflow,
53
58
  workspaceService,
54
59
  joinRequests: { list: vi.fn(), reconcile: vi.fn() } as unknown as JoinRequestsService,
55
- kbDirName: KB,
60
+ kb: testKbContext({ kbDirName: KB }),
56
61
  resolveUser: async () => MIA,
57
62
  }),
58
63
  );
@@ -5,6 +5,7 @@ import '../../auth/auth.middleware.js'; // Express Request.userEmail augmentatio
5
5
  import { createSkillsRoutes } from '../skills.routes.js';
6
6
  import type { ISkillService } from '../skills.contract.js';
7
7
  import type { IAllowedToolsChecker } from '../allowed-tools-check.js';
8
+ import { testKbContext } from '../../../__tests__/kb-context.js';
8
9
 
9
10
  /**
10
11
  * The browser's skill read carries the same `allowed-tools` warnings as
@@ -42,7 +43,7 @@ async function start(checker?: IAllowedToolsChecker): Promise<string> {
42
43
  req.userEmail = EMAIL;
43
44
  next();
44
45
  });
45
- app.use('/api', createSkillsRoutes(skillService, undefined, undefined, undefined, checker));
46
+ app.use('/api', createSkillsRoutes(skillService, testKbContext(), undefined, undefined, undefined, checker));
46
47
  server = await new Promise<Server>((resolve) => {
47
48
  const s = app.listen(0, () => resolve(s));
48
49
  });
@@ -13,6 +13,7 @@ import { execFile } from 'node:child_process';
13
13
  import { promisify } from 'node:util';
14
14
  import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
15
15
  import { GitService } from '../../workflow/git/git.service.js';
16
+ import { testKbContext } from '../../../__tests__/kb-context.js';
16
17
 
17
18
  const execFileAsync = promisify(execFile);
18
19
 
@@ -53,7 +54,7 @@ describe('SkillService', () => {
53
54
  } as unknown as IAccessControl;
54
55
 
55
56
  const svc = (access: IAccessControl = allowAll) =>
56
- new SkillService(workspaceService, access, KB_DIR, new NodeFs());
57
+ new SkillService(workspaceService, access, testKbContext({ kbDirName: KB_DIR }), new NodeFs());
57
58
 
58
59
  beforeEach(async () => {
59
60
  root = await mkdtemp(join(tmpdir(), 'skills-'));
@@ -377,7 +378,7 @@ describe('SkillService', () => {
377
378
 
378
379
  const versioned = (access: IAccessControl = allowAll) => {
379
380
  const service = svc(access);
380
- service.setHistory(new GitService(workspaceService, new WorkflowHooks(), KB_DIR));
381
+ service.setHistory(new GitService(workspaceService, new WorkflowHooks(), testKbContext({ kbDirName: KB_DIR })));
381
382
  return service;
382
383
  };
383
384
 
@@ -1,5 +1,5 @@
1
- import { PLUGINS_DIR, SKILLS_DIR } from '@bevel-software/platform-shared';
2
1
  import { logger } from '../../shared/logging.js';
2
+ import type { KbContext } from '../../shared/kb-context.js';
3
3
  import type { IToolRegistry } from '../tool-registry/tool.contract.js';
4
4
  import {
5
5
  EXTERNAL_KB_MANUAL_NAME,
@@ -236,11 +236,12 @@ function editDistance(a: string, b: string): number {
236
236
  * Accepts the workspace spelling (`<kbDirName>/Plugins/…`) the save
237
237
  * surfaces receive.
238
238
  */
239
- export function skillFileRepoPath(kbDirName: string, workspacePath: string): string | null {
239
+ export function skillFileRepoPath(kb: Pick<KbContext, 'kbDirName' | 'layout'>, workspacePath: string): string | null {
240
240
  const parts = workspacePath.split('/').filter((p) => p && p !== '.');
241
- if (parts[0] === kbDirName) parts.shift();
241
+ if (parts[0] === kb.kbDirName) parts.shift();
242
242
  if (parts.length < 3 || parts[parts.length - 1] !== 'SKILL.md') return null;
243
- return parts[0] === PLUGINS_DIR || parts[0] === SKILLS_DIR ? parts.join('/') : null;
243
+ const { pluginsDir, skillsDir } = kb.layout;
244
+ return parts[0] === pluginsDir || parts[0] === skillsDir ? parts.join('/') : null;
244
245
  }
245
246
 
246
247
  /** What the save surfaces and `get_skill` depend on. */
@@ -267,7 +268,7 @@ export class AllowedToolsChecker implements IAllowedToolsChecker {
267
268
  constructor(
268
269
  private readonly registry: Pick<IToolRegistry, 'listExternal'>,
269
270
  private readonly manuals: Pick<IToolManualService, 'listAccessible' | 'getDetail'>,
270
- private readonly kbDirName: string,
271
+ private readonly kb: Pick<KbContext, 'kbDirName' | 'layout'>,
271
272
  /**
272
273
  * The cap `getDetail` applies to a manual's capabilities. Taken from the
273
274
  * projection itself: a copy of the number here would silently start
@@ -300,7 +301,7 @@ export class AllowedToolsChecker implements IAllowedToolsChecker {
300
301
  * fail because a check could not run).
301
302
  */
302
303
  private declaredTools(workspacePath: string, content: string): readonly string[] | undefined {
303
- if (skillFileRepoPath(this.kbDirName, workspacePath) === null) return undefined;
304
+ if (skillFileRepoPath(this.kb, workspacePath) === null) return undefined;
304
305
  try {
305
306
  return parseSkillFrontmatter(content).allowedTools;
306
307
  } catch (err) {