@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,9 +1,7 @@
1
- import {
2
- PLUGINS_DIR,
3
- SKILLS_DIR,
4
- } from '@bevel-software/platform-shared';
1
+ import type { KbLayout } from '@bevel-software/platform-shared';
5
2
  import { type WorkspaceService } from '../workspace/workspace.service.js';
6
3
  import type { IAccessControl } from '../access/access-control.interface.js';
4
+ import type { KbContext } from '../../shared/kb-context.js';
7
5
  import { resolveDeclaredId } from '../../shared/frontmatter-id.js';
8
6
  import { visibleProposedFiles } from '../../shared/pending-proposals.js';
9
7
  import { isSafeSkillName, parseSkillFrontmatter } from './skills.service.js';
@@ -40,6 +38,7 @@ export class PendingSkillsService implements IPendingSkillService {
40
38
  private readonly accessControl: IAccessControl,
41
39
  private readonly skillService: ISkillService,
42
40
  private readonly workflow: IWorkflowService,
41
+ private readonly kb: KbContext,
43
42
  ) {}
44
43
 
45
44
  async listPendingSkills(userEmail: string): Promise<PendingSkill[]> {
@@ -54,14 +53,16 @@ export class PendingSkillsService implements IPendingSkillService {
54
53
  return [];
55
54
  }
56
55
 
56
+ const layout = this.kb.layout;
57
57
  const proposed = await visibleProposedFiles(
58
58
  {
59
59
  workspaceService: this.workspaceService,
60
60
  accessControl: this.accessControl,
61
61
  workflow: this.workflow,
62
+ kb: this.kb,
62
63
  },
63
64
  userEmail,
64
- (p) => isSkillDoc(p) && !released.has(folderOf(p)),
65
+ (p) => isSkillDoc(p, layout) && !released.has(folderOf(p)),
65
66
  );
66
67
 
67
68
  const out: PendingSkill[] = proposed.map(({ cr, path, content, isAuthor }) => {
@@ -96,12 +97,12 @@ export class PendingSkillsService implements IPendingSkillService {
96
97
  * catalog already supports. `Plugins/<plugin>/SKILL.md` is NOT a skill — a plugin
97
98
  * folder is not itself one.
98
99
  */
99
- function isSkillDoc(repoRelPath: string): boolean {
100
+ function isSkillDoc(repoRelPath: string, layout: KbLayout): boolean {
100
101
  const segments = repoRelPath.split('/');
101
102
  if (segments[segments.length - 1] !== SKILL_DOC) return false;
102
103
  // Under `Skills/` a skill may sit directly below the root: `Skills/<skill>/SKILL.md`.
103
- if (segments[0] === SKILLS_DIR) return segments.length >= 3;
104
- return segments.length >= 4 && segments[0] === PLUGINS_DIR;
104
+ if (segments[0] === layout.skillsDir) return segments.length >= 3;
105
+ return segments.length >= 4 && segments[0] === layout.pluginsDir;
105
106
  }
106
107
 
107
108
  /** The skill folder holding a SKILL.md. */
@@ -3,18 +3,13 @@ import { logger } from '../../shared/logging.js';
3
3
 
4
4
  const log = logger('skills');
5
5
  import '../auth/auth.middleware.js'; // Express Request.userId / userEmail augmentation
6
- import {
7
- DEFAULT_BRANCH,
8
- joinBranchFor,
9
- type AuthUser,
10
- type IWorkflowService,
11
- } from '@bevel-software/platform-shared';
6
+ import type { AuthUser, IWorkflowService } from '@bevel-software/platform-shared';
12
7
  import type { IAccessControl } from '../access/access-control.interface.js';
13
- import { spliceGrant } from '../access-model/access-splice.js';
8
+ import { folderTarget } from '../access/access-requests.contract.js';
9
+ import { AccessRequestsService } from '../access/access-requests.service.js';
14
10
  import { WorkflowDomainError } from '../../shared/domain-errors.js';
15
11
  import { domainErrorBody } from '../../shared/http-errors.js';
16
- import { isAbsence } from '../../shared/fs.contract.js';
17
- import { workspaceIdForBranch } from '../../shared/workspace-id.js';
12
+ import type { KbContext } from '../../shared/kb-context.js';
18
13
  import type { WorkspaceService } from '../workspace/workspace.service.js';
19
14
  import type { JoinRequestsService } from '../plugins/join-requests.service.js';
20
15
  import type { ISkillService } from './skills.contract.js';
@@ -29,13 +24,11 @@ import type { ISkillService } from './skills.contract.js';
29
24
  *
30
25
  * Why it exists: linking a skill into a plugin needs write on the skill's
31
26
  * rules (the link grants the plugin's principal there), and a plugin manager
32
- * often has no say over a skill some other scope owns. The request is a plain
33
- * change request whose branch splices `write: <requester>` into the skill
34
- * folder's `access.md`; the skill's editors see its proposals and accept
35
- * through the ordinary grant path, and it retires itself once the default
36
- * branch carries the grant (`JoinRequestsService`, keyed on the skill FOLDER
37
- * path rather than a plugin name — the branch-name convention takes any
38
- * exact string).
27
+ * often has no say over a skill some other scope owns. The request is opened
28
+ * by the shared `AccessRequestsService` — the same one the Manage access
29
+ * dialog's Request access uses — keyed on the skill FOLDER path, so this
30
+ * button and a Can edit request on that same folder are ONE request, shown in
31
+ * the skill page's banner and in the folder's dialog alike.
39
32
  *
40
33
  * Fail-closed like the skill catalog: a skill the caller cannot read answers
41
34
  * as unknown, and the editors' listing answers `[]` to anyone else.
@@ -46,13 +39,22 @@ export function createSkillAccessRequestRoutes(deps: {
46
39
  workflow: IWorkflowService;
47
40
  workspaceService: WorkspaceService;
48
41
  joinRequests: JoinRequestsService;
49
- kbDirName: string;
42
+ kb: KbContext;
50
43
  resolveUser: (req: express.Request) => Promise<AuthUser | null>;
51
44
  }): express.Router {
52
- const { skillService, accessControl, workflow, workspaceService, joinRequests, kbDirName, resolveUser } = deps;
45
+ const { skillService, accessControl, workflow, workspaceService, joinRequests, kb, resolveUser } = deps;
53
46
  const router = express.Router();
54
- const wsId = () => workspaceIdForBranch(DEFAULT_BRANCH);
47
+ const wsId = () => kb.defaultWorkspaceId();
55
48
  const rulesOf = (folder: string) => `${folder}/access.md`;
49
+ // The same opener the Manage access dialog uses, pointed at a skill's
50
+ // folder. Keyed on that folder's PATH, which is what makes this button and
51
+ // a Can edit request on the same folder one request rather than two.
52
+ const requests = new AccessRequestsService({
53
+ workflow,
54
+ workspaceService,
55
+ lifecycle: joinRequests,
56
+ kb,
57
+ });
56
58
 
57
59
  /** The skill the caller may read, by name — or null after answering 404. */
58
60
  async function readableSkill(
@@ -82,65 +84,13 @@ export function createSkillAccessRequestRoutes(deps: {
82
84
  res.status(409).json({ error: 'You can already edit this skill', kind: 'already-writable' });
83
85
  return;
84
86
  }
85
- const branch = joinBranchFor(user.email, folder);
86
- // FRESH: a repeated click must find the request the previous one opened,
87
- // and the cached listing can trail it — a miss here would send the
88
- // retry into a duplicate refusal.
89
- const existing = (await workflow.listChangeRequestsAuthoredBy(user.email, { fresh: true })).find(
90
- (cr) => cr.state === 'open' && cr.branch === branch,
91
- );
92
- if (existing) {
93
- res.json({ ok: true, number: existing.number });
94
- return;
95
- }
96
- // The branch may already exist (a request listed as closed, a retry
97
- // after a failed open). Existence is PROBED, before and — if creation
98
- // fails — after: the race shows up as "already exists" locally or as a
99
- // rejected push when origin got there first, and a message is not a
100
- // contract. A branch that is there is proceeded against; anything else
101
- // is a real failure, and a proposal on a branch that was not made would
102
- // be worse than the error. STRICT: the list proves absence, and a
103
- // listing that could not fetch proves nothing — it throws instead of
104
- // serving refs from before the branch was made (or deleted).
105
- const branchExists = async () =>
106
- (await workflow.listBranches(wsId(), { freshFetch: true, strictFetch: true })).some(
107
- (b) => b.name === branch,
108
- );
109
- if (!(await branchExists())) {
110
- try {
111
- await workflow.createBranch(wsId(), branch, DEFAULT_BRANCH);
112
- } catch (err) {
113
- if (!(await branchExists())) throw err;
114
- }
115
- }
116
- const ws = await workspaceService.getOrCreateForBranch(branch);
117
- const accessPath = `${kbDirName}/${rulesOf(folder)}`;
118
- // Only a PROVEN absence reads as "no rules yet": any other failure must
119
- // not be turned into an empty file that a splice then overwrites.
120
- const current = await workspaceService.readFile(ws.id, accessPath).catch((err: unknown) => {
121
- if (!isAbsence(err)) throw err;
122
- return '';
123
- });
124
- const spliced = spliceGrant(
125
- current,
126
- 'write',
127
- { kind: 'user', email: user.email, displayName: user.name },
128
- { target: 'folder' },
129
- );
130
- if (spliced.changed) {
131
- await workspaceService.writeFile(ws.id, accessPath, spliced.text);
132
- await workflow.commitChanges(ws.id, user, `Request write access to ${name}`);
133
- }
134
- const detail = await workflow.openChangeRequest(ws.id, user, {
135
- sourceBranch: branch,
136
- targetBranch: DEFAULT_BRANCH,
137
- title: `Access request: ${name}`,
138
- description:
139
- `${user.name} asked to edit the skill ${name}. An editor of the skill accepts by ` +
140
- `granting the access this branch proposes; the request closes itself once ` +
141
- `every proposal has landed.`,
87
+ const { number } = await requests.open({
88
+ user,
89
+ target: folderTarget(folder),
90
+ itemName: name,
91
+ level: 'write',
142
92
  });
143
- res.json({ ok: true, number: detail.number });
93
+ res.json({ ok: true, number });
144
94
  } catch (err) {
145
95
  if (err instanceof WorkflowDomainError) {
146
96
  res.status(err.status).json(domainErrorBody(err));
@@ -171,7 +121,7 @@ export function createSkillAccessRequestRoutes(deps: {
171
121
  const ctx = await requireEditor(req, res, () => res.json({ requests: [] }));
172
122
  if (!ctx) return;
173
123
  const crs = await workflow.listChangeRequests();
174
- res.json({ requests: await joinRequests.list(ctx.folder, ctx.folder, crs, ctx.user) });
124
+ res.json({ requests: await joinRequests.list(ctx.folder, folderTarget(ctx.folder), crs, ctx.user) });
175
125
  } catch (err) {
176
126
  log.error('failed to list access requests:', { err });
177
127
  res.status(500).json({ error: 'Failed to list access requests' });
@@ -192,7 +142,7 @@ export function createSkillAccessRequestRoutes(deps: {
192
142
  res.status(404).json({ error: 'Not found' });
193
143
  return;
194
144
  }
195
- res.json({ closed: await joinRequests.reconcile(ctx.folder, ctx.folder, cr, ctx.user) });
145
+ res.json({ closed: await joinRequests.reconcile(ctx.folder, folderTarget(ctx.folder), cr, ctx.user) });
196
146
  } catch (err) {
197
147
  log.error('failed to reconcile an access request:', { err });
198
148
  res.status(500).json({ error: 'Failed to reconcile the request' });
@@ -1,7 +1,6 @@
1
1
  import express from 'express';
2
- import { DEFAULT_BRANCH } from '@bevel-software/platform-shared';
3
2
  import '../auth/auth.middleware.js'; // Express Request.userId / userEmail augmentation
4
- import { workspaceIdForBranch } from '../../shared/workspace-id.js';
3
+ import type { KbContext } from '../../shared/kb-context.js';
5
4
  import type { IPendingSkillService, ISkillService, PluginMembership } from './skills.contract.js';
6
5
  import type { IAllowedToolsChecker } from './allowed-tools-check.js';
7
6
 
@@ -37,6 +36,8 @@ export interface SkillMembershipGate {
37
36
  */
38
37
  export function createSkillsRoutes(
39
38
  skillService: ISkillService,
39
+ /** The released branch's clone — where the discoverability verdicts are read. */
40
+ kb: Pick<KbContext, 'defaultWorkspaceId'>,
40
41
  pendingSkills?: IPendingSkillService,
41
42
  links?: SkillMembershipSource,
42
43
  /**
@@ -75,7 +76,7 @@ export function createSkillsRoutes(
75
76
  const folders = [...membership.byPlugin.entries()];
76
77
  const verdicts = folders.length
77
78
  ? await gate.canReadBatch(
78
- workspaceIdForBranch(DEFAULT_BRANCH),
79
+ kb.defaultWorkspaceId(),
79
80
  email,
80
81
  folders.map(([, p]) => `${p.folder}/access.md`),
81
82
  )
@@ -4,9 +4,8 @@ import { logger } from '../../shared/logging.js';
4
4
  const log = logger('skills');
5
5
  import fs from 'node:fs/promises';
6
6
  import { parseDocument } from 'yaml';
7
- import { DEFAULT_BRANCH, PLUGINS_DIR, SKILLS_DIR } from '@bevel-software/platform-shared';
8
7
  import type { WorkspaceService } from '../workspace/workspace.service.js';
9
- import { workspaceIdForBranch } from '../../shared/workspace-id.js';
8
+ import type { KbContext } from '../../shared/kb-context.js';
10
9
  import type { IAccessControl } from '../access/access-control.interface.js';
11
10
  import { extractFrontmatter, resolveDeclaredId, dedupeById } from '../../shared/frontmatter-id.js';
12
11
  import type { IgnoreRules, ITreeWalker } from '../../shared/fs.contract.js';
@@ -54,13 +53,17 @@ export class SkillService implements ISkillService {
54
53
  constructor(
55
54
  private readonly workspaceService: WorkspaceService,
56
55
  private readonly accessControl: IAccessControl,
57
- private readonly kbDirName: string,
56
+ private readonly kb: KbContext,
58
57
  private readonly disk: ITreeWalker,
59
58
  now: () => number = Date.now,
60
59
  ) {
61
60
  this.cache = new TtlCache(CACHE_TTL_MS, now);
62
61
  }
63
62
 
63
+ private get kbDirName(): string {
64
+ return this.kb.kbDirName;
65
+ }
66
+
64
67
  /** Attach the history source a `version` is answered from. */
65
68
  setHistory(history: SkillHistorySource): void {
66
69
  this.history = history;
@@ -92,7 +95,7 @@ export class SkillService implements ISkillService {
92
95
  const found = (await this.scan()).find((s) => s.summary.name === name);
93
96
  if (!found) return { ok: false, error: 'not_found' };
94
97
 
95
- const wsId = workspaceIdForBranch(DEFAULT_BRANCH);
98
+ const wsId = this.kb.defaultWorkspaceId();
96
99
  // Through `readable`, not a bare `canRead`: the two gates must never
97
100
  // disagree. `canRead` reads a file's own frontmatter rules off disk on
98
101
  // every call while `canReadBatch` resolves them through a per-workspace
@@ -213,7 +216,7 @@ export class SkillService implements ISkillService {
213
216
  */
214
217
  private async readable(userEmail: string, skillFolders: string[]): Promise<Map<string, boolean>> {
215
218
  return this.accessControl.canReadBatch(
216
- workspaceIdForBranch(DEFAULT_BRANCH),
219
+ this.kb.defaultWorkspaceId(),
217
220
  userEmail,
218
221
  skillFolders.map((p) => `${p}/SKILL.md`),
219
222
  );
@@ -238,7 +241,7 @@ export class SkillService implements ISkillService {
238
241
  // be read.
239
242
  let wsId: string;
240
243
  try {
241
- wsId = (await this.workspaceService.getOrCreateForBranch(DEFAULT_BRANCH)).id;
244
+ wsId = (await this.workspaceService.getOrCreateForBranch(this.kb.defaultBranch)).id;
242
245
  } catch {
243
246
  return [];
244
247
  }
@@ -314,15 +317,16 @@ export class SkillService implements ISkillService {
314
317
  // Each root starts its own ignore stack (the walk extends it with the
315
318
  // root's own file first). Order is cosmetic: the sort below is by name
316
319
  // then path, so a same-named pair resolves the same way regardless.
317
- await walkRoot(SKILLS_DIR);
318
- await walkRoot(PLUGINS_DIR);
320
+ const { skillsDir, pluginsDir } = this.kb.layout;
321
+ await walkRoot(skillsDir);
322
+ await walkRoot(pluginsDir);
319
323
  // A skill's id (frontmatter `id`/`name`, else folder name) is how getSkill()
320
324
  // resolves it, so it must be unique. Sort by (name, root, path) for a
321
325
  // deterministic winner — the shared root FIRST, since `Skills/` is a
322
326
  // skill's canonical home and a same-named inline copy is the stale one —
323
327
  // then REFUSE later duplicates via the shared dedup — the same rule tools
324
328
  // use (no silent auto-suffix that would rebind an id under the caller).
325
- const rootRank = (p: string) => (p === SKILLS_DIR || p.startsWith(`${SKILLS_DIR}/`) ? 0 : 1);
329
+ const rootRank = (p: string) => (p === skillsDir || p.startsWith(`${skillsDir}/`) ? 0 : 1);
326
330
  out.sort(
327
331
  (a, b) =>
328
332
  a.summary.name.localeCompare(b.summary.name) ||
@@ -16,6 +16,7 @@ import { SpillStore } from '../../workspace/spill-store.js';
16
16
  import { DocExtractService } from '../../workspace/file-readers/doc-extract.service.js';
17
17
  import { NEW_ROLE_GUIDANCE } from '../../access-model/roles-yaml-guard.js';
18
18
  import { loadActiveGroups } from '../../access/access-control.service.js';
19
+ import { testKbContext } from '../../../__tests__/kb-context.js';
19
20
 
20
21
  /**
21
22
  * The agent's file tools over the production context resolver and a real
@@ -68,10 +69,10 @@ async function start(): Promise<string> {
68
69
  canWriteBatchAtRef: async () => null,
69
70
  canReadBatch: async (_w: string, _u: string, paths: string[]) => new Map(paths.map((p) => [p, true])),
70
71
  } as never;
71
- registerWorkspaceTools(registry, router, toolAuth, createToolHandlerFactory(resolve), new SpillStore(path.join(os.tmpdir(), 'bevel-test-spills')), new DocExtractService(docCache), allowAll, KB, {
72
+ registerWorkspaceTools(registry, router, toolAuth, createToolHandlerFactory(resolve), new SpillStore(path.join(os.tmpdir(), 'bevel-test-spills')), new DocExtractService(docCache), allowAll, testKbContext({ kbDirName: KB }), {
72
73
  service: {} as never,
73
74
  enabled: false, // ontology boundary not under test here
74
- kbDirName: KB,
75
+ kb: testKbContext({ kbDirName: KB }),
75
76
  recoveryBotEmail: 'recovery-bot@bevel.local',
76
77
  hooks: new WorkflowHooks(),
77
78
  }, new RoutineWritePolicyService(), {} as never);
@@ -12,6 +12,7 @@ import { RoutineWritePolicyService } from '../../workspace/routine-write-policy.
12
12
  import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
13
13
  import { SpillStore } from '../../workspace/spill-store.js';
14
14
  import { DocExtractService } from '../../workspace/file-readers/doc-extract.service.js';
15
+ import { testKbContext } from '../../../__tests__/kb-context.js';
15
16
 
16
17
  const WS = 'target-company-state';
17
18
  let recorded: unknown[][] = [];
@@ -63,10 +64,10 @@ async function start(): Promise<string> {
63
64
  // kb (citation) tools alongside the workspace tools. Those registrations —
64
65
  // and their web_search / submit_feedback / cite_kb_node cases — moved to
65
66
  // the enterprise repo with their modules; core registers only core tools.
66
- registerWorkspaceTools(registry, router, toolAuth, th, new SpillStore('/tmp/bevel-test-spills'), new DocExtractService('/tmp/bevel-test-doc-extract'), accessControl, 'knowledge-base', {
67
+ registerWorkspaceTools(registry, router, toolAuth, th, new SpillStore('/tmp/bevel-test-spills'), new DocExtractService('/tmp/bevel-test-doc-extract'), accessControl, testKbContext(), {
67
68
  service: {} as never,
68
69
  enabled: false, // ontology boundary not under test here
69
- kbDirName: 'knowledge-base',
70
+ kb: testKbContext(),
70
71
  recoveryBotEmail: 'recovery-bot@bevel.local',
71
72
  hooks: new WorkflowHooks(),
72
73
  }, new RoutineWritePolicyService(), {} as never /* sessionSink — start_session not exercised here */);
@@ -12,6 +12,7 @@ import type { ICreatorAccess } from '../access-model/creator.js';
12
12
  import type { GroupsIndex } from '../access-model/group-files.js';
13
13
  import type { WorkspaceService } from '../workspace/workspace.service.js';
14
14
  import { isAbsence } from '../../shared/fs.contract.js';
15
+ import { assertBranchProvided } from '../../shared/domain-errors.js';
15
16
  import { branchForWorkspaceId } from '../../shared/workspace-id.js';
16
17
  import type { WorkflowEventBus } from '../workflow/event-bus.js';
17
18
  import type { AuthService } from '../auth/auth.service.js';
@@ -77,6 +78,20 @@ export function createToolContextResolver(deps: ToolContextDeps): ResolveToolCon
77
78
  const { loadActiveGroups } = deps;
78
79
  const fsCache = new Map<string, LocalFilesystem>();
79
80
  const getFilesystem = async (branch: string): Promise<LocalFilesystem> => {
81
+ // THE choke point: every knowledge-base tool resolves its workspace
82
+ // through here, and a `call_tool_chain` call reaches the very same route
83
+ // over loopback — so refusing a branch-less call here refuses it on both
84
+ // paths at once, with no per-tool guard to keep in step.
85
+ //
86
+ // Before ANY workspace work, because both things downstream do with this
87
+ // value are wrong when it is absent: `getOrCreateForUser` defaults a
88
+ // missing branch to the deployment's default (protected) branch, so an
89
+ // omitted argument would silently act on `main`; and a present-but-absent
90
+ // value like the string "undefined" goes to `workspaceIdForBranch`, which
91
+ // makes it a workspace directory of that name and then tries to clone a
92
+ // branch nobody ever pushed. Failing closed here means no workspace is
93
+ // created and no clone is attempted.
94
+ assertBranchProvided(branch);
80
95
  const cached = fsCache.get(branch);
81
96
  if (cached) return cached;
82
97
  const ws = await deps.workspaceService.getOrCreateForUser(user, branch);
@@ -1,8 +1,13 @@
1
1
  import { describe, expect, it, vi, afterEach } from 'vitest';
2
+ import { DEFAULT_KB_LAYOUT } from '@bevel-software/platform-shared';
2
3
  import { descriptorsFromMcpJson, judgeMcpServerEntry } from '../mcp-json-discovery.js';
3
4
 
4
5
  afterEach(() => vi.restoreAllMocks());
5
6
 
7
+ /** The reader under the default layout, which these cases are written against. */
8
+ const fromMcpJson = (folder: string, mcpJson: string, manifest: string | null) =>
9
+ descriptorsFromMcpJson(folder, mcpJson, manifest, DEFAULT_KB_LAYOUT);
10
+
6
11
  describe('judgeMcpServerEntry', () => {
7
12
  it('keeps every accepted header and env key — one spelled __proto__ included', () => {
8
13
  // Parsed from text, as a repository file is: JSON.parse makes `__proto__`
@@ -44,7 +49,7 @@ const MANIFEST = JSON.stringify({
44
49
 
45
50
  describe('descriptorsFromMcpJson', () => {
46
51
  it('synthesizes descriptors keyed by server name, path at mcp.json', () => {
47
- const out = descriptorsFromMcpJson(
52
+ const out = fromMcpJson(
48
53
  'GTM',
49
54
  JSON.stringify({ mcpServers: { notion: { type: 'streamable-http', url: 'https://mcp.notion.com/mcp' } } }),
50
55
  null,
@@ -63,7 +68,7 @@ describe('descriptorsFromMcpJson', () => {
63
68
  it('refuses an sse server rather than rebuilding it as a transport it is not', () => {
64
69
  // The pinned MCP client has no sse transport; emitting `http` for an sse
65
70
  // server configures a handshake the server does not speak.
66
- const out = descriptorsFromMcpJson(
71
+ const out = fromMcpJson(
67
72
  'GTM',
68
73
  JSON.stringify({ mcpServers: { legacy: { type: 'sse', url: 'https://mcp.legacy.example/sse' } } }),
69
74
  null,
@@ -72,7 +77,7 @@ describe('descriptorsFromMcpJson', () => {
72
77
  });
73
78
 
74
79
  it('merges extension auth over mcp.json literals and carries variables + description', () => {
75
- const out = descriptorsFromMcpJson(
80
+ const out = fromMcpJson(
76
81
  'GTM',
77
82
  JSON.stringify({
78
83
  mcpServers: { vendor: { type: 'streamable-http', url: 'https://v.example/mcp', headers: { 'X-V': '2' } } },
@@ -87,7 +92,7 @@ describe('descriptorsFromMcpJson', () => {
87
92
  });
88
93
 
89
94
  it('marks extension-flagged servers and every stdio server local-only', () => {
90
- const out = descriptorsFromMcpJson(
95
+ const out = fromMcpJson(
91
96
  'GTM',
92
97
  JSON.stringify({
93
98
  mcpServers: {
@@ -105,7 +110,7 @@ describe('descriptorsFromMcpJson', () => {
105
110
 
106
111
  it('skips a malformed entry without losing its siblings', () => {
107
112
  vi.spyOn(console, 'warn').mockImplementation(() => {});
108
- const out = descriptorsFromMcpJson(
113
+ const out = fromMcpJson(
109
114
  'GTM',
110
115
  JSON.stringify({
111
116
  mcpServers: {
@@ -123,7 +128,7 @@ describe('descriptorsFromMcpJson', () => {
123
128
  it('ignores malformed extension headers instead of spreading them into keys', () => {
124
129
  // A string spread into the merge would scatter its indices ('0', '1', …)
125
130
  // into header names; a malformed extension must cost its own data only.
126
- const out = descriptorsFromMcpJson(
131
+ const out = fromMcpJson(
127
132
  'GTM',
128
133
  JSON.stringify({
129
134
  mcpServers: { vendor: { type: 'streamable-http', url: 'https://v.example/mcp', headers: { 'X-V': '2' } } },
@@ -142,7 +147,7 @@ describe('descriptorsFromMcpJson', () => {
142
147
  // A dropped declaration would silently re-scope a credential (undeclared
143
148
  // defaults to the shared admin row), so a bad entry takes the SERVER
144
149
  // offline — never just the entry, and never its siblings.
145
- const out = descriptorsFromMcpJson(
150
+ const out = fromMcpJson(
146
151
  'GTM',
147
152
  JSON.stringify({
148
153
  mcpServers: {
@@ -165,7 +170,7 @@ describe('descriptorsFromMcpJson', () => {
165
170
  it('applies the .tool declaration rules: no reserved names, no duplicates, gated OAuth URLs, string authParams', () => {
166
171
  vi.spyOn(console, 'warn').mockImplementation(() => {});
167
172
  const declare = (variables: unknown) =>
168
- descriptorsFromMcpJson(
173
+ fromMcpJson(
169
174
  'GTM',
170
175
  JSON.stringify({ mcpServers: { vendor: { type: 'streamable-http', url: 'https://v.example/mcp' } } }),
171
176
  JSON.stringify({
@@ -197,7 +202,7 @@ describe('descriptorsFromMcpJson', () => {
197
202
  });
198
203
 
199
204
  it('trims a padded oauth clientId like the .tool parser does', () => {
200
- const out = descriptorsFromMcpJson(
205
+ const out = fromMcpJson(
201
206
  'GTM',
202
207
  JSON.stringify({ mcpServers: { vendor: { type: 'streamable-http', url: 'https://v.example/mcp' } } }),
203
208
  JSON.stringify({
@@ -225,7 +230,7 @@ describe('descriptorsFromMcpJson', () => {
225
230
  it('accepts a client-id-only sign-in (endpoints discovered later), refuses half a pair, carries pkce/resource', () => {
226
231
  vi.spyOn(console, 'warn').mockImplementation(() => {});
227
232
  const declare = (oauth: unknown) =>
228
- descriptorsFromMcpJson(
233
+ fromMcpJson(
229
234
  'GTM',
230
235
  JSON.stringify({ mcpServers: { vendor: { type: 'streamable-http', url: 'https://v.example/mcp' } } }),
231
236
  JSON.stringify({
@@ -262,9 +267,9 @@ describe('descriptorsFromMcpJson', () => {
262
267
 
263
268
  it('yields nothing for an unparsable file, quietly for an absent extensions block', () => {
264
269
  vi.spyOn(console, 'warn').mockImplementation(() => {});
265
- expect(descriptorsFromMcpJson('GTM', '{ not json', null)).toEqual([]);
270
+ expect(fromMcpJson('GTM', '{ not json', null)).toEqual([]);
266
271
  expect(
267
- descriptorsFromMcpJson('GTM', JSON.stringify({ mcpServers: {} }), '{ also not json'),
272
+ fromMcpJson('GTM', JSON.stringify({ mcpServers: {} }), '{ also not json'),
268
273
  ).toEqual([]);
269
274
  });
270
275
  });
@@ -9,6 +9,7 @@ import type { WorkspaceService } from '../../workspace/workspace.service.js';
9
9
  import type { IAccessControl } from '../../access/access-control.interface.js';
10
10
  import type { IToolManualService, ToolManualSummary } from '../tool-manuals.contract.js';
11
11
  import { McpServerEditService } from '../mcp-server-edit.service.js';
12
+ import { testKbContext } from '../../../__tests__/kb-context.js';
12
13
 
13
14
  const KB = 'knowledge-base';
14
15
  const USER: AuthUser = { id: 'u-1', email: 'ali@example.com', name: 'Ali' } as AuthUser;
@@ -77,7 +78,7 @@ beforeEach(async () => {
77
78
  }),
78
79
  } as unknown as IToolManualService;
79
80
 
80
- svc = new McpServerEditService(workspaceService, commits, accessControl, toolManuals, KB, new NodeFs());
81
+ svc = new McpServerEditService(workspaceService, commits, accessControl, toolManuals, testKbContext({ kbDirName: KB }), new NodeFs());
81
82
  });
82
83
 
83
84
  afterEach(async () => {
@@ -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 { IToolManualService, ToolManualSummary } from '../tool-manuals.contract.js';
8
+ import { testKbContext } from '../../../__tests__/kb-context.js';
8
9
 
9
10
  /**
10
11
  * The half of the tool catalog that is NOT on the default branch.
@@ -93,7 +94,7 @@ function harness(opts: {
93
94
  listChangeRequests: async () => opts.crs,
94
95
  } as unknown as IWorkflowService;
95
96
 
96
- return new PendingToolsService(workspaceService, accessControl, toolManuals, workflow);
97
+ return new PendingToolsService(workspaceService, accessControl, toolManuals, workflow, testKbContext());
97
98
  }
98
99
 
99
100
  const ADMIN_WRITES = { [TOOL_PATH]: [ADMIN] };
@@ -370,6 +371,7 @@ describe('PendingToolsService', () => {
370
371
  {} as unknown as IAccessControl,
371
372
  { listAllSummaries: async () => [] } as unknown as IToolManualService,
372
373
  workflow,
374
+ testKbContext(),
373
375
  );
374
376
  await expect(svc.listPendingTools(AUTHOR)).resolves.toEqual([]);
375
377
  });
@@ -384,6 +386,7 @@ describe('PendingToolsService', () => {
384
386
  },
385
387
  } as unknown as IToolManualService,
386
388
  { listChangeRequests: async () => [cr()] } as unknown as IWorkflowService,
389
+ testKbContext(),
387
390
  );
388
391
  await expect(svc.listPendingTools(AUTHOR)).resolves.toEqual([]);
389
392
  });
@@ -12,6 +12,7 @@ import type { IPluginIndexService, PluginCatalogEntry } from '../../plugins/plug
12
12
  import type { PluginSource, Discovery } from '../../plugins/discovery/plugin-source.js';
13
13
  import type { IToolManualService, ToolManualSummary } from '../tool-manuals.contract.js';
14
14
  import { ToolDeleteError, ToolDeleteService } from '../tool-delete.service.js';
15
+ import { testKbContext } from '../../../__tests__/kb-context.js';
15
16
 
16
17
  /**
17
18
  * Deleting one tool, over a real temp KB: the two shapes a tool comes in (a
@@ -147,7 +148,7 @@ function build(
147
148
  pluginIndex,
148
149
  opts.source ?? discovery([]),
149
150
  vault as never,
150
- KB,
151
+ testKbContext({ kbDirName: KB }),
151
152
  new NodeFs(),
152
153
  );
153
154
  }
@@ -11,6 +11,7 @@ import { workspaceIdForBranch } from '../../../shared/workspace-id.js';
11
11
  import type { WorkspaceService } from '../../workspace/workspace.service.js';
12
12
  import type { IAccessControl } from '../../access/access-control.interface.js';
13
13
  import type { IToolManualService } from '../tool-manuals.contract.js';
14
+ import { testKbContext } from '../../../__tests__/kb-context.js';
14
15
 
15
16
  /**
16
17
  * `GET /agent/plugins/:folder/archive` — error taxonomy of the plugin-folder
@@ -47,7 +48,7 @@ async function baseUrl(pluginIndex?: { catalog(): Promise<{ name: string; folder
47
48
  {} as unknown as IToolManualService,
48
49
  manualAuth,
49
50
  async () => 'ali@example.com',
50
- { workspaceService, accessControl, kbDirName: KB, disk: new NodeFs(), pluginIndex: pluginIndex as never },
51
+ { workspaceService, accessControl, kb: testKbContext({ kbDirName: KB }), disk: new NodeFs(), pluginIndex: pluginIndex as never },
51
52
  ),
52
53
  );
53
54
  httpServer = await new Promise<HttpServer>((resolve) => {
@@ -15,6 +15,7 @@ import { workspaceIdForBranch } from '../../../shared/workspace-id.js';
15
15
  import { utcpNamespacePrefix } from '../../../shared/utcp-namespace.js';
16
16
  import type { WorkspaceService } from '../../workspace/workspace.service.js';
17
17
  import type { IAccessControl } from '../../access/access-control.interface.js';
18
+ import { testKbContext } from '../../../__tests__/kb-context.js';
18
19
 
19
20
  const KB_DIR = 'knowledge-base';
20
21
  const wsId = workspaceIdForBranch(DEFAULT_BRANCH);
@@ -146,7 +147,7 @@ describe('a shell `.tool` in a workspace', () => {
146
147
  afterEach(() => rm(root, { recursive: true, force: true }));
147
148
 
148
149
  test('is listed to local consumers and withheld from remote ones', async () => {
149
- const svc = new ToolManualService(workspaceService, allowAll, KB_DIR, disk, new KbPluginSource(disk));
150
+ const svc = new ToolManualService(workspaceService, allowAll, testKbContext({ kbDirName: KB_DIR }), disk, new KbPluginSource(disk, testKbContext({ kbDirName: KB_DIR })));
150
151
  // `list_local_tools` names it, so the local server knows to materialize it.
151
152
  expect(await svc.listLocalOnly('user@x.eu')).toEqual([{ slug: 'git', name: 'git', path: 'Plugins/git.tool' }]);
152
153
  // The hosted proxy's manual set excludes it entirely.
@@ -157,7 +158,7 @@ describe('a shell `.tool` in a workspace', () => {
157
158
  test('its embedded cli tools survive manual serialization', async () => {
158
159
  // The whole point of registering the serializer: without it the manual body
159
160
  // fails validation and the local server gets nothing to run.
160
- const svc = new ToolManualService(workspaceService, allowAll, KB_DIR, disk, new KbPluginSource(disk));
161
+ const svc = new ToolManualService(workspaceService, allowAll, testKbContext({ kbDirName: KB_DIR }), disk, new KbPluginSource(disk, testKbContext({ kbDirName: KB_DIR })));
161
162
  const manual = await svc.resolveInlineManual('user@x.eu', 'git');
162
163
  expect(manual).not.toBeNull();
163
164
  const tools = (manual as { tools: { name: string; tool_call_template: { call_template_type: string } }[] }).tools;
@@ -206,7 +207,7 @@ describe('manual namespaces are unique, not merely manual names', () => {
206
207
  }
207
208
 
208
209
  const names = async (): Promise<string[]> =>
209
- (await new ToolManualService(workspaceService, allowAll, KB_DIR, disk, new KbPluginSource(disk)).listAllSummaries()).map((m) => m.name).sort();
210
+ (await new ToolManualService(workspaceService, allowAll, testKbContext({ kbDirName: KB_DIR }), disk, new KbPluginSource(disk, testKbContext({ kbDirName: KB_DIR }))).listAllSummaries()).map((m) => m.name).sort();
210
211
 
211
212
  it('keeps two manuals whose namespaces genuinely differ', async () => {
212
213
  // Underscore-doubling is injective, so `a_b` (a__b_) and `a__b` (a____b_)
@@ -243,7 +244,7 @@ describe('manual namespaces are unique, not merely manual names', () => {
243
244
  await writeMcpServer('Vendor', 'a-b');
244
245
  await writeTool('a.tool', 'a_b');
245
246
  await writeTool('c.tool', 'other');
246
- const kept = await new ToolManualService(workspaceService, allowAll, KB_DIR, disk, new KbPluginSource(disk)).listAllSummaries();
247
+ const kept = await new ToolManualService(workspaceService, allowAll, testKbContext({ kbDirName: KB_DIR }), disk, new KbPluginSource(disk, testKbContext({ kbDirName: KB_DIR }))).listAllSummaries();
247
248
  const namespaces = kept.map((m) => utcpNamespacePrefix(m.name));
248
249
  expect(new Set(namespaces).size).toBe(namespaces.length);
249
250
  });