@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,129 @@
1
+ import type { Server as HttpServer } from 'node:http';
2
+ import express from 'express';
3
+ import { afterEach, describe, expect, it } from 'vitest';
4
+ import '@utcp/http'; // registers the http CallTemplate serializer + protocol
5
+ import { HttpCallTemplateSerializer } from '@utcp/http';
6
+ import { CodeModeUtcpClient } from '../../code-mode/index.js';
7
+
8
+ const httpTemplate = new HttpCallTemplateSerializer();
9
+
10
+ /**
11
+ * PHASE 0 SPIKE (gates the unified-registry plan): prove the agent's INTERNAL
12
+ * execution model works — a real `CodeModeUtcpClient` discovers an HTTP UTCP
13
+ * manual over loopback and calls its tools from inside `call_tool_chain`, with a
14
+ * bearer token resolved from per-client config. Also benchmark per-op loopback
15
+ * latency (R1). This mirrors what each agent turn will do against the internal
16
+ * manual endpoint. Throwaway once the real registry e2e lands.
17
+ */
18
+
19
+ const MANUAL = 'bevel';
20
+
21
+ // The internal UTCP manual a module-hosted endpoint would serve. Tools use the
22
+ // `{body}` wrapper (body_field:'body') so multi-field args ride the JSON body —
23
+ // the only standard-http way to do that (verified in @utcp/http callTool).
24
+ function manual(): unknown {
25
+ const httpTool = (name: string, bodyProps: Record<string, unknown>) => ({
26
+ name,
27
+ description: `the ${name} tool`,
28
+ inputs: {
29
+ type: 'object',
30
+ properties: { body: { type: 'object', properties: bodyProps } },
31
+ required: ['body'],
32
+ },
33
+ outputs: { type: 'object', properties: {} },
34
+ tags: [],
35
+ tool_call_template: {
36
+ call_template_type: 'http',
37
+ http_method: 'POST',
38
+ url: `\${API_URL}/api/agent/tools/${name}`,
39
+ content_type: 'application/json',
40
+ headers: { Authorization: 'Bearer ${CONNECTION_KEY}' },
41
+ body_field: 'body',
42
+ },
43
+ });
44
+ return {
45
+ utcp_version: '1.1.0',
46
+ manual_version: '1.0.0',
47
+ tools: [httpTool('list_branches', {}), httpTool('echo', { msg: { type: 'string' } })],
48
+ };
49
+ }
50
+
51
+ let httpServer: HttpServer | undefined;
52
+ let seenAuth: string | undefined;
53
+
54
+ async function startApp(): Promise<string> {
55
+ const app = express();
56
+ app.use(express.json());
57
+ app.get('/api/agent/internal/utcp', (_req, res) => res.json(manual()));
58
+ app.post('/api/agent/tools/list_branches', (req, res) => {
59
+ seenAuth = req.headers.authorization;
60
+ res.json({ branches: ['current-company-state', 'target-company-state'] });
61
+ });
62
+ app.post('/api/agent/tools/echo', (req, res) => {
63
+ res.json({ echoed: (req.body as { msg?: string })?.msg ?? null });
64
+ });
65
+ httpServer = await new Promise<HttpServer>((resolve) => {
66
+ const s = app.listen(0, () => resolve(s));
67
+ });
68
+ const port = (httpServer.address() as { port: number }).port;
69
+ return `http://127.0.0.1:${port}`;
70
+ }
71
+
72
+ async function buildClient(baseUrl: string, token: string): Promise<CodeModeUtcpClient> {
73
+ // Per-client config carries the loopback base URL + the scoped token under the
74
+ // manual namespace (`<MANUAL>_API_URL` / `<MANUAL>_CONNECTION_KEY`).
75
+ const client = await CodeModeUtcpClient.create(process.cwd(), {
76
+ variables: { [`${MANUAL}_API_URL`]: baseUrl, [`${MANUAL}_CONNECTION_KEY`]: token },
77
+ } as never);
78
+ await client.registerManual(
79
+ httpTemplate.validateDict({
80
+ name: MANUAL,
81
+ call_template_type: 'http',
82
+ http_method: 'GET',
83
+ url: '${API_URL}/api/agent/internal/utcp',
84
+ content_type: 'application/json',
85
+ headers: { Authorization: 'Bearer ${CONNECTION_KEY}' },
86
+ }),
87
+ );
88
+ return client;
89
+ }
90
+
91
+ afterEach(async () => {
92
+ if (httpServer) await new Promise<void>((r) => httpServer!.close(() => r()));
93
+ httpServer = undefined;
94
+ seenAuth = undefined;
95
+ });
96
+
97
+ describe('Phase 0 — internal loopback execution', () => {
98
+ it('discovers an http manual and calls its tools from inside call_tool_chain', async () => {
99
+ const base = await startApp();
100
+ const client = await buildClient(base, 'internal-token-abc');
101
+
102
+ const tools = await client.getTools();
103
+ expect(tools.map((t) => t.name).sort()).toEqual([`${MANUAL}.echo`, `${MANUAL}.list_branches`]);
104
+
105
+ const { result } = await client.callToolChain(
106
+ `return { a: ${MANUAL}.list_branches({ body: {} }), b: ${MANUAL}.echo({ body: { msg: 'hi' } }) };`,
107
+ 20_000,
108
+ );
109
+ expect(result.a).toEqual({ branches: ['current-company-state', 'target-company-state'] });
110
+ expect(result.b).toEqual({ echoed: 'hi' });
111
+ // The per-client token reached the loopback endpoint.
112
+ expect(seenAuth).toBe('Bearer internal-token-abc');
113
+ });
114
+
115
+ it('benchmark: per-op loopback latency inside a code-mode loop', async () => {
116
+ const base = await startApp();
117
+ const client = await buildClient(base, 'tok');
118
+ const N = 30;
119
+ const t0 = performance.now();
120
+ const { result } = await client.callToolChain(
121
+ `let n = 0; for (let i = 0; i < ${N}; i++) { ${MANUAL}.echo({ body: { msg: 'x' } }); n++; } return n;`,
122
+ 30_000,
123
+ );
124
+ const ms = performance.now() - t0;
125
+ expect(result).toBe(N);
126
+ // eslint-disable-next-line no-console
127
+ console.log(`[phase0] ${N} loopback tool calls in one code-mode chain: ${ms.toFixed(0)}ms total, ${(ms / N).toFixed(1)}ms/op`);
128
+ });
129
+ });
@@ -0,0 +1,95 @@
1
+ import type { Server as HttpServer } from 'node:http';
2
+ import express from 'express';
3
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
4
+ import { ToolRegistry } from '../../tool-registry/tool-registry.js';
5
+ import { InternalTokenService } from '../../tool-auth/internal-token.service.js';
6
+ import { createToolAuthMiddleware } from '../../tool-auth/tool-auth.middleware.js';
7
+ import { createToolContextResolver } from '../tool-context.js';
8
+ import { createToolHandlerFactory } from '../tool-handler.js';
9
+ import { createManualRoutes } from '../../tool-registry/manual.routes.js';
10
+ import { registerWorkspaceTools } from '../../workspace/workspace.tools.js';
11
+ import { RoutineWritePolicyService } from '../../workspace/routine-write-policy.js';
12
+ import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
13
+ import { SpillStore } from '../../workspace/spill-store.js';
14
+
15
+ const WS = 'target-company-state';
16
+ let recorded: unknown[][] = [];
17
+
18
+ const externalApiKeyService = { verifyAndLoadToken: async () => null } as never;
19
+ const authService = { getUserById: async (id: string) => ({ id, email: 'e@x', name: 'N' }) } as never;
20
+ const workspaceService = {
21
+ getOrCreateForUser: async () => ({ id: WS }),
22
+ getWorkspacePath: async () => '/tmp/ws',
23
+ unzipFile: async (ws: string, p: string, d?: string) => {
24
+ recorded.push(['unzip', ws, p, d]);
25
+ return { extracted: [p], skipped: [] };
26
+ },
27
+ readFile: async () => {
28
+ throw new Error('no such file');
29
+ },
30
+ } as never;
31
+ const workflowService = {} as never;
32
+ const events = {} as never;
33
+ const accessControl = {
34
+ canRead: async () => true,
35
+ canReadBatch: async (_w: string, _u: string, paths: string[]) => new Map(paths.map((p) => [p, true])),
36
+ } as never;
37
+
38
+ const internalToken = new InternalTokenService({ secret: 's' });
39
+ let httpServer: HttpServer | undefined;
40
+
41
+ async function start(): Promise<string> {
42
+ const registry = new ToolRegistry();
43
+ const toolAuth = createToolAuthMiddleware(externalApiKeyService, internalToken);
44
+ const resolve = createToolContextResolver({ authService, workspaceService, workflowService, events, kbDirName: 'knowledge-base', creatorAccess: { planForCreate: async () => null, grantInExtractedFile: async () => null, noteAccessFileWritten: () => {} } });
45
+ const th = createToolHandlerFactory(resolve);
46
+ const router = express.Router();
47
+ // NOTE (core split): this suite used to register the search, feedback and
48
+ // kb (citation) tools alongside the workspace tools. Those registrations —
49
+ // and their web_search / submit_feedback / cite_kb_node cases — moved to
50
+ // the enterprise repo with their modules; core registers only core tools.
51
+ registerWorkspaceTools(registry, router, toolAuth, th, new SpillStore('/tmp/bevel-test-spills'), accessControl, 'knowledge-base', {
52
+ service: {} as never,
53
+ enabled: false, // ontology boundary not under test here
54
+ kbDirName: 'knowledge-base',
55
+ recoveryBotEmail: 'recovery-bot@bevel.local',
56
+ hooks: new WorkflowHooks(),
57
+ }, new RoutineWritePolicyService(), {} as never /* sessionSink — start_session not exercised here */);
58
+ router.use(createManualRoutes(registry, toolAuth));
59
+
60
+ const app = express();
61
+ app.use(express.json());
62
+ app.use('/api', router);
63
+ httpServer = await new Promise<HttpServer>((r) => {
64
+ const s = app.listen(0, () => r(s));
65
+ });
66
+ return `http://127.0.0.1:${(httpServer.address() as { port: number }).port}`;
67
+ }
68
+
69
+ const tok = () => internalToken.mint({ userId: 'user-A' });
70
+ const post = (url: string, body: unknown = {}) =>
71
+ fetch(url, { method: 'POST', headers: { 'content-type': 'application/json', authorization: `Bearer ${tok()}` }, body: JSON.stringify(body) });
72
+
73
+ beforeEach(() => {
74
+ recorded = [];
75
+ });
76
+ afterEach(async () => {
77
+ if (httpServer) await new Promise<void>((r) => httpServer!.close(() => r()));
78
+ httpServer = undefined;
79
+ });
80
+
81
+ describe('Phase 4 tools (core subset)', () => {
82
+ it('unzip calls workspaceService.unzipFile with the context workspace', async () => {
83
+ const base = await start();
84
+ const res = await post(`${base}/api/agent/tools/unzip`, { path: 'a.zip', branch: WS });
85
+ expect(res.status).toBe(200);
86
+ expect(recorded).toContainEqual(['unzip', WS, 'a.zip', undefined]);
87
+ });
88
+
89
+ it('the registered core tool appears in the internal manual', async () => {
90
+ const base = await start();
91
+ const m = (await (await fetch(`${base}/api/agent/internal/utcp`, { headers: { authorization: `Bearer ${tok()}` } })).json()) as { tools: { name: string }[] };
92
+ const names = m.tools.map((t) => t.name);
93
+ expect(names).toContain('unzip');
94
+ });
95
+ });
@@ -0,0 +1,146 @@
1
+ import type { Server as HttpServer } from 'node:http';
2
+ import express from 'express';
3
+ import { afterEach, describe, expect, it } from 'vitest';
4
+ import { ToolRegistry } from '../../tool-registry/tool-registry.js';
5
+ import { toolDef } from '../tool-def.js';
6
+ import { InternalTokenService } from '../../tool-auth/internal-token.service.js';
7
+ import { createToolAuthMiddleware, requireInternalSource } from '../../tool-auth/tool-auth.middleware.js';
8
+ import { createToolContextResolver } from '../tool-context.js';
9
+ import { createToolHandlerFactory } from '../tool-handler.js';
10
+ import { createManualRoutes } from '../../tool-registry/manual.routes.js';
11
+ import type { ToolContext } from '../tool.contract.js';
12
+
13
+ /**
14
+ * Integration test for the Phase 1 machinery: the ONE mechanism (host endpoint +
15
+ * register def), the dual `toolAuth` (connection key OR internal token resolving
16
+ * to a normalized context), write-scope enforcement, and the two manual
17
+ * endpoints — over a real express app.
18
+ */
19
+
20
+ const WS = 'target-company-state';
21
+
22
+ // Minimal service stubs (list_branches/touch don't touch the filesystem, so the
23
+ // lazy LockingFilesystem is never built).
24
+ const externalApiKeyService = {
25
+ looksLikeExternalApiKey: (t: string) => typeof t === 'string' && t.startsWith('bevel_'),
26
+ verifyAndLoadToken: async (t: string) =>
27
+ t === 'bevel_good' ? { user: { id: 'user-A', email: 'e@x', name: 'N' }, tokenId: 'tok-1' } : null,
28
+ } as never;
29
+ const authService = { getUserById: async (id: string) => ({ id, email: 'e@x', name: 'N' }) } as never;
30
+ const workspaceService = {
31
+ getOrCreateForUser: async () => ({ id: WS }),
32
+ getWorkspacePath: async () => '/tmp/ws',
33
+ } as never;
34
+ const workflowService = { listBranches: async () => [{ name: 'main', isProtected: true }] } as never;
35
+ const events = {} as never;
36
+
37
+ let httpServer: HttpServer | undefined;
38
+ const internalToken = new InternalTokenService({ secret: 'test-secret' });
39
+
40
+ async function start(): Promise<string> {
41
+ const registry = new ToolRegistry();
42
+ const toolAuth = createToolAuthMiddleware(externalApiKeyService, internalToken);
43
+ const resolve = createToolContextResolver({ authService, workspaceService, workflowService, events, kbDirName: 'knowledge-base', creatorAccess: { planForCreate: async () => null, grantInExtractedFile: async () => null, noteAccessFileWritten: () => {} } });
44
+ const toolHandler = createToolHandlerFactory(resolve);
45
+
46
+ registry.registerExternalTool(
47
+ toolDef({ name: 'list_branches', description: 'list', path: '/api/agent/tools/list_branches', inputs: { type: 'object', properties: {} } }),
48
+ );
49
+ registry.registerInternalTool(
50
+ toolDef({ name: 'list_branches', description: 'list', path: '/api/agent/tools/list_branches', inputs: { type: 'object', properties: {} } }),
51
+ );
52
+ registry.registerInternalTool(
53
+ toolDef({ name: 'touch', description: 'write', path: '/api/agent/tools/touch', inputs: { type: 'object', properties: {} }, tags: ['write'] }),
54
+ );
55
+
56
+ const app = express();
57
+ app.use(express.json());
58
+ app.post(
59
+ '/api/agent/tools/list_branches',
60
+ toolAuth,
61
+ toolHandler(async (_a: Record<string, unknown>, ctx: ToolContext) => ({
62
+ branches: await ctx.workflowService.listBranches('ws'),
63
+ ranAs: ctx.user.id,
64
+ source: ctx.source,
65
+ })),
66
+ );
67
+ // `touch` is internal-only (registered only via registerInternalTool) AND
68
+ // write-tagged — so its route carries the internal-source gate, mirroring the
69
+ // production mount helpers.
70
+ app.post(
71
+ '/api/agent/tools/touch',
72
+ toolAuth,
73
+ requireInternalSource,
74
+ toolHandler(async () => ({ ok: true }), { write: true }),
75
+ );
76
+ // Internal-only route: mounted (our agent reaches it over loopback) but gated.
77
+ app.post(
78
+ '/api/agent/tools/secret_internal',
79
+ toolAuth,
80
+ requireInternalSource,
81
+ toolHandler(async () => ({ ok: true })),
82
+ );
83
+ app.use('/api', createManualRoutes(registry, toolAuth));
84
+
85
+ httpServer = await new Promise<HttpServer>((resolve2) => {
86
+ const s = app.listen(0, () => resolve2(s));
87
+ });
88
+ const port = (httpServer.address() as { port: number }).port;
89
+ return `http://127.0.0.1:${port}`;
90
+ }
91
+
92
+ afterEach(async () => {
93
+ if (httpServer) await new Promise<void>((r) => httpServer!.close(() => r()));
94
+ httpServer = undefined;
95
+ });
96
+
97
+ const post = (url: string, bearer: string, body: unknown = {}) =>
98
+ fetch(url, { method: 'POST', headers: { 'content-type': 'application/json', authorization: `Bearer ${bearer}` }, body: JSON.stringify(body) });
99
+
100
+ const get = (url: string, bearer: string) => fetch(url, { headers: { authorization: `Bearer ${bearer}` } });
101
+
102
+ describe('tools surface — dual auth + scope + manuals', () => {
103
+ it('dispatches the same tool under BOTH a connection key and an internal token', async () => {
104
+ const base = await start();
105
+ const keyRes = await post(`${base}/api/agent/tools/list_branches`, 'bevel_good');
106
+ expect(keyRes.status).toBe(200);
107
+ expect(await keyRes.json()).toMatchObject({ branches: [{ name: 'main' }], ranAs: 'user-A', source: 'external' });
108
+
109
+ const intTok = internalToken.mint({ userId: 'user-A' });
110
+ const intRes = await post(`${base}/api/agent/tools/list_branches`, intTok);
111
+ expect(intRes.status).toBe(200);
112
+ expect(await intRes.json()).toMatchObject({ source: 'internal', ranAs: 'user-A' });
113
+ });
114
+
115
+ it('rejects a bad/absent bearer (401)', async () => {
116
+ const base = await start();
117
+ expect((await post(`${base}/api/agent/tools/list_branches`, 'nonsense')).status).toBe(401);
118
+ expect((await fetch(`${base}/api/agent/tools/list_branches`, { method: 'POST' })).status).toBe(401);
119
+ });
120
+
121
+ it('serves filtered manuals: internal has list_branches+touch, external only list_branches', async () => {
122
+ const base = await start();
123
+ const intTok = internalToken.mint({ userId: 'user-A' });
124
+ const internal = (await (await get(`${base}/api/agent/internal/utcp`, intTok)).json()) as { tools: { name: string }[] };
125
+ const external = (await (await get(`${base}/api/agent/utcp`, 'bevel_good')).json()) as { tools: { name: string }[] };
126
+ expect(internal.tools.map((t) => t.name).sort()).toEqual(['list_branches', 'touch']);
127
+ expect(external.tools.map((t) => t.name)).toEqual(['list_branches']);
128
+ });
129
+
130
+ it('refuses internal-only surfaces to an external connection key (403), but admits an internal token', async () => {
131
+ const base = await start();
132
+ const intTok = internalToken.mint({ userId: 'user-A' });
133
+
134
+ // The internal tool catalog: external key authenticates but is not internal.
135
+ expect((await get(`${base}/api/agent/internal/utcp`, 'bevel_good')).status).toBe(403);
136
+ expect((await get(`${base}/api/agent/internal/utcp`, intTok)).status).toBe(200);
137
+
138
+ // Internal-only tool routes, reached directly by name, are gated the same
139
+ // way — an external write-scope key can't bypass the catalog filtering by
140
+ // POSTing the route directly. (`touch` is also write-tagged.)
141
+ expect((await post(`${base}/api/agent/tools/secret_internal`, 'bevel_good')).status).toBe(403);
142
+ expect((await post(`${base}/api/agent/tools/secret_internal`, intTok)).status).toBe(200);
143
+ expect((await post(`${base}/api/agent/tools/touch`, 'bevel_good')).status).toBe(403);
144
+ expect((await post(`${base}/api/agent/tools/touch`, intTok)).status).toBe(200);
145
+ });
146
+ });
@@ -0,0 +1,75 @@
1
+ import { mkdtemp, rm, writeFile } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { InternalTokenService } from '../../tool-auth/internal-token.service.js';
6
+ import { createToolValidator } from '../validate-token.js';
7
+ import { hasHttpStatus } from '../tool.contract.js';
8
+
9
+ /**
10
+ * `validateToken` is the framework-agnostic SDK entry: bearer token → full
11
+ * `ToolContext`, fusing the shared verify core with the context resolver. These
12
+ * tests pin that contract (the same one a marketplace plugin will code against).
13
+ */
14
+
15
+ const internalToken = new InternalTokenService({ secret: 'test-secret' });
16
+ const externalApiKeyService = {
17
+ looksLikeExternalApiKey: (t: string) => typeof t === 'string' && t.startsWith('bevel_'),
18
+ verifyAndLoadToken: async (t: string) =>
19
+ t === 'bevel_ok' ? { user: { id: 'u-ext', email: 'e@x', name: 'Ext' }, tokenId: 'tk-1' } : null,
20
+ } as never;
21
+ const authService = { getUserById: async (id: string) => ({ id, email: 'e@x', name: 'N' }) } as never;
22
+
23
+ let tempDir = '';
24
+ const workspaceService = {
25
+ getWorkspacePath: async () => tempDir,
26
+ getOrCreateForUser: async () => ({ id: 'ext-ws' }),
27
+ } as never;
28
+
29
+ const validateToken = createToolValidator({
30
+ externalApiKeyService,
31
+ internalTokenService: internalToken,
32
+ authService,
33
+ workspaceService,
34
+ workflowService: {} as never,
35
+ events: {} as never,
36
+ kbDirName: 'knowledge-base',
37
+ creatorAccess: { planForCreate: async () => null, grantInExtractedFile: async () => null, noteAccessFileWritten: () => {} },
38
+ });
39
+
40
+ beforeEach(async () => {
41
+ tempDir = await mkdtemp(join(tmpdir(), 'validate-token-'));
42
+ await writeFile(join(tempDir, 'a.md'), 'hi');
43
+ });
44
+ afterEach(async () => {
45
+ if (tempDir) await rm(tempDir, { recursive: true, force: true });
46
+ tempDir = '';
47
+ });
48
+
49
+ describe('validateToken (tool-author SDK entry)', () => {
50
+ it('resolves an internal token to a write-scoped identity context (no workspace bound)', async () => {
51
+ const tok = internalToken.mint({ userId: 'u1' });
52
+ const ctx = await validateToken(tok);
53
+ expect(ctx).toMatchObject({ source: 'internal', scope: 'write' });
54
+ expect(ctx.user.id).toBe('u1');
55
+ });
56
+
57
+ it('resolves an external connection key to a write-scoped identity context', async () => {
58
+ const ctx = await validateToken('bevel_ok');
59
+ expect(ctx).toMatchObject({ source: 'external', scope: 'write' });
60
+ expect(ctx.user.id).toBe('u-ext');
61
+ });
62
+
63
+ it('getFilesystem(branch) builds the filesystem for that branch\'s workspace', async () => {
64
+ const tok = internalToken.mint({ userId: 'u1' });
65
+ const fs = await (await validateToken(tok)).getFilesystem('some/draft');
66
+ expect((await fs.readFile('a.md')).toString()).toBe('hi');
67
+ });
68
+
69
+ it('throws a 401 ToolError on a bad token and an empty token', async () => {
70
+ for (const bad of ['garbage', 'bevel_nope', '', undefined]) {
71
+ const err = await validateToken(bad as string).catch((e) => e);
72
+ expect(hasHttpStatus(err) && err.status).toBe(401);
73
+ }
74
+ });
75
+ });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The tool-author SDK — everything needed to build a tool, in ONE import.
3
+ * Internal tools use it today; it is the surface a third-party marketplace
4
+ * plugin will code against (eventually shipped as a standalone `@bevel-software/tool-sdk`
5
+ * package). A tool author never needs the registry internals, the Express
6
+ * middleware, or the internal-token service — only what is re-exported here.
7
+ *
8
+ * import { validateToken, toolDef, ToolError } from '<tool-sdk>';
9
+ *
10
+ * // in your endpoint:
11
+ * const ctx = await validateToken(bearerToken, body); // verify + resolve, throws ToolError
12
+ * const fs = await ctx.getFilesystem(); // lock-aware (write) / read-only (read)
13
+ * const def = toolDef({ name, description, inputs, path }); // self-describing UTCP Tool to register
14
+ */
15
+ export { createToolValidator, type ValidateToken, type ToolValidatorDeps } from './validate-token.js';
16
+ export { toolDef, type ToolDefSpec } from './tool-def.js';
17
+ export { ToolError, hasHttpStatus, type ToolContext, type ToolHandler } from './tool.contract.js';
18
+ export type { JsonSchema, UtcpTool } from '../tool-registry/tool.contract.js';
@@ -0,0 +1,98 @@
1
+ import { LocalFilesystem } from '@mastra/core/workspace';
2
+ import type { IWorkflowService } from '@bevel-software/platform-shared';
3
+ import { LockingFilesystem } from '../workflow/locking-filesystem.js';
4
+ import { ReadOnlyFilesystem } from '../workflow/read-only-filesystem.js';
5
+ import { makeRolesYamlWriteValidator } from '../access/roles-yaml-guard.js';
6
+ import type { ICreatorAccess } from '../access/creator-access.js';
7
+ import { branchForWorkspaceId, type WorkspaceService } from '../workspace/workspace.service.js';
8
+ import type { WorkflowEventBus } from '../workflow/event-bus.js';
9
+ import type { AuthService } from '../auth/auth.service.js';
10
+ import { ToolError, type ToolContext } from './tool.contract.js';
11
+ import type { ToolAuth } from '../tool-auth/tool-auth.middleware.js';
12
+
13
+ export interface ToolContextDeps {
14
+ authService: AuthService;
15
+ workspaceService: WorkspaceService;
16
+ workflowService: IWorkflowService;
17
+ events: WorkflowEventBus;
18
+ /** KB dir name — used to recognise (and validate) writes to `roles.yaml`. */
19
+ kbDirName: string;
20
+ /**
21
+ * Creator read-grant planner, threaded into the LockingFilesystem so agent
22
+ * creations in unreadable spots stay visible to the driving user (see
23
+ * `modules/access/creator-access`).
24
+ */
25
+ creatorAccess: ICreatorAccess;
26
+ }
27
+
28
+ export type ResolveToolContext = (
29
+ auth: ToolAuth,
30
+ abortSignal: AbortSignal,
31
+ sessionId?: string,
32
+ ) => Promise<ToolContext>;
33
+
34
+ /**
35
+ * Build the per-call `ToolContext` from a verified `ToolAuth`. Identity (user,
36
+ * scope, source) is resolved up front; the WORKSPACE is resolved on demand by
37
+ * `getFilesystem(branch)` and cached per branch. Internal and external callers
38
+ * are identical — the credential is identity-only, so the workspace always comes
39
+ * from the `branch` the tool passes (`getOrCreateForUser` clones the per-branch
40
+ * workspace if needed). A tool that never touches the KB never calls
41
+ * `getFilesystem`, so it resolves no workspace. Writes through the
42
+ * LockingFilesystem auto-commit+push as `user`. Framework-agnostic — never reads
43
+ * a request body; `branch` arrives as an explicit argument from the tool.
44
+ */
45
+ export function createToolContextResolver(deps: ToolContextDeps): ResolveToolContext {
46
+ // Reject an agent write that would leave roles.yaml unparseable (app-wide
47
+ // admin lockout) before it reaches disk — the agent gets a tool error and the
48
+ // file is untouched, mirroring the human editor's save-time gate.
49
+ const validateRolesWrite = makeRolesYamlWriteValidator(deps.kbDirName);
50
+
51
+ return async function resolveToolContext(auth, abortSignal, sessionId) {
52
+ const user = await deps.authService.getUserById(auth.userId);
53
+ if (!user) throw new ToolError('Your account is no longer available.', 401);
54
+
55
+ const fsCache = new Map<string, LocalFilesystem>();
56
+ const getFilesystem = async (branch: string): Promise<LocalFilesystem> => {
57
+ const cached = fsCache.get(branch);
58
+ if (cached) return cached;
59
+ const ws = await deps.workspaceService.getOrCreateForUser(user, branch);
60
+ const workspaceId = ws.id;
61
+ const basePath = await deps.workspaceService.getWorkspacePath(workspaceId);
62
+ const fs =
63
+ auth.scope === 'write'
64
+ ? new LockingFilesystem(
65
+ { basePath, contained: true },
66
+ {
67
+ workflow: deps.workflowService,
68
+ workspaceId,
69
+ branch: branchForWorkspaceId(workspaceId),
70
+ user,
71
+ validateWrite: validateRolesWrite,
72
+ creatorAccess: deps.creatorAccess,
73
+ },
74
+ )
75
+ : new ReadOnlyFilesystem({ basePath, contained: true });
76
+ fsCache.set(branch, fs);
77
+ return fs;
78
+ };
79
+
80
+ return {
81
+ user,
82
+ scope: auth.scope,
83
+ source: auth.source,
84
+ tokenId: auth.tokenId,
85
+ // For `internal` callers the signed token claim is the ONLY trustworthy
86
+ // session: honoring a body value would let one per-run token switch to a
87
+ // fresh `sessionId` and shed its accumulated touched-set. The body path is
88
+ // only for `external`/`session` callers, whose token carries no claim and
89
+ // whose `sessionId` is injected by the MCP proxy's continuity convention.
90
+ sessionId: auth.source === 'internal' ? auth.sessionId : sessionId ?? auth.sessionId,
91
+ abortSignal,
92
+ workspaceService: deps.workspaceService,
93
+ workflowService: deps.workflowService,
94
+ events: deps.events,
95
+ getFilesystem,
96
+ };
97
+ };
98
+ }
@@ -0,0 +1,73 @@
1
+ import '@utcp/http';
2
+ import { HttpCallTemplateSerializer } from '@utcp/http';
3
+ import { ToolSerializer } from '@utcp/sdk';
4
+ import type { JsonSchema, UtcpTool } from '../tool-registry/tool.contract.js';
5
+
6
+ const httpTemplate = new HttpCallTemplateSerializer();
7
+ const toolSerializer = new ToolSerializer();
8
+
9
+ /**
10
+ * The required `branch` input every KB tool declares — the model names the
11
+ * workspace (draft) the call acts on. Since the credential is identity-only
12
+ * (internal token == connection key), the workspace is never implied; it always
13
+ * comes from this argument.
14
+ */
15
+ export const BRANCH_INPUT: JsonSchema = {
16
+ type: 'string',
17
+ minLength: 1,
18
+ description: 'The branch (draft) whose workspace this operates on — pass the branch you are currently working on.',
19
+ };
20
+
21
+ /** Add a required `branch` property to an object input schema (KB tools). */
22
+ export function withBranchInput(inputs: JsonSchema): JsonSchema {
23
+ const o = inputs as { properties?: Record<string, JsonSchema>; required?: string[] };
24
+ return {
25
+ ...inputs,
26
+ properties: { ...(o.properties ?? {}), branch: BRANCH_INPUT },
27
+ required: [...new Set([...(o.required ?? []), 'branch'])],
28
+ } as JsonSchema;
29
+ }
30
+
31
+ export interface ToolDefSpec {
32
+ /** Unique within its surface; also the namespace member the agent calls (`Bevel.<name>`). */
33
+ name: string;
34
+ description: string;
35
+ /** The LOGICAL (flat) input schema — what the handler receives and the agent passes. */
36
+ inputs: JsonSchema;
37
+ outputs?: JsonSchema;
38
+ tags?: string[];
39
+ /** The route the owning module hosts, e.g. `/agent/tools/list_branches`. */
40
+ path: string;
41
+ }
42
+
43
+ /**
44
+ * Build a self-describing UTCP `Tool` def for a module-hosted endpoint. The flat
45
+ * `inputs` are wrapped under a single `body` property (`body_field: 'body'`) —
46
+ * the only standard-http way to ride multiple fields in the JSON body — so the
47
+ * agent calls `Bevel.<name>({ body: { ... } })` and the endpoint reads `req.body`
48
+ * as the flat args. The URL + bearer are `${API_URL}` / `${CONNECTION_KEY}`
49
+ * placeholders the consumer resolves (public URL + key for external; loopback +
50
+ * internal token for our agent), so one def serves both surfaces.
51
+ */
52
+ export function toolDef(spec: ToolDefSpec): UtcpTool {
53
+ return toolSerializer.validateDict({
54
+ name: spec.name,
55
+ description: spec.description,
56
+ inputs: {
57
+ type: 'object',
58
+ properties: { body: spec.inputs },
59
+ required: ['body'],
60
+ additionalProperties: false,
61
+ },
62
+ outputs: spec.outputs ?? { type: 'object', properties: {} },
63
+ tags: spec.tags ?? [],
64
+ tool_call_template: httpTemplate.validateDict({
65
+ call_template_type: 'http',
66
+ http_method: 'POST',
67
+ url: `\${API_URL}${spec.path}`,
68
+ content_type: 'application/json',
69
+ headers: { Authorization: 'Bearer ${CONNECTION_KEY}' },
70
+ body_field: 'body',
71
+ }),
72
+ });
73
+ }