@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,526 @@
1
+ import express from 'express';
2
+ import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
3
+ import { DEFAULT_BRANCH } from '@bevel-software/platform-shared';
4
+ import {
5
+ InvalidSecretError,
6
+ SecretNotFoundError,
7
+ SecretOAuthError,
8
+ scopesCovered,
9
+ missingScopes,
10
+ type ISecretsVaultService,
11
+ } from './secrets-vault.contract.js';
12
+ import type { IToolManualService, ToolManualSummary, ToolVariable } from '../tool-manuals/tool-manuals.contract.js';
13
+ import { utcpNamespacedKey } from '../../shared/utcp-namespace.js';
14
+ import type { IAccessControl } from '../access/access-control.interface.js';
15
+ import { workspaceIdForBranch } from '../workspace/workspace.service.js';
16
+ import '../auth/auth.middleware.js'; // Express Request augmentation (req.userId / req.userEmail)
17
+
18
+ export interface SecretsVaultRoutesDeps {
19
+ secretsVault: ISecretsVaultService;
20
+ /** Source of `.tool` manuals + their declared variable scopes (default-branch catalog). */
21
+ toolManualService: IToolManualService;
22
+ /** Gates who may set a tool's ADMIN (shared) secrets — writers of the `.tool` file. */
23
+ accessControl: IAccessControl;
24
+ /** HMAC secret for signing the OAuth `state` (reuse the connector state secret). */
25
+ stateSecret: string;
26
+ /** Public base URL of THIS backend — builds the OAuth redirect URI. */
27
+ publicBackendUrl: string;
28
+ /** Public base URL of the SPA — where the OAuth callback lands the browser. */
29
+ publicFrontendUrl: string;
30
+ }
31
+
32
+ function redirectUriFor(publicBackendUrl: string): string {
33
+ return `${publicBackendUrl}/api/secrets/oauth/callback`;
34
+ }
35
+
36
+ /**
37
+ * Authenticated Secrets Vault CRUD + OAuth start. Every route is scoped to
38
+ * `req.userId` — secrets are private per user. Mounted behind the JWT middleware.
39
+ */
40
+ export function createSecretsVaultRoutes(deps: SecretsVaultRoutesDeps): express.Router {
41
+ const { secretsVault, toolManualService, accessControl } = deps;
42
+ const router = express.Router();
43
+ const defaultWs = workspaceIdForBranch(DEFAULT_BRANCH);
44
+
45
+ // The vault key = the exact key UTCP looks the var up under (doubles underscores
46
+ // in the manual namespace), so storage and resolution agree for snake_case ids.
47
+ const varKey = (manualName: string, varName: string) => utcpNamespacedKey(manualName, varName);
48
+
49
+ /** Find an accessible (readable) manual by slug + its DECLARED variable, or null. */
50
+ async function findManualVar(
51
+ email: string,
52
+ slug: string,
53
+ varName: string,
54
+ ): Promise<{ manual: ToolManualSummary; variable: ToolVariable } | null> {
55
+ const manual = (await toolManualService.listAccessible(email)).find((m) => m.slug === slug);
56
+ if (!manual) return null;
57
+ const variable = (manual.variables ?? []).find((v) => v.name === varName);
58
+ return variable ? { manual, variable } : null;
59
+ }
60
+
61
+ router.get('/secrets', async (req, res) => {
62
+ const userId = req.userId;
63
+ if (!userId) return void res.status(401).json({ error: 'Not authenticated' });
64
+ try {
65
+ res.json({ secrets: await secretsVault.list(userId) });
66
+ } catch (err) {
67
+ console.error('[secrets] list failed:', err);
68
+ res.status(500).json({ error: 'Internal error' });
69
+ }
70
+ });
71
+
72
+ router.post('/secrets/static', async (req, res) => {
73
+ const userId = req.userId;
74
+ if (!userId) return void res.status(401).json({ error: 'Not authenticated' });
75
+ try {
76
+ const body = req.body ?? {};
77
+ const secret = await secretsVault.putStatic({
78
+ userId,
79
+ key: body.key,
80
+ value: body.value,
81
+ label: body.label,
82
+ });
83
+ res.status(201).json({ secret });
84
+ } catch (err) {
85
+ mapError(err, res, 'create static');
86
+ }
87
+ });
88
+
89
+ router.post('/secrets/oauth', async (req, res) => {
90
+ const userId = req.userId;
91
+ if (!userId) return void res.status(401).json({ error: 'Not authenticated' });
92
+ try {
93
+ const body = req.body ?? {};
94
+ const secret = await secretsVault.createOAuth({
95
+ userId,
96
+ key: body.key,
97
+ label: body.label,
98
+ provider: body.provider,
99
+ });
100
+ res.status(201).json({ secret });
101
+ } catch (err) {
102
+ mapError(err, res, 'create oauth');
103
+ }
104
+ });
105
+
106
+ router.delete('/secrets/:id', async (req, res) => {
107
+ const userId = req.userId;
108
+ if (!userId) return void res.status(401).json({ error: 'Not authenticated' });
109
+ try {
110
+ await secretsVault.remove(userId, req.params.id);
111
+ res.status(204).end();
112
+ } catch (err) {
113
+ mapError(err, res, 'delete');
114
+ }
115
+ });
116
+
117
+ // Return the provider consent URL as JSON (not a 302): the SPA fetches this
118
+ // with its bearer token, then navigates the browser to the URL.
119
+ router.get('/secrets/:id/oauth/start', async (req, res) => {
120
+ const userId = req.userId;
121
+ if (!userId) return void res.status(401).json({ error: 'Not authenticated' });
122
+ try {
123
+ const secret = await secretsVault.getById(userId, req.params.id);
124
+ if (!secret) return void res.status(404).json({ error: 'Secret not found' });
125
+ if (secret.kind !== 'oauth') return void res.status(400).json({ error: 'Secret has no OAuth flow' });
126
+ const state = signState(deps.stateSecret, {
127
+ u: userId,
128
+ i: req.params.id,
129
+ n: randomBytes(8).toString('hex'),
130
+ });
131
+ const url = await secretsVault.beginOAuth(
132
+ userId,
133
+ req.params.id,
134
+ redirectUriFor(deps.publicBackendUrl),
135
+ state,
136
+ );
137
+ res.json({ url });
138
+ } catch (err) {
139
+ mapError(err, res, 'oauth start');
140
+ }
141
+ });
142
+
143
+ // ---- per-tool secrets (two-tier: admin/shared + per-user) ------------------
144
+
145
+ // The caller's accessible `.tool` manuals, each with its declared variables,
146
+ // per-variable config status, and whether the caller may set ADMIN secrets.
147
+ // `?path=` narrows to a single tool (used by the `.tool` editor sidebar).
148
+ router.get('/secrets/tools', async (req, res) => {
149
+ const userId = req.userId;
150
+ const email = req.userEmail;
151
+ if (!userId || !email) return void res.status(401).json({ error: 'Not authenticated' });
152
+ try {
153
+ const pathFilter = typeof req.query.path === 'string' ? req.query.path : null;
154
+ let manuals = await toolManualService.listAccessible(email);
155
+ if (pathFilter) manuals = manuals.filter((m) => m.path === pathFilter);
156
+
157
+ const allKeys = manuals.flatMap((m) => (m.variables ?? []).map((v) => varKey(m.name, v.name)));
158
+ const status = await secretsVault.statusFor(userId, allKeys);
159
+ const statusByKey = new Map(status.map((s) => [s.key, s]));
160
+
161
+ const tools = await Promise.all(
162
+ manuals.map(async (m) => ({
163
+ slug: m.slug,
164
+ name: m.name,
165
+ path: m.path,
166
+ type: m.type,
167
+ setup: m.setup ?? null,
168
+ canWrite: await accessControl.canWrite(defaultWs, email, m.path),
169
+ variables: (m.variables ?? []).map((v) => {
170
+ const key = varKey(m.name, v.name);
171
+ const st = statusByKey.get(key);
172
+ const isOAuth = v.oauth != null;
173
+ const authorized = isOAuth ? (st?.userAuthorized ?? false) : undefined;
174
+ // For an OAuth var: which declared permissions the token doesn't cover,
175
+ // so the panel can say WHAT it works for and what it doesn't. Only
176
+ // meaningful once authorized (an unauthorized var has no token at all).
177
+ const missing = isOAuth && authorized ? missingScopes(v.oauth?.scopes, st?.grantedScopes) : [];
178
+ return {
179
+ name: v.name,
180
+ scope: v.scope,
181
+ label: v.label ?? null,
182
+ key,
183
+ adminConfigured: st?.adminConfigured ?? false,
184
+ userConfigured: st?.userConfigured ?? false,
185
+ oauth: isOAuth,
186
+ authorized,
187
+ needsReauth: isOAuth && authorized === true && missing.length > 0,
188
+ missingScopes: missing,
189
+ };
190
+ }),
191
+ })),
192
+ );
193
+ res.json({ tools });
194
+ } catch (err) {
195
+ console.error('[secrets] list tools failed:', err);
196
+ res.status(500).json({ error: 'Internal error' });
197
+ }
198
+ });
199
+
200
+ // The aggregated "connect your tools" view for a single user: every accessible
201
+ // tool with ONLY its per-user (`user`-scoped) variables and whether the caller
202
+ // has set each, plus the caller's OAuth secrets and their authorized state. This
203
+ // is the surface an external-agent user lands on from the needs-authorization
204
+ // link — it shows exactly what THEY must provide, never the admin/shared items.
205
+ router.get('/connect/pending', async (req, res) => {
206
+ const userId = req.userId;
207
+ const email = req.userEmail;
208
+ if (!userId || !email) return void res.status(401).json({ error: 'Not authenticated' });
209
+ try {
210
+ const manuals = await toolManualService.listAccessible(email);
211
+ const allKeys = manuals.flatMap((m) =>
212
+ (m.variables ?? []).filter((v) => v.scope === 'user').map((v) => varKey(m.name, v.name)),
213
+ );
214
+ const status = await secretsVault.statusFor(userId, allKeys);
215
+ const statusByKey = new Map(status.map((s) => [s.key, s]));
216
+
217
+ const tools = manuals
218
+ .map((m) => ({
219
+ slug: m.slug,
220
+ name: m.name,
221
+ path: m.path,
222
+ type: m.type,
223
+ // Plain (non-OAuth) per-user vars render as key inputs under "Keys".
224
+ variables: (m.variables ?? [])
225
+ .filter((v) => v.scope === 'user' && !v.oauth)
226
+ .map((v) => {
227
+ const key = varKey(m.name, v.name);
228
+ return {
229
+ name: v.name,
230
+ label: v.label ?? null,
231
+ key,
232
+ configured: statusByKey.get(key)?.userConfigured ?? false,
233
+ };
234
+ }),
235
+ }))
236
+ // Only surface tools that actually have per-user items to configure.
237
+ .filter((t) => t.variables.length > 0);
238
+
239
+ // OAuth-backed per-user vars render as Authorize buttons under "Sign-ins".
240
+ // Keyed by slug+var (the caller's row may not exist yet), with authorized
241
+ // state from the oauth-aware status.
242
+ const toolOAuth = manuals.flatMap((m) =>
243
+ (m.variables ?? [])
244
+ .filter((v) => v.scope === 'user' && v.oauth)
245
+ .map((v) => {
246
+ const st = statusByKey.get(varKey(m.name, v.name));
247
+ const authorized = st?.userAuthorized ?? false;
248
+ // Signed in, but the token's granted scopes no longer cover what the
249
+ // tool declares → surface as needing re-authorization, not as connected.
250
+ const needsReauth =
251
+ authorized && !scopesCovered(v.oauth?.scopes, st?.grantedScopes);
252
+ return {
253
+ slug: m.slug,
254
+ varName: v.name,
255
+ toolName: m.name,
256
+ key: varKey(m.name, v.name),
257
+ label: v.label ?? null,
258
+ authorized,
259
+ needsReauth,
260
+ };
261
+ }),
262
+ );
263
+
264
+ // Standalone sign-ins = oauth secrets the user registered directly on the
265
+ // Secrets page. A TOOL sign-in provisions a per-user row in the same
266
+ // table (keyed `<manual>_<VAR>`), so exclude every tool-var key here or
267
+ // an authorized tool sign-in would render twice — once as a toolOAuth
268
+ // row and again as a "standalone" one.
269
+ const toolOAuthKeys = new Set(toolOAuth.map((o) => o.key));
270
+ const secrets = await secretsVault.list(userId);
271
+ const oauth = secrets
272
+ .filter((s) => s.kind === 'oauth' && !toolOAuthKeys.has(s.key))
273
+ .map((s) => ({ id: s.id, key: s.key, label: s.label, authorized: s.authorized ?? false }));
274
+
275
+ res.json({ tools, oauth, toolOAuth });
276
+ } catch (err) {
277
+ console.error('[secrets] connect/pending failed:', err);
278
+ res.status(500).json({ error: 'Internal error' });
279
+ }
280
+ });
281
+
282
+ // Set/replace a tool's ADMIN (shared) secret — requires WRITE on the `.tool` file.
283
+ router.put('/secrets/tools/:slug/vars/:var/admin', async (req, res) => {
284
+ const userId = req.userId;
285
+ const email = req.userEmail;
286
+ if (!userId || !email) return void res.status(401).json({ error: 'Not authenticated' });
287
+ try {
288
+ const found = await findManualVar(email, req.params.slug, req.params.var);
289
+ if (!found) return void res.status(404).json({ error: 'Tool or variable not found' });
290
+ if (found.variable.scope !== 'admin') {
291
+ return void res.status(422).json({ error: 'This variable is set by each user, not the tool owner.' });
292
+ }
293
+ if (!(await accessControl.canWrite(defaultWs, email, found.manual.path))) {
294
+ return void res.status(403).json({ error: 'You need write access to this tool to set its shared secrets.' });
295
+ }
296
+ const body = req.body ?? {};
297
+ const secret = await secretsVault.putSharedStatic({
298
+ key: varKey(found.manual.name, found.variable.name),
299
+ value: body.value,
300
+ label: body.label,
301
+ });
302
+ res.status(201).json({ secret });
303
+ } catch (err) {
304
+ mapError(err, res, 'set admin var');
305
+ }
306
+ });
307
+
308
+ // Set/replace the CALLER's per-user secret for a user-scope variable.
309
+ router.put('/secrets/tools/:slug/vars/:var/user', async (req, res) => {
310
+ const userId = req.userId;
311
+ const email = req.userEmail;
312
+ if (!userId || !email) return void res.status(401).json({ error: 'Not authenticated' });
313
+ try {
314
+ const found = await findManualVar(email, req.params.slug, req.params.var);
315
+ if (!found) return void res.status(404).json({ error: 'Tool or variable not found' });
316
+ if (found.variable.scope !== 'user') {
317
+ return void res.status(422).json({ error: 'This variable is set by the tool owner, not per user.' });
318
+ }
319
+ const body = req.body ?? {};
320
+ const secret = await secretsVault.putStatic({
321
+ userId,
322
+ key: varKey(found.manual.name, found.variable.name),
323
+ value: body.value,
324
+ label: body.label,
325
+ });
326
+ res.status(201).json({ secret });
327
+ } catch (err) {
328
+ mapError(err, res, 'set user var');
329
+ }
330
+ });
331
+
332
+ // Set the confidential client secret for a tool's OAuth-backed variable — the
333
+ // ONLY place the secret is provided. Requires WRITE on the `.tool`. The provider
334
+ // config comes from the variable's own `oauth` declaration (stored WITH the
335
+ // secret so a later `.tool` edit can't redirect it).
336
+ router.put('/secrets/tools/:slug/vars/:var/oauth/admin', async (req, res) => {
337
+ const userId = req.userId;
338
+ const email = req.userEmail;
339
+ if (!userId || !email) return void res.status(401).json({ error: 'Not authenticated' });
340
+ try {
341
+ const found = await findManualVar(email, req.params.slug, req.params.var);
342
+ if (!found) return void res.status(404).json({ error: 'Tool or variable not found' });
343
+ if (!found.variable.oauth) {
344
+ return void res.status(422).json({ error: 'This variable is not an OAuth sign-in.' });
345
+ }
346
+ if (!(await accessControl.canWrite(defaultWs, email, found.manual.path))) {
347
+ return void res.status(403).json({ error: 'You need write access to this tool to set its client secret.' });
348
+ }
349
+ const clientSecret = (req.body ?? {}).clientSecret;
350
+ await secretsVault.putSharedOAuthClientSecret({
351
+ key: varKey(found.manual.name, found.variable.name),
352
+ clientSecret,
353
+ provider: {
354
+ authorizationUrl: found.variable.oauth.authorizationUrl,
355
+ tokenUrl: found.variable.oauth.tokenUrl,
356
+ clientId: found.variable.oauth.clientId,
357
+ scopes: found.variable.oauth.scopes,
358
+ // Static authorize params (e.g. Google's `access_type=offline`) so the
359
+ // provider returns a refresh token — stored with the secret so a later
360
+ // `.tool` edit can't redirect the flow.
361
+ authParams: found.variable.oauth.authParams,
362
+ },
363
+ });
364
+ res.status(201).json({ ok: true });
365
+ } catch (err) {
366
+ mapError(err, res, 'set oauth client secret');
367
+ }
368
+ });
369
+
370
+ // Start sign-in for a tool's OAuth-backed variable. Provisions the caller's row
371
+ // from the owner-set secret and returns the provider consent URL; the callback
372
+ // bounces back to /connect (via `r` in the signed state).
373
+ router.post('/secrets/tools/:slug/vars/:var/oauth/start', async (req, res) => {
374
+ const userId = req.userId;
375
+ const email = req.userEmail;
376
+ if (!userId || !email) return void res.status(401).json({ error: 'Not authenticated' });
377
+ try {
378
+ const found = await findManualVar(email, req.params.slug, req.params.var);
379
+ if (!found) return void res.status(404).json({ error: 'Tool or variable not found' });
380
+ if (!found.variable.oauth) {
381
+ return void res.status(422).json({ error: 'This variable is not an OAuth sign-in.' });
382
+ }
383
+ const key = varKey(found.manual.name, found.variable.name);
384
+ // Provision the caller's oauth row (from the owner-set secret) FIRST — its id
385
+ // is what the un-authed callback keys on. Pass an empty state placeholder; we
386
+ // sign the real state below with the returned id and swap it into the URL, so
387
+ // the callback resolves it byte-for-byte like the standalone flow.
388
+ const { id, url } = await secretsVault.beginToolOAuthByKey({
389
+ userId,
390
+ key,
391
+ redirectUri: redirectUriFor(deps.publicBackendUrl),
392
+ state: '',
393
+ // Request the permissions the tool file declares RIGHT NOW (not the frozen
394
+ // copy on the owner-set row), so adding a scope to the `.tool` takes effect
395
+ // on the next sign-in. The secret/clientId/addresses stay owner-pinned.
396
+ scopes: found.variable.oauth.scopes,
397
+ });
398
+ const state = signState(deps.stateSecret, {
399
+ u: userId,
400
+ i: id,
401
+ n: randomBytes(8).toString('hex'),
402
+ r: 'connect',
403
+ });
404
+ const consentUrl = new URL(url);
405
+ consentUrl.searchParams.set('state', state);
406
+ res.json({ url: consentUrl.toString() });
407
+ } catch (err) {
408
+ mapError(err, res, 'tool oauth start');
409
+ }
410
+ });
411
+
412
+ router.delete('/secrets/tools/:slug/vars/:var/admin', async (req, res) => {
413
+ const userId = req.userId;
414
+ const email = req.userEmail;
415
+ if (!userId || !email) return void res.status(401).json({ error: 'Not authenticated' });
416
+ try {
417
+ const found = await findManualVar(email, req.params.slug, req.params.var);
418
+ if (!found) return void res.status(404).json({ error: 'Tool or variable not found' });
419
+ if (!(await accessControl.canWrite(defaultWs, email, found.manual.path))) {
420
+ return void res.status(403).json({ error: 'You need write access to this tool to remove its shared secrets.' });
421
+ }
422
+ await secretsVault.removeShared(varKey(found.manual.name, found.variable.name));
423
+ res.status(204).end();
424
+ } catch (err) {
425
+ mapError(err, res, 'delete admin var');
426
+ }
427
+ });
428
+
429
+ router.delete('/secrets/tools/:slug/vars/:var/user', async (req, res) => {
430
+ const userId = req.userId;
431
+ const email = req.userEmail;
432
+ if (!userId || !email) return void res.status(401).json({ error: 'Not authenticated' });
433
+ try {
434
+ const found = await findManualVar(email, req.params.slug, req.params.var);
435
+ if (!found) return void res.status(404).json({ error: 'Tool or variable not found' });
436
+ await secretsVault.removeUserByKey(userId, varKey(found.manual.name, found.variable.name));
437
+ res.status(204).end();
438
+ } catch (err) {
439
+ mapError(err, res, 'delete user var');
440
+ }
441
+ });
442
+
443
+ return router;
444
+ }
445
+
446
+ /**
447
+ * The un-authenticated OAuth callback. Mounted BEFORE the JWT middleware: the
448
+ * provider redirects the browser here with no Authorization header, so the
449
+ * caller's identity rides in the signed `state`.
450
+ */
451
+ export function createSecretsVaultPublicRoutes(deps: SecretsVaultRoutesDeps): express.Router {
452
+ const { secretsVault } = deps;
453
+ const router = express.Router();
454
+
455
+ router.get('/secrets/oauth/callback', async (req, res) => {
456
+ const code = typeof req.query.code === 'string' ? req.query.code : '';
457
+ const stateRaw = typeof req.query.state === 'string' ? req.query.state : '';
458
+ // The landing page depends on where the flow started (the `r` field in the
459
+ // signed state): a tool-var sign-in returns to /connect, the standalone
460
+ // Secrets page to /secrets. Pre-verification errors can't know `r`, so they
461
+ // fall back to /secrets.
462
+ const back = (frag: string, dest = '/secrets') =>
463
+ res.redirect(`${deps.publicFrontendUrl}${dest}#${frag}`);
464
+ if (!code || !stateRaw) return void back(`error=${encodeURIComponent('Invalid OAuth callback.')}`);
465
+
466
+ const state = verifyState(deps.stateSecret, stateRaw);
467
+ if (!state) return void back(`error=${encodeURIComponent('OAuth state mismatch.')}`);
468
+ const dest = state.r === 'connect' ? '/connect' : '/secrets';
469
+
470
+ try {
471
+ await secretsVault.completeOAuth(state.u, state.i, code, redirectUriFor(deps.publicBackendUrl));
472
+ back(`authorized=${encodeURIComponent(state.i)}`, dest);
473
+ } catch (err) {
474
+ console.error('[secrets] oauth callback failed:', err instanceof Error ? err.message : String(err));
475
+ back(`error=${encodeURIComponent('Authorization failed. Check the provider configuration and try again.')}`, dest);
476
+ }
477
+ });
478
+
479
+ return router;
480
+ }
481
+
482
+ function mapError(err: unknown, res: express.Response, op: string): void {
483
+ if (err instanceof InvalidSecretError) return void res.status(422).json({ error: err.message });
484
+ if (err instanceof SecretNotFoundError) return void res.status(404).json({ error: err.message });
485
+ if (err instanceof SecretOAuthError) return void res.status(409).json({ error: err.message });
486
+ console.error(`[secrets] ${op} failed:`, err);
487
+ res.status(500).json({ error: 'Internal error' });
488
+ }
489
+
490
+ // ---- signed-state helpers (CSRF + identity for the un-authed callback) -------
491
+
492
+ interface OAuthState {
493
+ u: string; // user id
494
+ i: string; // secret id
495
+ n: string; // nonce
496
+ iat: number; // issued-at (epoch ms)
497
+ r?: string; // return path hint ('connect' → land on /connect; else /secrets)
498
+ }
499
+
500
+ const OAUTH_STATE_MAX_AGE_MS = 10 * 60_000;
501
+ const OAUTH_STATE_SKEW_MS = 60_000;
502
+
503
+ function signState(secret: string, state: Omit<OAuthState, 'iat'>): string {
504
+ const full: OAuthState = { ...state, iat: Date.now() };
505
+ const body = Buffer.from(JSON.stringify(full)).toString('base64url');
506
+ const sig = createHmac('sha256', secret).update(body).digest('base64url');
507
+ return `${body}.${sig}`;
508
+ }
509
+
510
+ function verifyState(secret: string, token: string): OAuthState | null {
511
+ const [body, sig] = token.split('.');
512
+ if (!body || !sig) return null;
513
+ const expected = createHmac('sha256', secret).update(body).digest('base64url');
514
+ const a = Buffer.from(sig);
515
+ const b = Buffer.from(expected);
516
+ if (a.length !== b.length || !timingSafeEqual(a, b)) return null;
517
+ try {
518
+ const parsed = JSON.parse(Buffer.from(body, 'base64url').toString()) as OAuthState;
519
+ if (typeof parsed.iat !== 'number' || !parsed.u || !parsed.i) return null;
520
+ const age = Date.now() - parsed.iat;
521
+ if (age > OAUTH_STATE_MAX_AGE_MS || age < -OAUTH_STATE_SKEW_MS) return null;
522
+ return parsed;
523
+ } catch {
524
+ return null;
525
+ }
526
+ }