@bevel-software/platform-core-backend 0.1.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 (720) hide show
  1. package/LICENSE +202 -0
  2. package/dist/assets.d.ts +5 -0
  3. package/dist/assets.d.ts.map +1 -0
  4. package/dist/assets.js +23 -0
  5. package/dist/assets.js.map +1 -0
  6. package/dist/core/core-ports.d.ts +83 -0
  7. package/dist/core/core-ports.d.ts.map +1 -0
  8. package/dist/core/core-ports.js +12 -0
  9. package/dist/core/core-ports.js.map +1 -0
  10. package/dist/core/create-core-server.d.ts +62 -0
  11. package/dist/core/create-core-server.d.ts.map +1 -0
  12. package/dist/core/create-core-server.js +204 -0
  13. package/dist/core/create-core-server.js.map +1 -0
  14. package/dist/core/create-core-services.d.ts +95 -0
  15. package/dist/core/create-core-services.d.ts.map +1 -0
  16. package/dist/core/create-core-services.js +352 -0
  17. package/dist/core/create-core-services.js.map +1 -0
  18. package/dist/core-config.d.ts +119 -0
  19. package/dist/core-config.d.ts.map +1 -0
  20. package/dist/core-config.js +240 -0
  21. package/dist/core-config.js.map +1 -0
  22. package/dist/index.d.ts +36 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +36 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/modules/access/access-control.interface.d.ts +348 -0
  27. package/dist/modules/access/access-control.interface.d.ts.map +1 -0
  28. package/dist/modules/access/access-control.interface.js +2 -0
  29. package/dist/modules/access/access-control.interface.js.map +1 -0
  30. package/dist/modules/access/access-control.service.d.ts +323 -0
  31. package/dist/modules/access/access-control.service.d.ts.map +1 -0
  32. package/dist/modules/access/access-control.service.js +1431 -0
  33. package/dist/modules/access/access-control.service.js.map +1 -0
  34. package/dist/modules/access/access-errors.d.ts +34 -0
  35. package/dist/modules/access/access-errors.d.ts.map +1 -0
  36. package/dist/modules/access/access-errors.js +40 -0
  37. package/dist/modules/access/access-errors.js.map +1 -0
  38. package/dist/modules/access/access-mutation.service.d.ts +176 -0
  39. package/dist/modules/access/access-mutation.service.d.ts.map +1 -0
  40. package/dist/modules/access/access-mutation.service.js +307 -0
  41. package/dist/modules/access/access-mutation.service.js.map +1 -0
  42. package/dist/modules/access/access-splice.d.ts +98 -0
  43. package/dist/modules/access/access-splice.d.ts.map +1 -0
  44. package/dist/modules/access/access-splice.js +346 -0
  45. package/dist/modules/access/access-splice.js.map +1 -0
  46. package/dist/modules/access/access.routes.d.ts +10 -0
  47. package/dist/modules/access/access.routes.d.ts.map +1 -0
  48. package/dist/modules/access/access.routes.js +757 -0
  49. package/dist/modules/access/access.routes.js.map +1 -0
  50. package/dist/modules/access/creator-access.d.ts +113 -0
  51. package/dist/modules/access/creator-access.d.ts.map +1 -0
  52. package/dist/modules/access/creator-access.js +212 -0
  53. package/dist/modules/access/creator-access.js.map +1 -0
  54. package/dist/modules/access/kb-read-filter.d.ts +41 -0
  55. package/dist/modules/access/kb-read-filter.d.ts.map +1 -0
  56. package/dist/modules/access/kb-read-filter.js +60 -0
  57. package/dist/modules/access/kb-read-filter.js.map +1 -0
  58. package/dist/modules/access/roles-admin.service.d.ts +240 -0
  59. package/dist/modules/access/roles-admin.service.d.ts.map +1 -0
  60. package/dist/modules/access/roles-admin.service.js +630 -0
  61. package/dist/modules/access/roles-admin.service.js.map +1 -0
  62. package/dist/modules/access/roles-edit.d.ts +91 -0
  63. package/dist/modules/access/roles-edit.d.ts.map +1 -0
  64. package/dist/modules/access/roles-edit.js +232 -0
  65. package/dist/modules/access/roles-edit.js.map +1 -0
  66. package/dist/modules/access/roles-yaml-guard.d.ts +56 -0
  67. package/dist/modules/access/roles-yaml-guard.d.ts.map +1 -0
  68. package/dist/modules/access/roles-yaml-guard.js +79 -0
  69. package/dist/modules/access/roles-yaml-guard.js.map +1 -0
  70. package/dist/modules/admin/admin-access.routes.d.ts +18 -0
  71. package/dist/modules/admin/admin-access.routes.d.ts.map +1 -0
  72. package/dist/modules/admin/admin-access.routes.js +26 -0
  73. package/dist/modules/admin/admin-access.routes.js.map +1 -0
  74. package/dist/modules/admin/admin-access.service.d.ts +24 -0
  75. package/dist/modules/admin/admin-access.service.d.ts.map +1 -0
  76. package/dist/modules/admin/admin-access.service.js +41 -0
  77. package/dist/modules/admin/admin-access.service.js.map +1 -0
  78. package/dist/modules/admin/admin.interface.d.ts +11 -0
  79. package/dist/modules/admin/admin.interface.d.ts.map +1 -0
  80. package/dist/modules/admin/admin.interface.js +2 -0
  81. package/dist/modules/admin/admin.interface.js.map +1 -0
  82. package/dist/modules/auth/account-erasure.service.d.ts +80 -0
  83. package/dist/modules/auth/account-erasure.service.d.ts.map +1 -0
  84. package/dist/modules/auth/account-erasure.service.js +91 -0
  85. package/dist/modules/auth/account-erasure.service.js.map +1 -0
  86. package/dist/modules/auth/auth.middleware.d.ts +23 -0
  87. package/dist/modules/auth/auth.middleware.d.ts.map +1 -0
  88. package/dist/modules/auth/auth.middleware.js +68 -0
  89. package/dist/modules/auth/auth.middleware.js.map +1 -0
  90. package/dist/modules/auth/auth.routes.d.ts +25 -0
  91. package/dist/modules/auth/auth.routes.d.ts.map +1 -0
  92. package/dist/modules/auth/auth.routes.js +72 -0
  93. package/dist/modules/auth/auth.routes.js.map +1 -0
  94. package/dist/modules/auth/auth.service.d.ts +76 -0
  95. package/dist/modules/auth/auth.service.d.ts.map +1 -0
  96. package/dist/modules/auth/auth.service.js +168 -0
  97. package/dist/modules/auth/auth.service.js.map +1 -0
  98. package/dist/modules/code-mode/code-mode-names.d.ts +16 -0
  99. package/dist/modules/code-mode/code-mode-names.d.ts.map +1 -0
  100. package/dist/modules/code-mode/code-mode-names.js +30 -0
  101. package/dist/modules/code-mode/code-mode-names.js.map +1 -0
  102. package/dist/modules/code-mode/code-mode.tool.d.ts +13 -0
  103. package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -0
  104. package/dist/modules/code-mode/code-mode.tool.js +112 -0
  105. package/dist/modules/code-mode/code-mode.tool.js.map +1 -0
  106. package/dist/modules/code-mode/index.d.ts +3 -0
  107. package/dist/modules/code-mode/index.d.ts.map +1 -0
  108. package/dist/modules/code-mode/index.js +3 -0
  109. package/dist/modules/code-mode/index.js.map +1 -0
  110. package/dist/modules/database/connection.d.ts +6 -0
  111. package/dist/modules/database/connection.d.ts.map +1 -0
  112. package/dist/modules/database/connection.js +12 -0
  113. package/dist/modules/database/connection.js.map +1 -0
  114. package/dist/modules/database/core-schema.d.ts +2273 -0
  115. package/dist/modules/database/core-schema.d.ts.map +1 -0
  116. package/dist/modules/database/core-schema.js +413 -0
  117. package/dist/modules/database/core-schema.js.map +1 -0
  118. package/dist/modules/database/migrate.d.ts +10 -0
  119. package/dist/modules/database/migrate.d.ts.map +1 -0
  120. package/dist/modules/database/migrate.js +40 -0
  121. package/dist/modules/database/migrate.js.map +1 -0
  122. package/dist/modules/database/schema.d.ts +12 -0
  123. package/dist/modules/database/schema.d.ts.map +1 -0
  124. package/dist/modules/database/schema.js +12 -0
  125. package/dist/modules/database/schema.js.map +1 -0
  126. package/dist/modules/diff/diff-paths.d.ts +2 -0
  127. package/dist/modules/diff/diff-paths.d.ts.map +1 -0
  128. package/dist/modules/diff/diff-paths.js +9 -0
  129. package/dist/modules/diff/diff-paths.js.map +1 -0
  130. package/dist/modules/diff/diff.config.d.ts +8 -0
  131. package/dist/modules/diff/diff.config.d.ts.map +1 -0
  132. package/dist/modules/diff/diff.config.js +13 -0
  133. package/dist/modules/diff/diff.config.js.map +1 -0
  134. package/dist/modules/diff/diff.interface.d.ts +73 -0
  135. package/dist/modules/diff/diff.interface.d.ts.map +1 -0
  136. package/dist/modules/diff/diff.interface.js +2 -0
  137. package/dist/modules/diff/diff.interface.js.map +1 -0
  138. package/dist/modules/diff/diff.routes.d.ts +35 -0
  139. package/dist/modules/diff/diff.routes.d.ts.map +1 -0
  140. package/dist/modules/diff/diff.routes.js +228 -0
  141. package/dist/modules/diff/diff.routes.js.map +1 -0
  142. package/dist/modules/diff/diff.service.d.ts +51 -0
  143. package/dist/modules/diff/diff.service.d.ts.map +1 -0
  144. package/dist/modules/diff/diff.service.js +489 -0
  145. package/dist/modules/diff/diff.service.js.map +1 -0
  146. package/dist/modules/diff/line-diff.d.ts +16 -0
  147. package/dist/modules/diff/line-diff.d.ts.map +1 -0
  148. package/dist/modules/diff/line-diff.js +67 -0
  149. package/dist/modules/diff/line-diff.js.map +1 -0
  150. package/dist/modules/mcp/mcp-auth.middleware.d.ts +27 -0
  151. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -0
  152. package/dist/modules/mcp/mcp-auth.middleware.js +116 -0
  153. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -0
  154. package/dist/modules/mcp/mcp-session-store.d.ts +74 -0
  155. package/dist/modules/mcp/mcp-session-store.d.ts.map +1 -0
  156. package/dist/modules/mcp/mcp-session-store.js +131 -0
  157. package/dist/modules/mcp/mcp-session-store.js.map +1 -0
  158. package/dist/modules/mcp/mcp.routes.d.ts +24 -0
  159. package/dist/modules/mcp/mcp.routes.d.ts.map +1 -0
  160. package/dist/modules/mcp/mcp.routes.js +229 -0
  161. package/dist/modules/mcp/mcp.routes.js.map +1 -0
  162. package/dist/modules/mcp/mcp.service.d.ts +198 -0
  163. package/dist/modules/mcp/mcp.service.d.ts.map +1 -0
  164. package/dist/modules/mcp/mcp.service.js +840 -0
  165. package/dist/modules/mcp/mcp.service.js.map +1 -0
  166. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +76 -0
  167. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -0
  168. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +291 -0
  169. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -0
  170. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +18 -0
  171. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -0
  172. package/dist/modules/mcp/oauth/oauth-consent.routes.js +52 -0
  173. package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -0
  174. package/dist/modules/mcp/oauth/oauth-state.d.ts +32 -0
  175. package/dist/modules/mcp/oauth/oauth-state.d.ts.map +1 -0
  176. package/dist/modules/mcp/oauth/oauth-state.js +34 -0
  177. package/dist/modules/mcp/oauth/oauth-state.js.map +1 -0
  178. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts +92 -0
  179. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts.map +1 -0
  180. package/dist/modules/secrets-vault/db-secrets-vault.service.js +728 -0
  181. package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -0
  182. package/dist/modules/secrets-vault/index.d.ts +7 -0
  183. package/dist/modules/secrets-vault/index.d.ts.map +1 -0
  184. package/dist/modules/secrets-vault/index.js +6 -0
  185. package/dist/modules/secrets-vault/index.js.map +1 -0
  186. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.d.ts +63 -0
  187. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.d.ts.map +1 -0
  188. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.js +269 -0
  189. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.js.map +1 -0
  190. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts +46 -0
  191. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts.map +1 -0
  192. package/dist/modules/secrets-vault/secrets-variable-loader.js +87 -0
  193. package/dist/modules/secrets-vault/secrets-variable-loader.js.map +1 -0
  194. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts +210 -0
  195. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts.map +1 -0
  196. package/dist/modules/secrets-vault/secrets-vault.contract.js +90 -0
  197. package/dist/modules/secrets-vault/secrets-vault.contract.js.map +1 -0
  198. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +30 -0
  199. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -0
  200. package/dist/modules/secrets-vault/secrets-vault.routes.js +490 -0
  201. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -0
  202. package/dist/modules/skills/index.d.ts +5 -0
  203. package/dist/modules/skills/index.d.ts.map +1 -0
  204. package/dist/modules/skills/index.js +4 -0
  205. package/dist/modules/skills/index.js.map +1 -0
  206. package/dist/modules/skills/skills.contract.d.ts +58 -0
  207. package/dist/modules/skills/skills.contract.d.ts.map +1 -0
  208. package/dist/modules/skills/skills.contract.js +10 -0
  209. package/dist/modules/skills/skills.contract.js.map +1 -0
  210. package/dist/modules/skills/skills.routes.d.ts +15 -0
  211. package/dist/modules/skills/skills.routes.d.ts.map +1 -0
  212. package/dist/modules/skills/skills.routes.js +34 -0
  213. package/dist/modules/skills/skills.routes.js.map +1 -0
  214. package/dist/modules/skills/skills.service.d.ts +21 -0
  215. package/dist/modules/skills/skills.service.d.ts.map +1 -0
  216. package/dist/modules/skills/skills.service.js +202 -0
  217. package/dist/modules/skills/skills.service.js.map +1 -0
  218. package/dist/modules/skills/skills.tools.d.ts +15 -0
  219. package/dist/modules/skills/skills.tools.d.ts.map +1 -0
  220. package/dist/modules/skills/skills.tools.js +96 -0
  221. package/dist/modules/skills/skills.tools.js.map +1 -0
  222. package/dist/modules/tool-auth/external-api-key.errors.d.ts +14 -0
  223. package/dist/modules/tool-auth/external-api-key.errors.d.ts.map +1 -0
  224. package/dist/modules/tool-auth/external-api-key.errors.js +23 -0
  225. package/dist/modules/tool-auth/external-api-key.errors.js.map +1 -0
  226. package/dist/modules/tool-auth/external-api-key.interface.d.ts +90 -0
  227. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -0
  228. package/dist/modules/tool-auth/external-api-key.interface.js +2 -0
  229. package/dist/modules/tool-auth/external-api-key.interface.js.map +1 -0
  230. package/dist/modules/tool-auth/external-api-key.service.d.ts +25 -0
  231. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -0
  232. package/dist/modules/tool-auth/external-api-key.service.js +164 -0
  233. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -0
  234. package/dist/modules/tool-auth/internal-token.service.d.ts +62 -0
  235. package/dist/modules/tool-auth/internal-token.service.d.ts.map +1 -0
  236. package/dist/modules/tool-auth/internal-token.service.js +85 -0
  237. package/dist/modules/tool-auth/internal-token.service.js.map +1 -0
  238. package/dist/modules/tool-auth/llm-usage-meter.d.ts +16 -0
  239. package/dist/modules/tool-auth/llm-usage-meter.d.ts.map +1 -0
  240. package/dist/modules/tool-auth/llm-usage-meter.js +6 -0
  241. package/dist/modules/tool-auth/llm-usage-meter.js.map +1 -0
  242. package/dist/modules/tool-auth/tool-auth.middleware.d.ts +101 -0
  243. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -0
  244. package/dist/modules/tool-auth/tool-auth.middleware.js +166 -0
  245. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -0
  246. package/dist/modules/tool-helpers/index.d.ts +19 -0
  247. package/dist/modules/tool-helpers/index.d.ts.map +1 -0
  248. package/dist/modules/tool-helpers/index.js +18 -0
  249. package/dist/modules/tool-helpers/index.js.map +1 -0
  250. package/dist/modules/tool-helpers/tool-context.d.ts +35 -0
  251. package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -0
  252. package/dist/modules/tool-helpers/tool-context.js +66 -0
  253. package/dist/modules/tool-helpers/tool-context.js.map +1 -0
  254. package/dist/modules/tool-helpers/tool-def.d.ts +33 -0
  255. package/dist/modules/tool-helpers/tool-def.d.ts.map +1 -0
  256. package/dist/modules/tool-helpers/tool-def.js +57 -0
  257. package/dist/modules/tool-helpers/tool-def.js.map +1 -0
  258. package/dist/modules/tool-helpers/tool-handler.d.ts +19 -0
  259. package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -0
  260. package/dist/modules/tool-helpers/tool-handler.js +84 -0
  261. package/dist/modules/tool-helpers/tool-handler.js.map +1 -0
  262. package/dist/modules/tool-helpers/tool.contract.d.ts +64 -0
  263. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -0
  264. package/dist/modules/tool-helpers/tool.contract.js +24 -0
  265. package/dist/modules/tool-helpers/tool.contract.js.map +1 -0
  266. package/dist/modules/tool-helpers/validate-token.d.ts +31 -0
  267. package/dist/modules/tool-helpers/validate-token.d.ts.map +1 -0
  268. package/dist/modules/tool-helpers/validate-token.js +20 -0
  269. package/dist/modules/tool-helpers/validate-token.js.map +1 -0
  270. package/dist/modules/tool-manuals/index.d.ts +5 -0
  271. package/dist/modules/tool-manuals/index.d.ts.map +1 -0
  272. package/dist/modules/tool-manuals/index.js +5 -0
  273. package/dist/modules/tool-manuals/index.js.map +1 -0
  274. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +182 -0
  275. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -0
  276. package/dist/modules/tool-manuals/tool-manuals.contract.js +19 -0
  277. package/dist/modules/tool-manuals/tool-manuals.contract.js.map +1 -0
  278. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +24 -0
  279. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -0
  280. package/dist/modules/tool-manuals/tool-manuals.routes.js +102 -0
  281. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -0
  282. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +108 -0
  283. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -0
  284. package/dist/modules/tool-manuals/tool-manuals.service.js +710 -0
  285. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -0
  286. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +35 -0
  287. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -0
  288. package/dist/modules/tool-manuals/tool-manuals.tools.js +157 -0
  289. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -0
  290. package/dist/modules/tool-registry/manual.routes.d.ts +6 -0
  291. package/dist/modules/tool-registry/manual.routes.d.ts.map +1 -0
  292. package/dist/modules/tool-registry/manual.routes.js +76 -0
  293. package/dist/modules/tool-registry/manual.routes.js.map +1 -0
  294. package/dist/modules/tool-registry/tool-registry.d.ts +23 -0
  295. package/dist/modules/tool-registry/tool-registry.d.ts.map +1 -0
  296. package/dist/modules/tool-registry/tool-registry.js +46 -0
  297. package/dist/modules/tool-registry/tool-registry.js.map +1 -0
  298. package/dist/modules/tool-registry/tool.contract.d.ts +48 -0
  299. package/dist/modules/tool-registry/tool.contract.d.ts.map +1 -0
  300. package/dist/modules/tool-registry/tool.contract.js +2 -0
  301. package/dist/modules/tool-registry/tool.contract.js.map +1 -0
  302. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +14 -0
  303. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -0
  304. package/dist/modules/workflow/agent-tools/workflow.tools.js +437 -0
  305. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -0
  306. package/dist/modules/workflow/event-bus.d.ts +107 -0
  307. package/dist/modules/workflow/event-bus.d.ts.map +1 -0
  308. package/dist/modules/workflow/event-bus.js +224 -0
  309. package/dist/modules/workflow/event-bus.js.map +1 -0
  310. package/dist/modules/workflow/events.routes.d.ts +80 -0
  311. package/dist/modules/workflow/events.routes.d.ts.map +1 -0
  312. package/dist/modules/workflow/events.routes.js +216 -0
  313. package/dist/modules/workflow/events.routes.js.map +1 -0
  314. package/dist/modules/workflow/file-change-notifier.d.ts +38 -0
  315. package/dist/modules/workflow/file-change-notifier.d.ts.map +1 -0
  316. package/dist/modules/workflow/file-change-notifier.js +22 -0
  317. package/dist/modules/workflow/file-change-notifier.js.map +1 -0
  318. package/dist/modules/workflow/file-lock.service.d.ts +57 -0
  319. package/dist/modules/workflow/file-lock.service.d.ts.map +1 -0
  320. package/dist/modules/workflow/file-lock.service.js +202 -0
  321. package/dist/modules/workflow/file-lock.service.js.map +1 -0
  322. package/dist/modules/workflow/git/branch-name.d.ts +10 -0
  323. package/dist/modules/workflow/git/branch-name.d.ts.map +1 -0
  324. package/dist/modules/workflow/git/branch-name.js +76 -0
  325. package/dist/modules/workflow/git/branch-name.js.map +1 -0
  326. package/dist/modules/workflow/git/clone-config.d.ts +61 -0
  327. package/dist/modules/workflow/git/clone-config.d.ts.map +1 -0
  328. package/dist/modules/workflow/git/clone-config.js +69 -0
  329. package/dist/modules/workflow/git/clone-config.js.map +1 -0
  330. package/dist/modules/workflow/git/git-version.d.ts +34 -0
  331. package/dist/modules/workflow/git/git-version.d.ts.map +1 -0
  332. package/dist/modules/workflow/git/git-version.js +63 -0
  333. package/dist/modules/workflow/git/git-version.js.map +1 -0
  334. package/dist/modules/workflow/git/git.service.d.ts +427 -0
  335. package/dist/modules/workflow/git/git.service.d.ts.map +1 -0
  336. package/dist/modules/workflow/git/git.service.js +1987 -0
  337. package/dist/modules/workflow/git/git.service.js.map +1 -0
  338. package/dist/modules/workflow/git/mutex.d.ts +11 -0
  339. package/dist/modules/workflow/git/mutex.d.ts.map +1 -0
  340. package/dist/modules/workflow/git/mutex.js +23 -0
  341. package/dist/modules/workflow/git/mutex.js.map +1 -0
  342. package/dist/modules/workflow/git/pull-request.service.d.ts +124 -0
  343. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -0
  344. package/dist/modules/workflow/git/pull-request.service.js +328 -0
  345. package/dist/modules/workflow/git/pull-request.service.js.map +1 -0
  346. package/dist/modules/workflow/locking-filesystem.d.ts +133 -0
  347. package/dist/modules/workflow/locking-filesystem.d.ts.map +1 -0
  348. package/dist/modules/workflow/locking-filesystem.js +400 -0
  349. package/dist/modules/workflow/locking-filesystem.js.map +1 -0
  350. package/dist/modules/workflow/pending-commits.service.d.ts +221 -0
  351. package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -0
  352. package/dist/modules/workflow/pending-commits.service.js +364 -0
  353. package/dist/modules/workflow/pending-commits.service.js.map +1 -0
  354. package/dist/modules/workflow/pending-commits.worker.d.ts +148 -0
  355. package/dist/modules/workflow/pending-commits.worker.d.ts.map +1 -0
  356. package/dist/modules/workflow/pending-commits.worker.js +245 -0
  357. package/dist/modules/workflow/pending-commits.worker.js.map +1 -0
  358. package/dist/modules/workflow/read-only-filesystem.d.ts +24 -0
  359. package/dist/modules/workflow/read-only-filesystem.d.ts.map +1 -0
  360. package/dist/modules/workflow/read-only-filesystem.js +39 -0
  361. package/dist/modules/workflow/read-only-filesystem.js.map +1 -0
  362. package/dist/modules/workflow/recovery-bot.d.ts +31 -0
  363. package/dist/modules/workflow/recovery-bot.d.ts.map +1 -0
  364. package/dist/modules/workflow/recovery-bot.js +64 -0
  365. package/dist/modules/workflow/recovery-bot.js.map +1 -0
  366. package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts +137 -0
  367. package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts.map +1 -0
  368. package/dist/modules/workflow/review-workflow/review-workflow.interface.js +2 -0
  369. package/dist/modules/workflow/review-workflow/review-workflow.interface.js.map +1 -0
  370. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts +26 -0
  371. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -0
  372. package/dist/modules/workflow/review-workflow/review-workflow.service.js +636 -0
  373. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -0
  374. package/dist/modules/workflow/sanitize-error.d.ts +29 -0
  375. package/dist/modules/workflow/sanitize-error.d.ts.map +1 -0
  376. package/dist/modules/workflow/sanitize-error.js +60 -0
  377. package/dist/modules/workflow/sanitize-error.js.map +1 -0
  378. package/dist/modules/workflow/session-ontology.policy.d.ts +52 -0
  379. package/dist/modules/workflow/session-ontology.policy.d.ts.map +1 -0
  380. package/dist/modules/workflow/session-ontology.policy.js +62 -0
  381. package/dist/modules/workflow/session-ontology.policy.js.map +1 -0
  382. package/dist/modules/workflow/session-ontology.service.d.ts +100 -0
  383. package/dist/modules/workflow/session-ontology.service.d.ts.map +1 -0
  384. package/dist/modules/workflow/session-ontology.service.js +143 -0
  385. package/dist/modules/workflow/session-ontology.service.js.map +1 -0
  386. package/dist/modules/workflow/workflow-hooks.d.ts +87 -0
  387. package/dist/modules/workflow/workflow-hooks.d.ts.map +1 -0
  388. package/dist/modules/workflow/workflow-hooks.js +35 -0
  389. package/dist/modules/workflow/workflow-hooks.js.map +1 -0
  390. package/dist/modules/workflow/workflow.errors.d.ts +171 -0
  391. package/dist/modules/workflow/workflow.errors.d.ts.map +1 -0
  392. package/dist/modules/workflow/workflow.errors.js +260 -0
  393. package/dist/modules/workflow/workflow.errors.js.map +1 -0
  394. package/dist/modules/workflow/workflow.routes.d.ts +26 -0
  395. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -0
  396. package/dist/modules/workflow/workflow.routes.js +804 -0
  397. package/dist/modules/workflow/workflow.routes.js.map +1 -0
  398. package/dist/modules/workflow/workflow.service.d.ts +385 -0
  399. package/dist/modules/workflow/workflow.service.d.ts.map +1 -0
  400. package/dist/modules/workflow/workflow.service.js +1155 -0
  401. package/dist/modules/workflow/workflow.service.js.map +1 -0
  402. package/dist/modules/workspace/bevel-ignore.d.ts +25 -0
  403. package/dist/modules/workspace/bevel-ignore.d.ts.map +1 -0
  404. package/dist/modules/workspace/bevel-ignore.js +57 -0
  405. package/dist/modules/workspace/bevel-ignore.js.map +1 -0
  406. package/dist/modules/workspace/kb-seed.interface.d.ts +36 -0
  407. package/dist/modules/workspace/kb-seed.interface.d.ts.map +1 -0
  408. package/dist/modules/workspace/kb-seed.interface.js +2 -0
  409. package/dist/modules/workspace/kb-seed.interface.js.map +1 -0
  410. package/dist/modules/workspace/kb-seed.service.d.ts +70 -0
  411. package/dist/modules/workspace/kb-seed.service.d.ts.map +1 -0
  412. package/dist/modules/workspace/kb-seed.service.js +325 -0
  413. package/dist/modules/workspace/kb-seed.service.js.map +1 -0
  414. package/dist/modules/workspace/routine-write-policy.d.ts +49 -0
  415. package/dist/modules/workspace/routine-write-policy.d.ts.map +1 -0
  416. package/dist/modules/workspace/routine-write-policy.js +46 -0
  417. package/dist/modules/workspace/routine-write-policy.js.map +1 -0
  418. package/dist/modules/workspace/session-ontology.gate.d.ts +112 -0
  419. package/dist/modules/workspace/session-ontology.gate.d.ts.map +1 -0
  420. package/dist/modules/workspace/session-ontology.gate.js +161 -0
  421. package/dist/modules/workspace/session-ontology.gate.js.map +1 -0
  422. package/dist/modules/workspace/session-sink.d.ts +25 -0
  423. package/dist/modules/workspace/session-sink.d.ts.map +1 -0
  424. package/dist/modules/workspace/session-sink.js +8 -0
  425. package/dist/modules/workspace/session-sink.js.map +1 -0
  426. package/dist/modules/workspace/spill-store.d.ts +24 -0
  427. package/dist/modules/workspace/spill-store.d.ts.map +1 -0
  428. package/dist/modules/workspace/spill-store.js +87 -0
  429. package/dist/modules/workspace/spill-store.js.map +1 -0
  430. package/dist/modules/workspace/workspace.routes.d.ts +25 -0
  431. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -0
  432. package/dist/modules/workspace/workspace.routes.js +1046 -0
  433. package/dist/modules/workspace/workspace.routes.js.map +1 -0
  434. package/dist/modules/workspace/workspace.service.d.ts +339 -0
  435. package/dist/modules/workspace/workspace.service.d.ts.map +1 -0
  436. package/dist/modules/workspace/workspace.service.js +1221 -0
  437. package/dist/modules/workspace/workspace.service.js.map +1 -0
  438. package/dist/modules/workspace/workspace.tools.d.ts +19 -0
  439. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -0
  440. package/dist/modules/workspace/workspace.tools.js +767 -0
  441. package/dist/modules/workspace/workspace.tools.js.map +1 -0
  442. package/dist/shared/frontmatter-id.d.ts +35 -0
  443. package/dist/shared/frontmatter-id.d.ts.map +1 -0
  444. package/dist/shared/frontmatter-id.js +68 -0
  445. package/dist/shared/frontmatter-id.js.map +1 -0
  446. package/dist/shared/fs-walk.d.ts +9 -0
  447. package/dist/shared/fs-walk.d.ts.map +1 -0
  448. package/dist/shared/fs-walk.js +34 -0
  449. package/dist/shared/fs-walk.js.map +1 -0
  450. package/dist/shared/hash-email.d.ts +11 -0
  451. package/dist/shared/hash-email.d.ts.map +1 -0
  452. package/dist/shared/hash-email.js +14 -0
  453. package/dist/shared/hash-email.js.map +1 -0
  454. package/dist/shared/kb-layout.d.ts +38 -0
  455. package/dist/shared/kb-layout.d.ts.map +1 -0
  456. package/dist/shared/kb-layout.js +102 -0
  457. package/dist/shared/kb-layout.js.map +1 -0
  458. package/dist/shared/kb-layout.test.d.ts +2 -0
  459. package/dist/shared/kb-layout.test.d.ts.map +1 -0
  460. package/dist/shared/kb-layout.test.js +67 -0
  461. package/dist/shared/kb-layout.test.js.map +1 -0
  462. package/dist/shared/ssrf.d.ts +20 -0
  463. package/dist/shared/ssrf.d.ts.map +1 -0
  464. package/dist/shared/ssrf.js +89 -0
  465. package/dist/shared/ssrf.js.map +1 -0
  466. package/dist/shared/token-crypto.d.ts +16 -0
  467. package/dist/shared/token-crypto.d.ts.map +1 -0
  468. package/dist/shared/token-crypto.js +49 -0
  469. package/dist/shared/token-crypto.js.map +1 -0
  470. package/dist/shared/ttl-cache.d.ts +16 -0
  471. package/dist/shared/ttl-cache.d.ts.map +1 -0
  472. package/dist/shared/ttl-cache.js +27 -0
  473. package/dist/shared/ttl-cache.js.map +1 -0
  474. package/dist/shared/utcp-namespace.d.ts +46 -0
  475. package/dist/shared/utcp-namespace.d.ts.map +1 -0
  476. package/dist/shared/utcp-namespace.js +82 -0
  477. package/dist/shared/utcp-namespace.js.map +1 -0
  478. package/dist/version.d.ts +17 -0
  479. package/dist/version.d.ts.map +1 -0
  480. package/dist/version.js +19 -0
  481. package/dist/version.js.map +1 -0
  482. package/kb-template/.bevelignore +21 -0
  483. package/kb-template/Agents/.gitkeep +0 -0
  484. package/kb-template/Agents/README.md +38 -0
  485. package/kb-template/CLAUDE.md +419 -0
  486. package/kb-template/Data/.gitkeep +0 -0
  487. package/kb-template/Data/README.md +39 -0
  488. package/kb-template/KnowledgeBase/.gitkeep +0 -0
  489. package/kb-template/KnowledgeBase/README.md +37 -0
  490. package/kb-template/Pipelines/.gitkeep +0 -0
  491. package/kb-template/Pipelines/README.md +38 -0
  492. package/kb-template/Skills/.gitkeep +0 -0
  493. package/kb-template/Skills/README.md +32 -0
  494. package/kb-template/Tools/.gitkeep +0 -0
  495. package/kb-template/Tools/README.md +42 -0
  496. package/kb-template/access.md +36 -0
  497. package/migrations/0000_core_init.sql +243 -0
  498. package/migrations/meta/0000_snapshot.json +1480 -0
  499. package/migrations/meta/_journal.json +13 -0
  500. package/package.json +80 -0
  501. package/src/assets.ts +25 -0
  502. package/src/core/core-ports.ts +91 -0
  503. package/src/core/create-core-server.ts +338 -0
  504. package/src/core/create-core-services.ts +501 -0
  505. package/src/core-config.ts +257 -0
  506. package/src/index.ts +69 -0
  507. package/src/modules/access/__tests__/access-control.atref-batch.test.ts +98 -0
  508. package/src/modules/access/__tests__/access-control.read-batch.test.ts +132 -0
  509. package/src/modules/access/__tests__/access-control.service.test.ts +1011 -0
  510. package/src/modules/access/__tests__/access-mutation.service.test.ts +439 -0
  511. package/src/modules/access/__tests__/access-splice.test.ts +247 -0
  512. package/src/modules/access/__tests__/access.routes.revoke.test.ts +407 -0
  513. package/src/modules/access/__tests__/creator-access.test.ts +217 -0
  514. package/src/modules/access/__tests__/grant-sources.test.ts +204 -0
  515. package/src/modules/access/__tests__/kb-read-filter.test.ts +70 -0
  516. package/src/modules/access/__tests__/roles-admin.service.test.ts +469 -0
  517. package/src/modules/access/__tests__/roles-edit.test.ts +138 -0
  518. package/src/modules/access/__tests__/roles-yaml-guard.test.ts +70 -0
  519. package/src/modules/access/__tests__/roles.routes.test.ts +234 -0
  520. package/src/modules/access/access-control.interface.ts +383 -0
  521. package/src/modules/access/access-control.service.ts +1794 -0
  522. package/src/modules/access/access-errors.ts +60 -0
  523. package/src/modules/access/access-mutation.service.ts +369 -0
  524. package/src/modules/access/access-splice.ts +413 -0
  525. package/src/modules/access/access.routes.ts +894 -0
  526. package/src/modules/access/creator-access.ts +270 -0
  527. package/src/modules/access/kb-read-filter.ts +76 -0
  528. package/src/modules/access/roles-admin.service.ts +741 -0
  529. package/src/modules/access/roles-edit.ts +248 -0
  530. package/src/modules/access/roles-yaml-guard.ts +89 -0
  531. package/src/modules/admin/admin-access.routes.ts +29 -0
  532. package/src/modules/admin/admin-access.service.ts +38 -0
  533. package/src/modules/admin/admin.interface.ts +10 -0
  534. package/src/modules/auth/account-erasure.service.ts +183 -0
  535. package/src/modules/auth/auth.middleware.ts +78 -0
  536. package/src/modules/auth/auth.routes.ts +97 -0
  537. package/src/modules/auth/auth.service.ts +199 -0
  538. package/src/modules/code-mode/code-mode-names.ts +38 -0
  539. package/src/modules/code-mode/code-mode.tool.ts +117 -0
  540. package/src/modules/code-mode/index.ts +6 -0
  541. package/src/modules/database/connection.ts +15 -0
  542. package/src/modules/database/core-schema.ts +431 -0
  543. package/src/modules/database/migrate.ts +43 -0
  544. package/src/modules/database/schema.ts +11 -0
  545. package/src/modules/diff/__tests__/diff.routes.read-gate.test.ts +87 -0
  546. package/src/modules/diff/__tests__/diff.routes.rejectPathsLocked.test.ts +150 -0
  547. package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +184 -0
  548. package/src/modules/diff/__tests__/diff.service.test.ts +202 -0
  549. package/src/modules/diff/diff-paths.ts +9 -0
  550. package/src/modules/diff/diff.config.ts +12 -0
  551. package/src/modules/diff/diff.interface.ts +78 -0
  552. package/src/modules/diff/diff.routes.ts +277 -0
  553. package/src/modules/diff/diff.service.ts +508 -0
  554. package/src/modules/diff/line-diff.ts +79 -0
  555. package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +287 -0
  556. package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +249 -0
  557. package/src/modules/mcp/__tests__/mcp-proxy-helpers.test.ts +253 -0
  558. package/src/modules/mcp/__tests__/mcp-session-store.test.ts +151 -0
  559. package/src/modules/mcp/__tests__/mcp.e2e.test.ts +150 -0
  560. package/src/modules/mcp/__tests__/mcp.routes.delete.test.ts +92 -0
  561. package/src/modules/mcp/__tests__/mcp.service.test.ts +414 -0
  562. package/src/modules/mcp/mcp-auth.middleware.ts +126 -0
  563. package/src/modules/mcp/mcp-session-store.ts +162 -0
  564. package/src/modules/mcp/mcp.routes.ts +263 -0
  565. package/src/modules/mcp/mcp.service.ts +973 -0
  566. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +401 -0
  567. package/src/modules/mcp/oauth/oauth-consent.routes.ts +60 -0
  568. package/src/modules/mcp/oauth/oauth-state.ts +61 -0
  569. package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +277 -0
  570. package/src/modules/secrets-vault/__tests__/db-secrets-vault.oauth.test.ts +206 -0
  571. package/src/modules/secrets-vault/__tests__/mcp-oauth-discovery.service.test.ts +178 -0
  572. package/src/modules/secrets-vault/__tests__/scopes-covered.test.ts +101 -0
  573. package/src/modules/secrets-vault/__tests__/secrets-variable-loader.test.ts +54 -0
  574. package/src/modules/secrets-vault/__tests__/tool-owner-gate.route.test.ts +143 -0
  575. package/src/modules/secrets-vault/db-secrets-vault.service.ts +792 -0
  576. package/src/modules/secrets-vault/index.ts +25 -0
  577. package/src/modules/secrets-vault/mcp-oauth-discovery.service.ts +289 -0
  578. package/src/modules/secrets-vault/secrets-variable-loader.ts +104 -0
  579. package/src/modules/secrets-vault/secrets-vault.contract.ts +270 -0
  580. package/src/modules/secrets-vault/secrets-vault.routes.ts +526 -0
  581. package/src/modules/skills/__tests__/skills.service.test.ts +176 -0
  582. package/src/modules/skills/index.ts +10 -0
  583. package/src/modules/skills/skills.contract.ts +54 -0
  584. package/src/modules/skills/skills.routes.ts +38 -0
  585. package/src/modules/skills/skills.service.ts +245 -0
  586. package/src/modules/skills/skills.tools.ts +121 -0
  587. package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +358 -0
  588. package/src/modules/tool-auth/__tests__/internal-token.service.test.ts +79 -0
  589. package/src/modules/tool-auth/__tests__/manual-auth.middleware.test.ts +88 -0
  590. package/src/modules/tool-auth/external-api-key.errors.ts +25 -0
  591. package/src/modules/tool-auth/external-api-key.interface.ts +99 -0
  592. package/src/modules/tool-auth/external-api-key.service.ts +209 -0
  593. package/src/modules/tool-auth/internal-token.service.ts +124 -0
  594. package/src/modules/tool-auth/llm-usage-meter.ts +19 -0
  595. package/src/modules/tool-auth/tool-auth.middleware.ts +220 -0
  596. package/src/modules/tool-helpers/__tests__/phase0-loopback-spike.test.ts +129 -0
  597. package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +95 -0
  598. package/src/modules/tool-helpers/__tests__/tools-surface.test.ts +146 -0
  599. package/src/modules/tool-helpers/__tests__/validate-token.test.ts +75 -0
  600. package/src/modules/tool-helpers/index.ts +18 -0
  601. package/src/modules/tool-helpers/tool-context.ts +98 -0
  602. package/src/modules/tool-helpers/tool-def.ts +73 -0
  603. package/src/modules/tool-helpers/tool-handler.ts +91 -0
  604. package/src/modules/tool-helpers/tool.contract.ts +85 -0
  605. package/src/modules/tool-helpers/validate-token.ts +50 -0
  606. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +200 -0
  607. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +499 -0
  608. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +156 -0
  609. package/src/modules/tool-manuals/index.ts +12 -0
  610. package/src/modules/tool-manuals/tool-manuals.contract.ts +183 -0
  611. package/src/modules/tool-manuals/tool-manuals.routes.ts +110 -0
  612. package/src/modules/tool-manuals/tool-manuals.service.ts +781 -0
  613. package/src/modules/tool-manuals/tool-manuals.tools.ts +202 -0
  614. package/src/modules/tool-registry/__tests__/tool-registry.test.ts +64 -0
  615. package/src/modules/tool-registry/manual.routes.ts +87 -0
  616. package/src/modules/tool-registry/tool-registry.ts +55 -0
  617. package/src/modules/tool-registry/tool.contract.ts +52 -0
  618. package/src/modules/workflow/__tests__/event-bus.test.ts +322 -0
  619. package/src/modules/workflow/__tests__/file-change-notifier.test.ts +51 -0
  620. package/src/modules/workflow/__tests__/format-affected-owners.test.ts +67 -0
  621. package/src/modules/workflow/__tests__/locking-filesystem.test.ts +445 -0
  622. package/src/modules/workflow/__tests__/pending-commits.canonical.test.ts +36 -0
  623. package/src/modules/workflow/__tests__/pending-commits.worker.test.ts +243 -0
  624. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +308 -0
  625. package/src/modules/workflow/__tests__/sanitize-error.test.ts +67 -0
  626. package/src/modules/workflow/__tests__/session-ontology.policy.test.ts +62 -0
  627. package/src/modules/workflow/__tests__/session-ontology.service.test.ts +200 -0
  628. package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +232 -0
  629. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +380 -0
  630. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +340 -0
  631. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +192 -0
  632. package/src/modules/workflow/agent-tools/workflow.tools.ts +502 -0
  633. package/src/modules/workflow/event-bus.ts +262 -0
  634. package/src/modules/workflow/events.routes.ts +266 -0
  635. package/src/modules/workflow/file-change-notifier.ts +54 -0
  636. package/src/modules/workflow/file-lock.service.ts +269 -0
  637. package/src/modules/workflow/git/__tests__/branch-name.test.ts +86 -0
  638. package/src/modules/workflow/git/__tests__/branchAuthor.test.ts +80 -0
  639. package/src/modules/workflow/git/__tests__/clone-config.test.ts +15 -0
  640. package/src/modules/workflow/git/__tests__/git-test-helpers.ts +47 -0
  641. package/src/modules/workflow/git/__tests__/git-version.failure.test.ts +24 -0
  642. package/src/modules/workflow/git/__tests__/git-version.test.ts +49 -0
  643. package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +389 -0
  644. package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +124 -0
  645. package/src/modules/workflow/git/__tests__/git.service.commitChanges.test.ts +105 -0
  646. package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +211 -0
  647. package/src/modules/workflow/git/__tests__/git.service.createBranch.test.ts +154 -0
  648. package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +320 -0
  649. package/src/modules/workflow/git/__tests__/git.service.diffFileAtCommit.test.ts +202 -0
  650. package/src/modules/workflow/git/__tests__/git.service.diffFileBetweenBranches.test.ts +453 -0
  651. package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +198 -0
  652. package/src/modules/workflow/git/__tests__/git.service.listTrackedFiles.test.ts +125 -0
  653. package/src/modules/workflow/git/__tests__/git.service.logForFile.test.ts +219 -0
  654. package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +145 -0
  655. package/src/modules/workflow/git/__tests__/git.service.pendingChanges.test.ts +240 -0
  656. package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +272 -0
  657. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +232 -0
  658. package/src/modules/workflow/git/__tests__/git.service.readFileAtRef.test.ts +101 -0
  659. package/src/modules/workflow/git/__tests__/git.service.status.test.ts +127 -0
  660. package/src/modules/workflow/git/__tests__/mutex.test.ts +78 -0
  661. package/src/modules/workflow/git/__tests__/pull-request.service.test.ts +225 -0
  662. package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-cancel.test.ts +101 -0
  663. package/src/modules/workflow/git/branch-name.ts +70 -0
  664. package/src/modules/workflow/git/clone-config.ts +71 -0
  665. package/src/modules/workflow/git/git-version.ts +70 -0
  666. package/src/modules/workflow/git/git.service.ts +2248 -0
  667. package/src/modules/workflow/git/mutex.ts +22 -0
  668. package/src/modules/workflow/git/pull-request.service.ts +447 -0
  669. package/src/modules/workflow/locking-filesystem.ts +489 -0
  670. package/src/modules/workflow/pending-commits.service.ts +444 -0
  671. package/src/modules/workflow/pending-commits.worker.ts +361 -0
  672. package/src/modules/workflow/read-only-filesystem.ts +54 -0
  673. package/src/modules/workflow/recovery-bot.ts +73 -0
  674. package/src/modules/workflow/review-workflow/__tests__/approval-states.test.ts +560 -0
  675. package/src/modules/workflow/review-workflow/__tests__/cancel-pr.test.ts +176 -0
  676. package/src/modules/workflow/review-workflow/__tests__/merge-gate.test.ts +258 -0
  677. package/src/modules/workflow/review-workflow/review-workflow.interface.ts +199 -0
  678. package/src/modules/workflow/review-workflow/review-workflow.service.ts +806 -0
  679. package/src/modules/workflow/sanitize-error.ts +62 -0
  680. package/src/modules/workflow/session-ontology.policy.ts +70 -0
  681. package/src/modules/workflow/session-ontology.service.ts +178 -0
  682. package/src/modules/workflow/workflow-hooks.ts +101 -0
  683. package/src/modules/workflow/workflow.errors.ts +285 -0
  684. package/src/modules/workflow/workflow.routes.ts +858 -0
  685. package/src/modules/workflow/workflow.service.ts +1555 -0
  686. package/src/modules/workspace/__tests__/kb-seed.service.test.ts +213 -0
  687. package/src/modules/workspace/__tests__/routine-write-policy.test.ts +68 -0
  688. package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +237 -0
  689. package/src/modules/workspace/__tests__/spill-store.test.ts +43 -0
  690. package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +233 -0
  691. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +176 -0
  692. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +303 -0
  693. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +276 -0
  694. package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +120 -0
  695. package/src/modules/workspace/__tests__/workspace.service.test.ts +565 -0
  696. package/src/modules/workspace/__tests__/workspace.tools.test.ts +504 -0
  697. package/src/modules/workspace/bevel-ignore.ts +62 -0
  698. package/src/modules/workspace/kb-seed.interface.ts +36 -0
  699. package/src/modules/workspace/kb-seed.service.ts +361 -0
  700. package/src/modules/workspace/routine-write-policy.ts +79 -0
  701. package/src/modules/workspace/session-ontology.gate.ts +189 -0
  702. package/src/modules/workspace/session-sink.ts +25 -0
  703. package/src/modules/workspace/spill-store.ts +87 -0
  704. package/src/modules/workspace/workspace.routes.ts +1114 -0
  705. package/src/modules/workspace/workspace.service.ts +1343 -0
  706. package/src/modules/workspace/workspace.tools.ts +885 -0
  707. package/src/shared/__tests__/frontmatter-id.test.ts +88 -0
  708. package/src/shared/__tests__/fs-walk.test.ts +42 -0
  709. package/src/shared/__tests__/ssrf.test.ts +53 -0
  710. package/src/shared/__tests__/utcp-namespace.test.ts +19 -0
  711. package/src/shared/frontmatter-id.ts +72 -0
  712. package/src/shared/fs-walk.ts +30 -0
  713. package/src/shared/hash-email.ts +14 -0
  714. package/src/shared/kb-layout.test.ts +88 -0
  715. package/src/shared/kb-layout.ts +101 -0
  716. package/src/shared/ssrf.ts +78 -0
  717. package/src/shared/token-crypto.ts +54 -0
  718. package/src/shared/ttl-cache.ts +27 -0
  719. package/src/shared/utcp-namespace.ts +88 -0
  720. package/src/version.ts +19 -0
@@ -0,0 +1,209 @@
1
+ import { createHash, randomBytes } from 'node:crypto';
2
+ import { and, desc, eq, isNotNull, isNull } from 'drizzle-orm';
3
+ import type { AuthUser } from '@bevel-software/platform-shared';
4
+ import type { Database } from '../database/connection.js';
5
+ import { externalApiKeys, users } from '../database/schema.js';
6
+ import {
7
+ InvalidTokenLabelError,
8
+ TokenNotFoundError,
9
+ TokenStillActiveError,
10
+ } from './external-api-key.errors.js';
11
+ import type {
12
+ ExternalApiKeySummary,
13
+ IExternalApiKeyService,
14
+ MintedExternalApiKey,
15
+ } from './external-api-key.interface.js';
16
+
17
+ // Plaintext format: `<tenant>_<43 base64url chars>`. 32 random bytes encoded
18
+ // base64url is 43 chars and gives 256 bits of entropy — overkill against
19
+ // brute force, cheap to copy. The tenant prefix (default `bevel_`) lets the
20
+ // auth middleware route key-vs-JWT requests without parsing both shapes.
21
+ const TOKEN_BYTES = 32;
22
+
23
+ const MAX_LABEL_LEN = 200;
24
+
25
+ export class ExternalApiKeyService implements IExternalApiKeyService {
26
+ /**
27
+ * @param keyPrefix Tenant-derived plaintext prefix (e.g. `bevel_`) — injected
28
+ * from {@link AppConfig.externalApiKeyPrefix} so a deploy can brand its keys.
29
+ */
30
+ constructor(
31
+ private readonly db: Database,
32
+ private readonly keyPrefix: string,
33
+ ) {}
34
+
35
+ /** True if a bearer string carries this tenant's external-API-key prefix. */
36
+ looksLikeExternalApiKey(token: string): boolean {
37
+ return typeof token === 'string' && token.startsWith(this.keyPrefix);
38
+ }
39
+
40
+ async mint(userId: string, label: string): Promise<MintedExternalApiKey> {
41
+ const trimmed = (label ?? '').trim();
42
+ if (trimmed.length === 0) {
43
+ throw new InvalidTokenLabelError('Label cannot be empty');
44
+ }
45
+ if (trimmed.length > MAX_LABEL_LEN) {
46
+ throw new InvalidTokenLabelError(
47
+ `Label cannot exceed ${MAX_LABEL_LEN} characters`,
48
+ );
49
+ }
50
+
51
+ const plaintext = this.keyPrefix + randomBytes(TOKEN_BYTES).toString('base64url');
52
+ const tokenHash = hashToken(plaintext);
53
+
54
+ const [row] = await this.db
55
+ .insert(externalApiKeys)
56
+ .values({ userId, tokenHash, label: trimmed })
57
+ .returning();
58
+
59
+ return {
60
+ plaintext,
61
+ summary: toSummary(row),
62
+ };
63
+ }
64
+
65
+ async verifyAndLoadUser(plaintext: string): Promise<AuthUser | null> {
66
+ const resolved = await this.verifyAndLoadToken(plaintext);
67
+ return resolved ? resolved.user : null;
68
+ }
69
+
70
+ async verifyAndLoadToken(
71
+ plaintext: string,
72
+ ): Promise<{ tokenId: string; user: AuthUser } | null> {
73
+ if (!this.looksLikeExternalApiKey(plaintext)) {
74
+ return null;
75
+ }
76
+ const tokenHash = hashToken(plaintext);
77
+
78
+ // Join users so a single round-trip resolves both "token is valid" and
79
+ // "load the user it belongs to". The unique index on token_hash makes
80
+ // this a point-lookup. `isNull(revokedAt)` is what enforces revocation
81
+ // — the row remains for audit.
82
+ const [row] = await this.db
83
+ .select({
84
+ tokenId: externalApiKeys.id,
85
+ userId: users.id,
86
+ email: users.email,
87
+ name: users.name,
88
+ avatarUrl: users.avatarUrl,
89
+ })
90
+ .from(externalApiKeys)
91
+ .innerJoin(users, eq(externalApiKeys.userId, users.id))
92
+ .where(and(eq(externalApiKeys.tokenHash, tokenHash), isNull(externalApiKeys.revokedAt)))
93
+ .limit(1);
94
+
95
+ if (!row) return null;
96
+
97
+ // Fire-and-forget so verification latency is bounded by the SELECT, not
98
+ // the UPDATE. A failed touch is logged but never blocks the caller —
99
+ // the worst case is a slightly stale `last_used_at`, which is fine for
100
+ // a "when was this key last used" audit view.
101
+ this.touchLastUsed(row.tokenId).catch((err) => {
102
+ console.warn('[external-api-key] touchLastUsed failed:', err);
103
+ });
104
+
105
+ return {
106
+ tokenId: row.tokenId,
107
+ user: {
108
+ id: row.userId,
109
+ email: row.email,
110
+ name: row.name,
111
+ avatarUrl: row.avatarUrl ?? undefined,
112
+ },
113
+ };
114
+ }
115
+
116
+ async listForUser(userId: string): Promise<ExternalApiKeySummary[]> {
117
+ const rows = await this.db
118
+ .select()
119
+ .from(externalApiKeys)
120
+ .where(eq(externalApiKeys.userId, userId))
121
+ .orderBy(desc(externalApiKeys.createdAt));
122
+ return rows.map(toSummary);
123
+ }
124
+
125
+ async revoke(id: string, userId: string): Promise<void> {
126
+ // Scope the WHERE by userId so a user can never revoke another user's
127
+ // token even if they learn the id. Idempotent on already-revoked rows
128
+ // because we only set `revokedAt` when it's currently null — re-revoking
129
+ // returns 0 rows changed but no error.
130
+ const result = await this.db
131
+ .update(externalApiKeys)
132
+ .set({ revokedAt: new Date() })
133
+ .where(
134
+ and(
135
+ eq(externalApiKeys.id, id),
136
+ eq(externalApiKeys.userId, userId),
137
+ isNull(externalApiKeys.revokedAt),
138
+ ),
139
+ )
140
+ .returning({ id: externalApiKeys.id });
141
+
142
+ if (result.length === 0) {
143
+ // Distinguish "doesn't exist / not yours" from "already revoked".
144
+ // The latter must stay idempotent (return success); only the former
145
+ // throws.
146
+ const [existing] = await this.db
147
+ .select({ id: externalApiKeys.id })
148
+ .from(externalApiKeys)
149
+ .where(and(eq(externalApiKeys.id, id), eq(externalApiKeys.userId, userId)))
150
+ .limit(1);
151
+ if (!existing) {
152
+ throw new TokenNotFoundError();
153
+ }
154
+ }
155
+ }
156
+
157
+ async remove(id: string, userId: string): Promise<void> {
158
+ // Only revoked rows may be hard-deleted — deleting an active key would
159
+ // silently cut off a live agent. Scope by userId so a user can only
160
+ // delete their own tokens. Validate first (so we can return a precise
161
+ // not-found vs still-active error), then delete inside a transaction.
162
+ const [existing] = await this.db
163
+ .select({ revokedAt: externalApiKeys.revokedAt })
164
+ .from(externalApiKeys)
165
+ .where(and(eq(externalApiKeys.id, id), eq(externalApiKeys.userId, userId)))
166
+ .limit(1);
167
+ if (!existing) {
168
+ throw new TokenNotFoundError();
169
+ }
170
+ if (existing.revokedAt === null) {
171
+ // Exists and is yours, but wasn't revoked — refuse rather than delete.
172
+ throw new TokenStillActiveError();
173
+ }
174
+
175
+ // Dependents (e.g. the enterprise LLM-usage metering rows) hang off this
176
+ // row via ON DELETE CASCADE foreign keys, so a bare delete takes any audit
177
+ // trail with it — this service doesn't have to know those tables exist.
178
+ await this.db
179
+ .delete(externalApiKeys)
180
+ .where(
181
+ and(
182
+ eq(externalApiKeys.id, id),
183
+ eq(externalApiKeys.userId, userId),
184
+ isNotNull(externalApiKeys.revokedAt),
185
+ ),
186
+ );
187
+ }
188
+
189
+ private async touchLastUsed(tokenId: string): Promise<void> {
190
+ await this.db
191
+ .update(externalApiKeys)
192
+ .set({ lastUsedAt: new Date() })
193
+ .where(eq(externalApiKeys.id, tokenId));
194
+ }
195
+ }
196
+
197
+ function hashToken(plaintext: string): string {
198
+ return createHash('sha256').update(plaintext).digest('hex');
199
+ }
200
+
201
+ function toSummary(row: typeof externalApiKeys.$inferSelect): ExternalApiKeySummary {
202
+ return {
203
+ id: row.id,
204
+ label: row.label,
205
+ createdAt: row.createdAt.getTime(),
206
+ lastUsedAt: row.lastUsedAt ? row.lastUsedAt.getTime() : null,
207
+ revokedAt: row.revokedAt ? row.revokedAt.getTime() : null,
208
+ };
209
+ }
@@ -0,0 +1,124 @@
1
+ import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
2
+
3
+ /**
4
+ * What an internal token authorizes: a user identity, nothing more. Minted when
5
+ * an agent's code-mode client is built and seeded into that client's UTCP config.
6
+ * Deliberately identity-only — the SAME shape a `bevel_…` connection key resolves
7
+ * to: the workspace is chosen per call from the tool's `branch` argument, and the
8
+ * scope is always write (the middleware sets it, exactly as for connection keys).
9
+ */
10
+ export interface InternalTokenClaim {
11
+ userId: string;
12
+ /**
13
+ * The agent run / conversation id (the Mastra thread id) this token is scoped
14
+ * to, when minted per-run. Surfaced as `ToolContext.sessionId` so the
15
+ * ontology-session boundary can scope to one run for the in-process agent
16
+ * (the external/MCP path carries `sessionId` on the tool body instead).
17
+ * Absent for identity-only tokens.
18
+ */
19
+ sessionId?: string;
20
+ /**
21
+ * True when this token is the LOOPBACK identity of an external caller — the
22
+ * MCP proxy mints one per OAuth/JWT MCP session (which has no `bevel_…`
23
+ * connection key to pass through). The verifier resolves such tokens to
24
+ * `source: 'external'`: the caller IS an external agent, and must be treated
25
+ * like one everywhere — admitted to external-only surfaces (`start_session`,
26
+ * `ask`), refused from internal-only ones (`execute_command`, …), and
27
+ * expected to carry `sessionId` on the tool body, not in the token.
28
+ */
29
+ externalProxy?: boolean;
30
+ }
31
+
32
+ interface SignedPayload extends InternalTokenClaim {
33
+ /** Expiry, epoch ms. */
34
+ exp: number;
35
+ }
36
+
37
+ const DEFAULT_PREFIX = 'bevel-int_';
38
+
39
+ function b64url(buf: Buffer): string {
40
+ return buf.toString('base64url');
41
+ }
42
+
43
+ /**
44
+ * Mints + verifies stateless HMAC internal tokens. No DB: the token is
45
+ * self-contained `(claim, exp)` signed with a process secret, so it is
46
+ * multi-replica safe for verification within a deploy and costs nothing to
47
+ * issue. Tokens carry only `userId` and are short-lived; the agent factory
48
+ * mints one per code-mode client (per user).
49
+ *
50
+ * Distinct from connection keys (`bevel_…`, long-lived, user-wide): internal
51
+ * tokens are the least-privilege credential for the in-process loopback surface
52
+ * and are rejected by the external endpoints, and vice-versa.
53
+ */
54
+ export class InternalTokenService {
55
+ private readonly secret: Buffer;
56
+ private readonly ttlMs: number;
57
+ private readonly now: () => number;
58
+ private readonly prefix: string;
59
+
60
+ constructor(
61
+ opts: { secret?: string; ttlMs?: number; now?: () => number; prefix?: string } = {},
62
+ ) {
63
+ // A per-boot random secret is fine: tokens are minted per turn-ish and
64
+ // re-minted after a restart. A caller may inject a stable secret (tests, or
65
+ // a future multi-replica deploy) instead.
66
+ this.secret = opts.secret ? Buffer.from(opts.secret, 'utf8') : randomBytes(32);
67
+ this.ttlMs = opts.ttlMs ?? 60 * 60 * 1000; // 1h
68
+ this.now = opts.now ?? Date.now;
69
+ // Tenant-derived prefix (default `bevel-int_`), injected from
70
+ // AppConfig.internalTokenPrefix so internal tokens brand with the deploy's tenant.
71
+ this.prefix = opts.prefix ?? DEFAULT_PREFIX;
72
+ }
73
+
74
+ /** Token lifetime in ms — so callers caching a minted token can refresh it before expiry. */
75
+ get tokenTtlMs(): number {
76
+ return this.ttlMs;
77
+ }
78
+
79
+ /** @param ttlMs Override the default lifetime — e.g. the MCP proxy mints
80
+ * session-loopback tokens that must outlive its 4h session idle TTL. */
81
+ mint(claim: InternalTokenClaim, ttlMs?: number): string {
82
+ const payload: SignedPayload = { ...claim, exp: this.now() + (ttlMs ?? this.ttlMs) };
83
+ const body = b64url(Buffer.from(JSON.stringify(payload), 'utf8'));
84
+ const sig = b64url(this.sign(body));
85
+ return `${this.prefix}${body}.${sig}`;
86
+ }
87
+
88
+ /** Returns the claim for a valid, unexpired token; null otherwise. */
89
+ verify(token: string): InternalTokenClaim | null {
90
+ if (!this.looksLikeInternalToken(token)) return null;
91
+ const rest = token.slice(this.prefix.length);
92
+ const dot = rest.indexOf('.');
93
+ if (dot < 0) return null;
94
+ const body = rest.slice(0, dot);
95
+ const sig = rest.slice(dot + 1);
96
+
97
+ const expected = b64url(this.sign(body));
98
+ if (sig.length !== expected.length) return null;
99
+ if (!timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) return null;
100
+
101
+ let payload: SignedPayload;
102
+ try {
103
+ payload = JSON.parse(Buffer.from(body, 'base64url').toString('utf8'));
104
+ } catch {
105
+ return null;
106
+ }
107
+ if (typeof payload.exp !== 'number' || payload.exp < this.now()) return null;
108
+ if (typeof payload.userId !== 'string') return null;
109
+ return {
110
+ userId: payload.userId,
111
+ ...(typeof payload.sessionId === 'string' ? { sessionId: payload.sessionId } : {}),
112
+ ...(payload.externalProxy === true ? { externalProxy: true } : {}),
113
+ };
114
+ }
115
+
116
+ /** True if the bearer string looks like an internal token (vs an external API key). */
117
+ looksLikeInternalToken(token: string): boolean {
118
+ return token.startsWith(this.prefix);
119
+ }
120
+
121
+ private sign(body: string): Buffer {
122
+ return createHmac('sha256', this.secret).update(body).digest();
123
+ }
124
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Metering view over connection-key LLM usage, consumed by the connection-key
3
+ * management routes (mcp) to show each key's spend against the daily budget.
4
+ * The enterprise LLM proxy's `LlmUsageService` satisfies this structurally; a
5
+ * core-only deployment (no LLM proxy, nothing to meter) passes
6
+ * {@link unmeteredLlmUsage}.
7
+ */
8
+ export interface ILlmUsageMeter {
9
+ /** Daily per-key token cap shown in the UI, or null when unmetered. */
10
+ readonly dailyCap: number | null;
11
+ /** Today's usage per key id, as `{ [tokenId]: tokens }` — missing keys mean 0. */
12
+ usageForTokens(tokenIds: string[]): Promise<Record<string, number>>;
13
+ }
14
+
15
+ /** Core default: no proxy, no metering — every key reads as unused/uncapped. */
16
+ export const unmeteredLlmUsage: ILlmUsageMeter = {
17
+ dailyCap: null,
18
+ usageForTokens: async () => ({}),
19
+ };
@@ -0,0 +1,220 @@
1
+ import type { Request, Response, NextFunction, RequestHandler } from 'express';
2
+ import type { IExternalApiKeyService } from './external-api-key.interface.js';
3
+ import type { AuthService } from '../auth/auth.service.js';
4
+ import { InternalTokenService } from './internal-token.service.js';
5
+
6
+ /**
7
+ * What the `toolAuth` middleware resolves a bearer to, before the per-call
8
+ * `ToolContext` is built. Internal and external are now the SAME shape — a user
9
+ * identity at write scope — resolving through one path; `source` only records
10
+ * which credential authenticated (so internal-only routes can be gated):
11
+ * - `external`: a `bevel_…` connection key → user.
12
+ * - `internal`: an identity-only HMAC token minted for an agent's code-mode client.
13
+ * - `session`: a browser JWT — admitted ONLY on the read-only manual endpoint
14
+ * (`createManualAuthMiddleware`), never on a tool-execution route, so it can
15
+ * browse the catalog but cannot invoke tools.
16
+ * The workspace is chosen per call from the tool's `branch` argument (downstream
17
+ * ACL / protected-branch checks gate writes).
18
+ */
19
+ export interface ToolAuth {
20
+ source: 'internal' | 'external' | 'session';
21
+ userId: string;
22
+ tokenId?: string;
23
+ /** The agent run id carried by a per-run internal token (in-process agent). The external path supplies `sessionId` on the tool body instead. */
24
+ sessionId?: string;
25
+ /** Always `'write'` now (the middleware sets it for both internal + external — neither credential carries scope). The read path is dormant until consumer agents are removed. */
26
+ scope: 'read' | 'write';
27
+ }
28
+
29
+ declare global {
30
+ // eslint-disable-next-line @typescript-eslint/no-namespace
31
+ namespace Express {
32
+ interface Request {
33
+ toolAuth?: ToolAuth;
34
+ }
35
+ }
36
+ }
37
+
38
+ const WWW_AUTH = 'Bearer realm="bevel-tools"';
39
+
40
+ /**
41
+ * Gate that admits ONLY in-process callers (those bearing an internal HMAC
42
+ * token). Mount it AFTER `toolAuth` on every internal-only surface — the
43
+ * internal tool catalog and the routes of tools registered with
44
+ * `registerInternalTool` but NOT `registerExternalTool` (e.g. `execute_command`,
45
+ * `switch_branch`, the `sharepoint_*` reads). `toolAuth` alone is not enough:
46
+ * an external connection key authenticates successfully, so without this gate it
47
+ * could invoke an internal-only route directly by guessing its name. The route
48
+ * MUST stay mounted (our own agent reaches it over the same loopback HTTP), so
49
+ * the restriction has to be enforced here at request time, not by hiding the
50
+ * route. 403 (authenticated, but not authorized for this surface).
51
+ */
52
+ export const requireInternalSource: RequestHandler = (req, res, next) => {
53
+ if (req.toolAuth?.source !== 'internal') {
54
+ res.status(403).json({ error: 'This tool is internal-only.' });
55
+ return;
56
+ }
57
+ next();
58
+ };
59
+
60
+ /**
61
+ * Mirror of `requireInternalSource` for surfaces that must admit ONLY external
62
+ * callers. `start_session` mints a fresh chat thread as the caller's
63
+ * ontology-session id; an internal (in-process agent) token already carries
64
+ * its run's `sessionId`, so letting it mint a new thread mid-run would
65
+ * silently reset the one-ontology-per-conversation boundary.
66
+ *
67
+ * "External" is decided by the VERIFIER, not by which credential shape
68
+ * authenticated: a `bevel_…` connection key resolves external, and so does an
69
+ * `externalProxy` internal token — the loopback identity the MCP proxy mints
70
+ * for an OAuth/JWT MCP session, whose caller IS an external agent. (Gating on
71
+ * the raw credential shape used to 403 those sessions here, deadlocking them:
72
+ * they couldn't mint a sessionId, and every session-gated tool demands one.)
73
+ * Mount AFTER `toolAuth`. 403 (authenticated, but not authorized).
74
+ */
75
+ export const requireExternalSource: RequestHandler = (req, res, next) => {
76
+ if (req.toolAuth?.source !== 'external') {
77
+ res.status(403).json({ error: 'This tool is external-only.' });
78
+ return;
79
+ }
80
+ next();
81
+ };
82
+
83
+ /** Outcome of verifying a bearer token — either a normalized identity or a status+message to surface. */
84
+ export type VerifyResult =
85
+ | { ok: true; auth: ToolAuth }
86
+ | { ok: false; status: number; message: string };
87
+
88
+ /**
89
+ * The framework-agnostic verify core: bearer token (the value AFTER `Bearer `) →
90
+ * normalized `ToolAuth`, accepting EITHER a `bevel_…` connection key (external —
91
+ * pipeline-agent, MCP) OR an internal HMAC token (our own agent's loopback). A
92
+ * bare JWT / unknown scheme is refused. Throws only if the connection-key store
93
+ * itself errors (backend down); the caller maps that to 500. This is the shared
94
+ * primitive both `createToolAuthMiddleware` (our Express hosting) and
95
+ * `validateToken` (the tool-author SDK) are built on, so there is ONE auth path.
96
+ */
97
+ export function createTokenVerifier(
98
+ externalApiKeyService: IExternalApiKeyService,
99
+ internalTokenService: InternalTokenService,
100
+ ): (token: string | undefined) => Promise<VerifyResult> {
101
+ const missing = { ok: false as const, status: 401, message: 'A connection key or internal token is required' };
102
+ return async (token) => {
103
+ if (!token) return missing;
104
+
105
+ // Internal token → in-process loopback caller. Usually our own agent
106
+ // (source 'internal'), EXCEPT the `externalProxy` tokens the MCP proxy
107
+ // mints as the loopback identity of an OAuth/JWT MCP session — that
108
+ // caller is an external agent and resolves as one, so external-only
109
+ // surfaces admit it and internal-only surfaces refuse it, exactly like a
110
+ // connection key (it just has no tokenId to meter on).
111
+ if (internalTokenService.looksLikeInternalToken(token)) {
112
+ const claim = internalTokenService.verify(token);
113
+ if (!claim) return { ok: false, status: 401, message: 'Invalid or expired internal token' };
114
+ return claim.externalProxy
115
+ ? { ok: true, auth: { source: 'external', userId: claim.userId, scope: 'write' } }
116
+ : { ok: true, auth: { source: 'internal', userId: claim.userId, sessionId: claim.sessionId, scope: 'write' } };
117
+ }
118
+
119
+ // External API key → external caller. (verifyAndLoadToken may throw → propagates → caller maps to 500.)
120
+ if (externalApiKeyService.looksLikeExternalApiKey(token)) {
121
+ const resolved = await externalApiKeyService.verifyAndLoadToken(token);
122
+ return resolved
123
+ ? { ok: true, auth: { source: 'external', userId: resolved.user.id, tokenId: resolved.tokenId, scope: 'write' } }
124
+ : { ok: false, status: 401, message: 'Invalid or revoked connection key' };
125
+ }
126
+
127
+ return missing;
128
+ };
129
+ }
130
+
131
+ /**
132
+ * The one auth gate every tool endpoint applies — a THIN Express adapter over
133
+ * `createTokenVerifier`: parse the bearer header, run the shared verify core,
134
+ * normalize the result to `req.toolAuth` (or the matching status). All auth logic
135
+ * lives in the verifier; this only does header parsing + HTTP mapping.
136
+ */
137
+ export function createToolAuthMiddleware(
138
+ externalApiKeyService: IExternalApiKeyService,
139
+ internalTokenService: InternalTokenService,
140
+ ): RequestHandler {
141
+ const verify = createTokenVerifier(externalApiKeyService, internalTokenService);
142
+ return async (req: Request, res: Response, next: NextFunction) => {
143
+ const header = req.headers.authorization;
144
+ if (!header || !header.toLowerCase().startsWith('bearer ')) {
145
+ res.setHeader('WWW-Authenticate', WWW_AUTH);
146
+ res.status(401).json({ error: 'Missing or invalid Authorization header' });
147
+ return;
148
+ }
149
+ const token = header.slice(header.indexOf(' ') + 1).trim();
150
+ try {
151
+ const result = await verify(token);
152
+ if (!result.ok) {
153
+ if (result.status === 401) res.setHeader('WWW-Authenticate', WWW_AUTH);
154
+ res.status(result.status).json({ error: result.message });
155
+ return;
156
+ }
157
+ req.toolAuth = result.auth;
158
+ next();
159
+ } catch (err) {
160
+ console.error('[tools] connection-key verification failed:', err);
161
+ res.status(500).json({ error: 'Authentication backend unavailable' });
162
+ }
163
+ };
164
+ }
165
+
166
+ /**
167
+ * Auth gate for the READ-ONLY discovery manuals (`GET /agent/utcp` +
168
+ * `/agent/internal/utcp`) ONLY. Superset of `createToolAuthMiddleware`: it
169
+ * accepts a `bevel_…` connection key, an internal token, OR a browser JWT —
170
+ * the last resolving to `source: 'session'`. This is what lets a logged-in user
171
+ * browse the catalog with their existing session (the manual is just a spec, no
172
+ * secrets, and may become per-user — hence one user-aware endpoint rather than a
173
+ * parallel route). It is deliberately NOT used on tool-execution routes, so a
174
+ * JWT can read the manual but can never invoke a tool. The internal manual stays
175
+ * `requireInternalSource`-gated downstream, so a session/key is 403'd there.
176
+ */
177
+ export function createManualAuthMiddleware(
178
+ externalApiKeyService: IExternalApiKeyService,
179
+ internalTokenService: InternalTokenService,
180
+ authService: AuthService,
181
+ ): RequestHandler {
182
+ const verify = createTokenVerifier(externalApiKeyService, internalTokenService);
183
+ return async (req: Request, res: Response, next: NextFunction) => {
184
+ const header = req.headers.authorization;
185
+ if (!header || !header.toLowerCase().startsWith('bearer ')) {
186
+ res.setHeader('WWW-Authenticate', WWW_AUTH);
187
+ res.status(401).json({ error: 'Missing or invalid Authorization header' });
188
+ return;
189
+ }
190
+ const token = header.slice(header.indexOf(' ') + 1).trim();
191
+
192
+ // An external API key / internal token goes through the shared verify core.
193
+ if (internalTokenService.looksLikeInternalToken(token) || externalApiKeyService.looksLikeExternalApiKey(token)) {
194
+ try {
195
+ const result = await verify(token);
196
+ if (!result.ok) {
197
+ if (result.status === 401) res.setHeader('WWW-Authenticate', WWW_AUTH);
198
+ res.status(result.status).json({ error: result.message });
199
+ return;
200
+ }
201
+ req.toolAuth = result.auth;
202
+ next();
203
+ } catch (err) {
204
+ console.error('[tools] connection-key verification failed:', err);
205
+ res.status(500).json({ error: 'Authentication backend unavailable' });
206
+ }
207
+ return;
208
+ }
209
+
210
+ // Otherwise treat the bearer as a browser session JWT.
211
+ try {
212
+ const { userId } = authService.verifyToken(token);
213
+ req.toolAuth = { source: 'session', userId, scope: 'write' };
214
+ next();
215
+ } catch {
216
+ res.setHeader('WWW-Authenticate', WWW_AUTH);
217
+ res.status(401).json({ error: 'Invalid or expired token' });
218
+ }
219
+ };
220
+ }