@bevel-software/platform-core-backend 0.32.0 → 0.33.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 (958) hide show
  1. package/agent-guide/access-control.md +5 -0
  2. package/agent-guide/html-views.md +46 -10
  3. package/dist/core/create-core-server.d.ts.map +1 -1
  4. package/dist/core/create-core-server.js +29 -4
  5. package/dist/core/create-core-server.js.map +1 -1
  6. package/dist/core/create-core-services.d.ts +7 -2
  7. package/dist/core/create-core-services.d.ts.map +1 -1
  8. package/dist/core/create-core-services.js +22 -6
  9. package/dist/core/create-core-services.js.map +1 -1
  10. package/dist/core/lifecycle.d.ts +8 -0
  11. package/dist/core/lifecycle.d.ts.map +1 -1
  12. package/dist/core/lifecycle.js +4 -0
  13. package/dist/core/lifecycle.js.map +1 -1
  14. package/dist/core/public-config.d.ts +10 -0
  15. package/dist/core/public-config.d.ts.map +1 -1
  16. package/dist/core/public-config.js +10 -0
  17. package/dist/core/public-config.js.map +1 -1
  18. package/dist/modules/access/access-control.service.d.ts +3 -3
  19. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  20. package/dist/modules/access/access-control.service.js +4 -5
  21. package/dist/modules/access/access-control.service.js.map +1 -1
  22. package/dist/modules/access/access-declarations.d.ts +1 -1
  23. package/dist/modules/access/access-declarations.d.ts.map +1 -1
  24. package/dist/modules/access/access-declarations.js +1 -1
  25. package/dist/modules/access/access-declarations.js.map +1 -1
  26. package/dist/modules/access/access-mutation.service.d.ts +8 -3
  27. package/dist/modules/access/access-mutation.service.d.ts.map +1 -1
  28. package/dist/modules/access/access-mutation.service.js +3 -3
  29. package/dist/modules/access/access-mutation.service.js.map +1 -1
  30. package/dist/modules/access/access-requests.contract.d.ts +1 -1
  31. package/dist/modules/access/access-requests.contract.d.ts.map +1 -1
  32. package/dist/modules/access/access-requests.routes.d.ts +3 -3
  33. package/dist/modules/access/access-requests.routes.d.ts.map +1 -1
  34. package/dist/modules/access/access-requests.routes.js +7 -7
  35. package/dist/modules/access/access-requests.routes.js.map +1 -1
  36. package/dist/modules/access/access-requests.service.d.ts +21 -20
  37. package/dist/modules/access/access-requests.service.d.ts.map +1 -1
  38. package/dist/modules/access/access-requests.service.js +22 -68
  39. package/dist/modules/access/access-requests.service.js.map +1 -1
  40. package/dist/modules/access/access-view.d.ts +1 -1
  41. package/dist/modules/access/access-view.d.ts.map +1 -1
  42. package/dist/modules/access/access-view.js +1 -1
  43. package/dist/modules/access/access-view.js.map +1 -1
  44. package/dist/modules/access/access.routes.d.ts +5 -7
  45. package/dist/modules/access/access.routes.d.ts.map +1 -1
  46. package/dist/modules/access/access.routes.js +4 -4
  47. package/dist/modules/access/access.routes.js.map +1 -1
  48. package/dist/modules/access/admin-locked-commit.d.ts +2 -2
  49. package/dist/modules/access/admin-locked-commit.d.ts.map +1 -1
  50. package/dist/modules/access/admin-locked-commit.js +1 -1
  51. package/dist/modules/access/admin-locked-commit.js.map +1 -1
  52. package/dist/modules/access/capability-registry.js +1 -1
  53. package/dist/modules/access/capability-registry.js.map +1 -1
  54. package/dist/modules/access/change-read-gate.d.ts +2 -2
  55. package/dist/modules/access/change-read-gate.d.ts.map +1 -1
  56. package/dist/modules/access/change-read-gate.js +1 -3
  57. package/dist/modules/access/change-read-gate.js.map +1 -1
  58. package/dist/modules/access/creator-access.d.ts +2 -2
  59. package/dist/modules/access/creator-access.d.ts.map +1 -1
  60. package/dist/modules/access/creator-access.js +2 -4
  61. package/dist/modules/access/creator-access.js.map +1 -1
  62. package/dist/modules/access/directory-sync-bot.d.ts +1 -1
  63. package/dist/modules/access/directory-sync-bot.d.ts.map +1 -1
  64. package/dist/modules/access/directory-sync-bot.js +1 -1
  65. package/dist/modules/access/directory-sync-bot.js.map +1 -1
  66. package/dist/modules/access/groups-admin.routes.d.ts +2 -2
  67. package/dist/modules/access/groups-admin.routes.d.ts.map +1 -1
  68. package/dist/modules/access/groups-admin.routes.js +2 -2
  69. package/dist/modules/access/groups-admin.routes.js.map +1 -1
  70. package/dist/modules/access/groups-admin.service.d.ts +1 -1
  71. package/dist/modules/access/groups-admin.service.d.ts.map +1 -1
  72. package/dist/modules/access/groups-admin.service.js +2 -3
  73. package/dist/modules/access/groups-admin.service.js.map +1 -1
  74. package/dist/modules/access/groups-edit.js +2 -2
  75. package/dist/modules/access/groups-edit.js.map +1 -1
  76. package/dist/modules/access/index.d.ts +17 -0
  77. package/dist/modules/access/index.d.ts.map +1 -0
  78. package/dist/modules/access/index.js +6 -0
  79. package/dist/modules/access/index.js.map +1 -0
  80. package/dist/modules/access/reference-scan.js +1 -1
  81. package/dist/modules/access/reference-scan.js.map +1 -1
  82. package/dist/modules/access/roles-admin.service.d.ts +1 -1
  83. package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
  84. package/dist/modules/access/roles-admin.service.js +2 -5
  85. package/dist/modules/access/roles-admin.service.js.map +1 -1
  86. package/dist/modules/access/roles-edit.js +1 -1
  87. package/dist/modules/access/roles-edit.js.map +1 -1
  88. package/dist/modules/access/synced-groups-committer.d.ts +2 -2
  89. package/dist/modules/access/synced-groups-committer.d.ts.map +1 -1
  90. package/dist/modules/access/synced-groups-committer.js +2 -2
  91. package/dist/modules/access/synced-groups-committer.js.map +1 -1
  92. package/dist/modules/access/synced-groups-writer.js +2 -2
  93. package/dist/modules/access/synced-groups-writer.js.map +1 -1
  94. package/dist/modules/access/user-access-removal.service.d.ts +1 -1
  95. package/dist/modules/access/user-access-removal.service.d.ts.map +1 -1
  96. package/dist/modules/access/user-access-removal.service.js +2 -5
  97. package/dist/modules/access/user-access-removal.service.js.map +1 -1
  98. package/dist/modules/access-model/index.d.ts +20 -5
  99. package/dist/modules/access-model/index.d.ts.map +1 -1
  100. package/dist/modules/access-model/index.js +18 -5
  101. package/dist/modules/access-model/index.js.map +1 -1
  102. package/dist/modules/access-model/roles-yaml-guard.d.ts +1 -1
  103. package/dist/modules/access-model/roles-yaml-guard.d.ts.map +1 -1
  104. package/dist/modules/admin/admin-access.routes.d.ts +1 -1
  105. package/dist/modules/admin/admin-access.routes.d.ts.map +1 -1
  106. package/dist/modules/admin/admin-access.routes.js +1 -1
  107. package/dist/modules/admin/admin-access.routes.js.map +1 -1
  108. package/dist/modules/admin/admin-access.service.d.ts +2 -2
  109. package/dist/modules/admin/admin-access.service.d.ts.map +1 -1
  110. package/dist/modules/admin/index.d.ts +8 -0
  111. package/dist/modules/admin/index.d.ts.map +1 -0
  112. package/dist/modules/admin/index.js +2 -0
  113. package/dist/modules/admin/index.js.map +1 -0
  114. package/dist/modules/agent-guide/agent-guide.js +1 -1
  115. package/dist/modules/agent-guide/agent-guide.js.map +1 -1
  116. package/dist/modules/agent-guide/agent-guide.tools.d.ts +3 -3
  117. package/dist/modules/agent-guide/agent-guide.tools.d.ts.map +1 -1
  118. package/dist/modules/agent-guide/agent-guide.tools.js +2 -4
  119. package/dist/modules/agent-guide/agent-guide.tools.js.map +1 -1
  120. package/dist/modules/agent-guide/index.d.ts +1 -1
  121. package/dist/modules/agent-guide/index.d.ts.map +1 -1
  122. package/dist/modules/agent-guide/index.js +1 -1
  123. package/dist/modules/agent-guide/index.js.map +1 -1
  124. package/dist/modules/agent-instructions/read-preamble.d.ts +1 -1
  125. package/dist/modules/agent-instructions/read-preamble.d.ts.map +1 -1
  126. package/dist/modules/audit/agent-audit.service.d.ts +2 -2
  127. package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
  128. package/dist/modules/audit/agent-audit.service.js +1 -1
  129. package/dist/modules/audit/agent-audit.service.js.map +1 -1
  130. package/dist/modules/audit/agent-connection.routes.d.ts +1 -1
  131. package/dist/modules/audit/agent-connection.routes.d.ts.map +1 -1
  132. package/dist/modules/audit/agent-connection.routes.js +1 -1
  133. package/dist/modules/audit/agent-connection.routes.js.map +1 -1
  134. package/dist/modules/audit/agent-rest-audit.middleware.d.ts +1 -1
  135. package/dist/modules/audit/agent-rest-audit.middleware.d.ts.map +1 -1
  136. package/dist/modules/audit/agent-rest-audit.middleware.js +1 -1
  137. package/dist/modules/audit/agent-rest-audit.middleware.js.map +1 -1
  138. package/dist/modules/audit/audit.routes.d.ts +3 -3
  139. package/dist/modules/audit/audit.routes.d.ts.map +1 -1
  140. package/dist/modules/audit/audit.routes.js +2 -2
  141. package/dist/modules/audit/audit.routes.js.map +1 -1
  142. package/dist/modules/auth/account-erasure.service.d.ts +3 -3
  143. package/dist/modules/auth/account-erasure.service.d.ts.map +1 -1
  144. package/dist/modules/auth/account-erasure.service.js +1 -5
  145. package/dist/modules/auth/account-erasure.service.js.map +1 -1
  146. package/dist/modules/auth/account-switch-lock.d.ts +1 -1
  147. package/dist/modules/auth/account-switch-lock.d.ts.map +1 -1
  148. package/dist/modules/auth/account-switch-lock.js +1 -1
  149. package/dist/modules/auth/account-switch-lock.js.map +1 -1
  150. package/dist/modules/auth/account.routes.d.ts +2 -2
  151. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  152. package/dist/modules/auth/account.routes.js +1 -1
  153. package/dist/modules/auth/account.routes.js.map +1 -1
  154. package/dist/modules/auth/auth.service.d.ts +1 -1
  155. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  156. package/dist/modules/auth/auth.service.js +3 -3
  157. package/dist/modules/auth/auth.service.js.map +1 -1
  158. package/dist/modules/auth/index.d.ts +2 -0
  159. package/dist/modules/auth/index.d.ts.map +1 -1
  160. package/dist/modules/auth/oidc-auth-provider.js +1 -1
  161. package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
  162. package/dist/modules/code-mode/code-mode.tool.d.ts +1 -1
  163. package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -1
  164. package/dist/modules/connection-probe/connection-probe.service.d.ts +2 -2
  165. package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
  166. package/dist/modules/connection-probe/connection-probe.service.js +1 -4
  167. package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
  168. package/dist/modules/database/core-schema.d.ts +107 -234
  169. package/dist/modules/database/core-schema.d.ts.map +1 -1
  170. package/dist/modules/database/core-schema.js +39 -35
  171. package/dist/modules/database/core-schema.js.map +1 -1
  172. package/dist/modules/database/index.d.ts +10 -0
  173. package/dist/modules/database/index.d.ts.map +1 -0
  174. package/dist/modules/database/index.js +4 -0
  175. package/dist/modules/database/index.js.map +1 -0
  176. package/dist/modules/database/migrate.d.ts.map +1 -1
  177. package/dist/modules/database/migrate.js +78 -3
  178. package/dist/modules/database/migrate.js.map +1 -1
  179. package/dist/modules/declared-variables/declared-variables.routes.d.ts +2 -2
  180. package/dist/modules/declared-variables/declared-variables.routes.d.ts.map +1 -1
  181. package/dist/modules/diff/diff.routes.d.ts +3 -3
  182. package/dist/modules/diff/diff.routes.d.ts.map +1 -1
  183. package/dist/modules/diff/diff.routes.js +3 -3
  184. package/dist/modules/diff/diff.routes.js.map +1 -1
  185. package/dist/modules/diff/diff.service.d.ts +2 -2
  186. package/dist/modules/diff/diff.service.d.ts.map +1 -1
  187. package/dist/modules/diff/index.d.ts +7 -0
  188. package/dist/modules/diff/index.d.ts.map +1 -0
  189. package/dist/modules/diff/index.js +2 -0
  190. package/dist/modules/diff/index.js.map +1 -0
  191. package/dist/modules/embed/account-link.service.d.ts +1 -1
  192. package/dist/modules/embed/account-link.service.d.ts.map +1 -1
  193. package/dist/modules/embed/account-link.service.js +1 -1
  194. package/dist/modules/embed/account-link.service.js.map +1 -1
  195. package/dist/modules/embed/embed.routes.d.ts +1 -1
  196. package/dist/modules/embed/embed.routes.d.ts.map +1 -1
  197. package/dist/modules/embed/embed.routes.js +2 -2
  198. package/dist/modules/embed/embed.routes.js.map +1 -1
  199. package/dist/modules/embed/embed.service.d.ts +1 -1
  200. package/dist/modules/embed/embed.service.d.ts.map +1 -1
  201. package/dist/modules/embed/embed.tools.d.ts +4 -4
  202. package/dist/modules/embed/embed.tools.d.ts.map +1 -1
  203. package/dist/modules/embed/embed.tools.js +3 -5
  204. package/dist/modules/embed/embed.tools.js.map +1 -1
  205. package/dist/modules/github-app/github-app.connection.d.ts +1 -1
  206. package/dist/modules/github-app/github-app.connection.d.ts.map +1 -1
  207. package/dist/modules/github-app/github-app.routes.d.ts +3 -3
  208. package/dist/modules/github-app/github-app.routes.d.ts.map +1 -1
  209. package/dist/modules/github-app/github-app.routes.js +1 -1
  210. package/dist/modules/github-app/github-app.routes.js.map +1 -1
  211. package/dist/modules/kb-fs/index.d.ts +10 -0
  212. package/dist/modules/kb-fs/index.d.ts.map +1 -1
  213. package/dist/modules/kb-fs/index.js +10 -0
  214. package/dist/modules/kb-fs/index.js.map +1 -1
  215. package/dist/modules/kb-fs/locking-filesystem.d.ts +1 -1
  216. package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
  217. package/dist/modules/kb-sync/kb-sync.routes.d.ts +1 -1
  218. package/dist/modules/kb-sync/kb-sync.routes.d.ts.map +1 -1
  219. package/dist/modules/kb-sync/kb-sync.routes.js +2 -2
  220. package/dist/modules/kb-sync/kb-sync.routes.js.map +1 -1
  221. package/dist/modules/kb-sync/kb-sync.service.js +1 -1
  222. package/dist/modules/kb-sync/kb-sync.service.js.map +1 -1
  223. package/dist/modules/kb-sync/sync-auth.js +1 -1
  224. package/dist/modules/kb-sync/sync-auth.js.map +1 -1
  225. package/dist/modules/kb-sync/sync-payload.js +1 -1
  226. package/dist/modules/kb-sync/sync-payload.js.map +1 -1
  227. package/dist/modules/marketplace/git-http.routes.d.ts +1 -1
  228. package/dist/modules/marketplace/git-http.routes.d.ts.map +1 -1
  229. package/dist/modules/marketplace/git-http.routes.js +1 -1
  230. package/dist/modules/marketplace/git-http.routes.js.map +1 -1
  231. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.d.ts +1 -1
  232. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.d.ts.map +1 -1
  233. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.js +1 -1
  234. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.js.map +1 -1
  235. package/dist/modules/marketplace/github-facade/github-facade-codes.store.d.ts +1 -1
  236. package/dist/modules/marketplace/github-facade/github-facade-codes.store.d.ts.map +1 -1
  237. package/dist/modules/marketplace/github-facade/github-facade-codes.store.js +1 -1
  238. package/dist/modules/marketplace/github-facade/github-facade-codes.store.js.map +1 -1
  239. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.d.ts +1 -1
  240. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.d.ts.map +1 -1
  241. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.js +1 -1
  242. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.js.map +1 -1
  243. package/dist/modules/marketplace/github-facade/github-facade.routes.d.ts +2 -2
  244. package/dist/modules/marketplace/github-facade/github-facade.routes.d.ts.map +1 -1
  245. package/dist/modules/marketplace/github-facade/github-facade.routes.js +2 -2
  246. package/dist/modules/marketplace/github-facade/github-facade.routes.js.map +1 -1
  247. package/dist/modules/marketplace/github-facade/github-facade.service.d.ts +2 -2
  248. package/dist/modules/marketplace/github-facade/github-facade.service.d.ts.map +1 -1
  249. package/dist/modules/marketplace/github-facade/github-facade.service.js +1 -1
  250. package/dist/modules/marketplace/github-facade/github-facade.service.js.map +1 -1
  251. package/dist/modules/marketplace/marketplace-repo.service.d.ts +1 -1
  252. package/dist/modules/marketplace/marketplace-repo.service.d.ts.map +1 -1
  253. package/dist/modules/marketplace/marketplace-repo.service.js +1 -1
  254. package/dist/modules/mcp/index.d.ts +8 -0
  255. package/dist/modules/mcp/index.d.ts.map +1 -0
  256. package/dist/modules/mcp/index.js +7 -0
  257. package/dist/modules/mcp/index.js.map +1 -0
  258. package/dist/modules/mcp/mcp-auth.middleware.d.ts +4 -5
  259. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
  260. package/dist/modules/mcp/mcp-auth.middleware.js +4 -4
  261. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
  262. package/dist/modules/mcp/mcp.routes.d.ts +2 -4
  263. package/dist/modules/mcp/mcp.routes.d.ts.map +1 -1
  264. package/dist/modules/mcp/mcp.routes.js +2 -2
  265. package/dist/modules/mcp/mcp.routes.js.map +1 -1
  266. package/dist/modules/mcp/mcp.service.d.ts +14 -4
  267. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  268. package/dist/modules/mcp/mcp.service.js +17 -7
  269. package/dist/modules/mcp/mcp.service.js.map +1 -1
  270. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +1 -1
  271. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  272. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +1 -1
  273. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  274. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +1 -1
  275. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -1
  276. package/dist/modules/mcp/oauth/oauth-consent.routes.js +1 -1
  277. package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -1
  278. package/dist/modules/onboarding/onboarding.routes.d.ts +1 -1
  279. package/dist/modules/onboarding/onboarding.routes.d.ts.map +1 -1
  280. package/dist/modules/onboarding/onboarding.routes.js +1 -1
  281. package/dist/modules/onboarding/onboarding.routes.js.map +1 -1
  282. package/dist/modules/onboarding/starter-pack.service.d.ts +4 -5
  283. package/dist/modules/onboarding/starter-pack.service.d.ts.map +1 -1
  284. package/dist/modules/onboarding/starter-pack.service.js +2 -2
  285. package/dist/modules/onboarding/starter-pack.service.js.map +1 -1
  286. package/dist/modules/plugins/compile/compile-marketplace.d.ts +1 -1
  287. package/dist/modules/plugins/compile/compile-marketplace.d.ts.map +1 -1
  288. package/dist/modules/plugins/compile/compile-marketplace.js +1 -1
  289. package/dist/modules/plugins/compile/compile-marketplace.js.map +1 -1
  290. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts +3 -3
  291. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts.map +1 -1
  292. package/dist/modules/plugins/discovery/bundle-dialect/registry.d.ts +1 -1
  293. package/dist/modules/plugins/discovery/bundle-dialect/registry.d.ts.map +1 -1
  294. package/dist/modules/plugins/discovery/bundle-dialect/registry.js +1 -1
  295. package/dist/modules/plugins/discovery/bundle-dialect/registry.js.map +1 -1
  296. package/dist/modules/plugins/index.d.ts +1 -0
  297. package/dist/modules/plugins/index.d.ts.map +1 -1
  298. package/dist/modules/plugins/index.js +2 -0
  299. package/dist/modules/plugins/index.js.map +1 -1
  300. package/dist/modules/plugins/join-proposals.d.ts +2 -2
  301. package/dist/modules/plugins/join-proposals.d.ts.map +1 -1
  302. package/dist/modules/plugins/join-proposals.js +1 -1
  303. package/dist/modules/plugins/join-proposals.js.map +1 -1
  304. package/dist/modules/plugins/join-request-jobs.service.d.ts +1 -1
  305. package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -1
  306. package/dist/modules/plugins/join-request-jobs.service.js +2 -2
  307. package/dist/modules/plugins/join-request-jobs.service.js.map +1 -1
  308. package/dist/modules/plugins/join-request-records.store.d.ts +1 -1
  309. package/dist/modules/plugins/join-request-records.store.d.ts.map +1 -1
  310. package/dist/modules/plugins/join-request-records.store.js +1 -1
  311. package/dist/modules/plugins/join-request-records.store.js.map +1 -1
  312. package/dist/modules/plugins/join-requests.service.d.ts +3 -3
  313. package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
  314. package/dist/modules/plugins/join-requests.service.js +1 -1
  315. package/dist/modules/plugins/join-requests.service.js.map +1 -1
  316. package/dist/modules/plugins/plugin-links.d.ts +3 -3
  317. package/dist/modules/plugins/plugin-links.d.ts.map +1 -1
  318. package/dist/modules/plugins/plugin-links.js +1 -1
  319. package/dist/modules/plugins/plugin-links.js.map +1 -1
  320. package/dist/modules/plugins/plugin-links.service.d.ts +8 -5
  321. package/dist/modules/plugins/plugin-links.service.d.ts.map +1 -1
  322. package/dist/modules/plugins/plugin-links.service.js +8 -6
  323. package/dist/modules/plugins/plugin-links.service.js.map +1 -1
  324. package/dist/modules/plugins/plugin-provision.service.d.ts +2 -2
  325. package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
  326. package/dist/modules/plugins/plugin-provision.service.js +2 -3
  327. package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
  328. package/dist/modules/plugins/plugin-rename.service.d.ts +2 -2
  329. package/dist/modules/plugins/plugin-rename.service.d.ts.map +1 -1
  330. package/dist/modules/plugins/plugin-rename.service.js +1 -1
  331. package/dist/modules/plugins/plugin-rename.service.js.map +1 -1
  332. package/dist/modules/plugins/plugins.contract.d.ts +1 -1
  333. package/dist/modules/plugins/plugins.contract.d.ts.map +1 -1
  334. package/dist/modules/plugins/plugins.routes.d.ts +2 -2
  335. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  336. package/dist/modules/plugins/plugins.routes.js +3 -3
  337. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  338. package/dist/modules/plugins/plugins.service.d.ts +4 -4
  339. package/dist/modules/plugins/plugins.service.d.ts.map +1 -1
  340. package/dist/modules/plugins/plugins.service.js +1 -1
  341. package/dist/modules/plugins/plugins.service.js.map +1 -1
  342. package/dist/modules/plugins/plugins.tools.d.ts +1 -1
  343. package/dist/modules/plugins/plugins.tools.d.ts.map +1 -1
  344. package/dist/modules/plugins/plugins.tools.js +3 -3
  345. package/dist/modules/plugins/plugins.tools.js.map +1 -1
  346. package/dist/modules/plugins/teams.routes.d.ts +3 -3
  347. package/dist/modules/plugins/teams.routes.d.ts.map +1 -1
  348. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts +1 -1
  349. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts.map +1 -1
  350. package/dist/modules/secrets-vault/db-secrets-vault.service.js +1 -1
  351. package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -1
  352. package/dist/modules/secrets-vault/index.d.ts +1 -0
  353. package/dist/modules/secrets-vault/index.d.ts.map +1 -1
  354. package/dist/modules/secrets-vault/index.js +2 -0
  355. package/dist/modules/secrets-vault/index.js.map +1 -1
  356. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +4 -4
  357. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  358. package/dist/modules/secrets-vault/secrets-vault.routes.js +1 -1
  359. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  360. package/dist/modules/settings/connection-check.js +1 -1
  361. package/dist/modules/settings/connection-check.js.map +1 -1
  362. package/dist/modules/settings/deployment-settings.service.d.ts +7 -1
  363. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  364. package/dist/modules/settings/deployment-settings.service.js +45 -3
  365. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  366. package/dist/modules/settings/git-root-folders.js +1 -1
  367. package/dist/modules/settings/git-root-folders.js.map +1 -1
  368. package/dist/modules/settings/index.d.ts +13 -0
  369. package/dist/modules/settings/index.d.ts.map +1 -0
  370. package/dist/modules/settings/index.js +3 -0
  371. package/dist/modules/settings/index.js.map +1 -0
  372. package/dist/modules/settings/setup.routes.d.ts +3 -3
  373. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  374. package/dist/modules/settings/setup.routes.js +2 -2
  375. package/dist/modules/settings/setup.routes.js.map +1 -1
  376. package/dist/modules/skills/allowed-tools-check.d.ts +2 -2
  377. package/dist/modules/skills/allowed-tools-check.d.ts.map +1 -1
  378. package/dist/modules/skills/allowed-tools-check.js +1 -1
  379. package/dist/modules/skills/allowed-tools-check.js.map +1 -1
  380. package/dist/modules/skills/index.d.ts +1 -0
  381. package/dist/modules/skills/index.d.ts.map +1 -1
  382. package/dist/modules/skills/pending-skills.service.d.ts +3 -3
  383. package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
  384. package/dist/modules/skills/pending-skills.service.js.map +1 -1
  385. package/dist/modules/skills/skill-access-requests.routes.d.ts +5 -5
  386. package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
  387. package/dist/modules/skills/skill-access-requests.routes.js +6 -13
  388. package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
  389. package/dist/modules/skills/skills.routes.d.ts +1 -1
  390. package/dist/modules/skills/skills.routes.d.ts.map +1 -1
  391. package/dist/modules/skills/skills.routes.js +1 -1
  392. package/dist/modules/skills/skills.routes.js.map +1 -1
  393. package/dist/modules/skills/skills.service.d.ts +2 -2
  394. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  395. package/dist/modules/skills/skills.tools.d.ts +3 -3
  396. package/dist/modules/skills/skills.tools.d.ts.map +1 -1
  397. package/dist/modules/skills/skills.tools.js +3 -7
  398. package/dist/modules/skills/skills.tools.js.map +1 -1
  399. package/dist/modules/tool-auth/connection-key-rejection.js +1 -1
  400. package/dist/modules/tool-auth/connection-key-rejection.js.map +1 -1
  401. package/dist/modules/tool-auth/connection-keys-admin.routes.d.ts +2 -2
  402. package/dist/modules/tool-auth/connection-keys-admin.routes.d.ts.map +1 -1
  403. package/dist/modules/tool-auth/connection-keys-admin.routes.js +1 -1
  404. package/dist/modules/tool-auth/connection-keys-admin.routes.js.map +1 -1
  405. package/dist/modules/tool-auth/external-api-key.service.d.ts +1 -1
  406. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  407. package/dist/modules/tool-auth/external-api-key.service.js +1 -1
  408. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  409. package/dist/modules/tool-auth/index.d.ts +15 -0
  410. package/dist/modules/tool-auth/index.d.ts.map +1 -0
  411. package/dist/modules/tool-auth/index.js +11 -0
  412. package/dist/modules/tool-auth/index.js.map +1 -0
  413. package/dist/modules/tool-auth/tool-auth.middleware.d.ts +2 -2
  414. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
  415. package/dist/modules/tool-auth/tool-auth.middleware.js +1 -1
  416. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
  417. package/dist/modules/tool-helpers/default-branch-write.d.ts +1 -1
  418. package/dist/modules/tool-helpers/default-branch-write.d.ts.map +1 -1
  419. package/dist/modules/tool-helpers/index.d.ts +4 -1
  420. package/dist/modules/tool-helpers/index.d.ts.map +1 -1
  421. package/dist/modules/tool-helpers/index.js +3 -0
  422. package/dist/modules/tool-helpers/index.js.map +1 -1
  423. package/dist/modules/tool-helpers/route-argument-check.js +1 -1
  424. package/dist/modules/tool-helpers/route-argument-check.js.map +1 -1
  425. package/dist/modules/tool-helpers/route-tool-schemas.d.ts +1 -1
  426. package/dist/modules/tool-helpers/route-tool-schemas.d.ts.map +1 -1
  427. package/dist/modules/tool-helpers/tool-context.d.ts +5 -6
  428. package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
  429. package/dist/modules/tool-helpers/tool-context.js +2 -3
  430. package/dist/modules/tool-helpers/tool-context.js.map +1 -1
  431. package/dist/modules/tool-helpers/tool-def.d.ts +4 -2
  432. package/dist/modules/tool-helpers/tool-def.d.ts.map +1 -1
  433. package/dist/modules/tool-helpers/tool-def.js +3 -1
  434. package/dist/modules/tool-helpers/tool-def.js.map +1 -1
  435. package/dist/modules/tool-helpers/tool-handler.d.ts +2 -2
  436. package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
  437. package/dist/modules/tool-helpers/tool-handler.js +2 -2
  438. package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
  439. package/dist/modules/tool-helpers/tool.contract.d.ts +2 -2
  440. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
  441. package/dist/modules/tool-helpers/validate-token.d.ts +1 -2
  442. package/dist/modules/tool-helpers/validate-token.d.ts.map +1 -1
  443. package/dist/modules/tool-helpers/validate-token.js +1 -1
  444. package/dist/modules/tool-helpers/validate-token.js.map +1 -1
  445. package/dist/modules/tool-manuals/index.d.ts +5 -0
  446. package/dist/modules/tool-manuals/index.d.ts.map +1 -1
  447. package/dist/modules/tool-manuals/index.js +4 -0
  448. package/dist/modules/tool-manuals/index.js.map +1 -1
  449. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts +2 -2
  450. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -1
  451. package/dist/modules/tool-manuals/pending-tools.service.d.ts +2 -2
  452. package/dist/modules/tool-manuals/pending-tools.service.d.ts.map +1 -1
  453. package/dist/modules/tool-manuals/tool-delete.service.d.ts +5 -6
  454. package/dist/modules/tool-manuals/tool-delete.service.d.ts.map +1 -1
  455. package/dist/modules/tool-manuals/tool-delete.service.js.map +1 -1
  456. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +5 -5
  457. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
  458. package/dist/modules/tool-manuals/tool-manuals.routes.js +2 -2
  459. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
  460. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +3 -3
  461. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  462. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +3 -3
  463. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  464. package/dist/modules/tool-manuals/tool-manuals.tools.js +1 -2
  465. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  466. package/dist/modules/tool-registry/description-length.js +2 -2
  467. package/dist/modules/tool-registry/description-length.js.map +1 -1
  468. package/dist/modules/tool-registry/index.d.ts +8 -0
  469. package/dist/modules/tool-registry/index.d.ts.map +1 -0
  470. package/dist/modules/tool-registry/index.js +8 -0
  471. package/dist/modules/tool-registry/index.js.map +1 -0
  472. package/dist/modules/tool-registry/manual.routes.d.ts +37 -2
  473. package/dist/modules/tool-registry/manual.routes.d.ts.map +1 -1
  474. package/dist/modules/tool-registry/manual.routes.js +14 -7
  475. package/dist/modules/tool-registry/manual.routes.js.map +1 -1
  476. package/dist/modules/tool-registry/read-only-hints.contract.d.ts +52 -0
  477. package/dist/modules/tool-registry/read-only-hints.contract.d.ts.map +1 -0
  478. package/dist/modules/tool-registry/read-only-hints.contract.js +2 -0
  479. package/dist/modules/tool-registry/read-only-hints.contract.js.map +1 -0
  480. package/dist/modules/tool-registry/read-only-hints.d.ts +89 -0
  481. package/dist/modules/tool-registry/read-only-hints.d.ts.map +1 -0
  482. package/dist/modules/tool-registry/read-only-hints.js +212 -0
  483. package/dist/modules/tool-registry/read-only-hints.js.map +1 -0
  484. package/dist/modules/tool-registry/tool.contract.d.ts +8 -0
  485. package/dist/modules/tool-registry/tool.contract.d.ts.map +1 -1
  486. package/dist/modules/tool-registry/tool.contract.js +10 -1
  487. package/dist/modules/tool-registry/tool.contract.js.map +1 -1
  488. package/dist/modules/update-check/update-check.routes.d.ts +2 -2
  489. package/dist/modules/update-check/update-check.routes.d.ts.map +1 -1
  490. package/dist/modules/update-check/update-check.routes.js +1 -1
  491. package/dist/modules/update-check/update-check.routes.js.map +1 -1
  492. package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts +9 -104
  493. package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts.map +1 -1
  494. package/dist/modules/workflow/agent-tools/change-request-read-shape.js +8 -118
  495. package/dist/modules/workflow/agent-tools/change-request-read-shape.js.map +1 -1
  496. package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts +16 -17
  497. package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts.map +1 -1
  498. package/dist/modules/workflow/agent-tools/change-request-read.tools.js +19 -86
  499. package/dist/modules/workflow/agent-tools/change-request-read.tools.js.map +1 -1
  500. package/dist/modules/workflow/agent-tools/change-request-summary.d.ts +5 -1
  501. package/dist/modules/workflow/agent-tools/change-request-summary.d.ts.map +1 -1
  502. package/dist/modules/workflow/agent-tools/change-request-summary.js +10 -1
  503. package/dist/modules/workflow/agent-tools/change-request-summary.js.map +1 -1
  504. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +7 -5
  505. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  506. package/dist/modules/workflow/agent-tools/workflow.tools.js +46 -68
  507. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  508. package/dist/modules/workflow/change-request-hooks.d.ts +1 -1
  509. package/dist/modules/workflow/event-bus.d.ts.map +1 -1
  510. package/dist/modules/workflow/event-bus.js +3 -1
  511. package/dist/modules/workflow/event-bus.js.map +1 -1
  512. package/dist/modules/workflow/events-delivery.d.ts +120 -0
  513. package/dist/modules/workflow/events-delivery.d.ts.map +1 -0
  514. package/dist/modules/workflow/events-delivery.js +202 -0
  515. package/dist/modules/workflow/events-delivery.js.map +1 -0
  516. package/dist/modules/workflow/events.routes.d.ts +16 -7
  517. package/dist/modules/workflow/events.routes.d.ts.map +1 -1
  518. package/dist/modules/workflow/events.routes.js +23 -4
  519. package/dist/modules/workflow/events.routes.js.map +1 -1
  520. package/dist/modules/workflow/file-lock.service.d.ts +1 -1
  521. package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
  522. package/dist/modules/workflow/file-lock.service.js +1 -1
  523. package/dist/modules/workflow/file-lock.service.js.map +1 -1
  524. package/dist/modules/workflow/git/git.service.d.ts +2 -2
  525. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  526. package/dist/modules/workflow/git/git.service.js +3 -6
  527. package/dist/modules/workflow/git/git.service.js.map +1 -1
  528. package/dist/modules/workflow/git/node-git-runner.js +1 -1
  529. package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
  530. package/dist/modules/workflow/git/pull-request.service.d.ts +6 -7
  531. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
  532. package/dist/modules/workflow/git/pull-request.service.js +40 -33
  533. package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
  534. package/dist/modules/workflow/index.d.ts +14 -2
  535. package/dist/modules/workflow/index.d.ts.map +1 -1
  536. package/dist/modules/workflow/index.js +11 -2
  537. package/dist/modules/workflow/index.js.map +1 -1
  538. package/dist/modules/workflow/pending-commits.service.d.ts +1 -1
  539. package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
  540. package/dist/modules/workflow/pending-commits.service.js +1 -1
  541. package/dist/modules/workflow/pending-commits.service.js.map +1 -1
  542. package/dist/modules/workflow/read-on-branch.d.ts +1 -1
  543. package/dist/modules/workflow/read-on-branch.d.ts.map +1 -1
  544. package/dist/modules/workflow/recovery-bot.d.ts +1 -1
  545. package/dist/modules/workflow/recovery-bot.d.ts.map +1 -1
  546. package/dist/modules/workflow/recovery-bot.js +1 -1
  547. package/dist/modules/workflow/recovery-bot.js.map +1 -1
  548. package/dist/modules/workflow/review-workflow/approval-lock.d.ts +1 -1
  549. package/dist/modules/workflow/review-workflow/approval-lock.d.ts.map +1 -1
  550. package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts +4 -20
  551. package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts.map +1 -1
  552. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts +4 -8
  553. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
  554. package/dist/modules/workflow/review-workflow/review-workflow.service.js +3 -138
  555. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
  556. package/dist/modules/workflow/workflow.routes.d.ts +5 -5
  557. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
  558. package/dist/modules/workflow/workflow.routes.js +42 -94
  559. package/dist/modules/workflow/workflow.routes.js.map +1 -1
  560. package/dist/modules/workflow/workflow.service.d.ts +40 -50
  561. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  562. package/dist/modules/workflow/workflow.service.js +218 -154
  563. package/dist/modules/workflow/workflow.service.js.map +1 -1
  564. package/dist/modules/workspace/agent-access.gate.d.ts +3 -3
  565. package/dist/modules/workspace/agent-access.gate.d.ts.map +1 -1
  566. package/dist/modules/workspace/agent-download.builder.d.ts +1 -1
  567. package/dist/modules/workspace/agent-download.builder.d.ts.map +1 -1
  568. package/dist/modules/workspace/agent-download.builder.js +1 -1
  569. package/dist/modules/workspace/agent-download.builder.js.map +1 -1
  570. package/dist/modules/workspace/agent-upload.routes.d.ts.map +1 -1
  571. package/dist/modules/workspace/agent-upload.routes.js +19 -0
  572. package/dist/modules/workspace/agent-upload.routes.js.map +1 -1
  573. package/dist/modules/workspace/agent-upload.store.d.ts +11 -0
  574. package/dist/modules/workspace/agent-upload.store.d.ts.map +1 -1
  575. package/dist/modules/workspace/agent-upload.store.js +18 -0
  576. package/dist/modules/workspace/agent-upload.store.js.map +1 -1
  577. package/dist/modules/workspace/bounded-matcher.d.ts +5 -11
  578. package/dist/modules/workspace/bounded-matcher.d.ts.map +1 -1
  579. package/dist/modules/workspace/bounded-matcher.js +26 -87
  580. package/dist/modules/workspace/bounded-matcher.js.map +1 -1
  581. package/dist/modules/workspace/file-readers/doc-extract.service.d.ts +54 -10
  582. package/dist/modules/workspace/file-readers/doc-extract.service.d.ts.map +1 -1
  583. package/dist/modules/workspace/file-readers/doc-extract.service.js +69 -17
  584. package/dist/modules/workspace/file-readers/doc-extract.service.js.map +1 -1
  585. package/dist/modules/workspace/file-readers/doc-extract.types.d.ts +9 -2
  586. package/dist/modules/workspace/file-readers/doc-extract.types.d.ts.map +1 -1
  587. package/dist/modules/workspace/file-readers/doc-extract.types.js.map +1 -1
  588. package/dist/modules/workspace/file-readers/document-extractor.contract.d.ts +41 -0
  589. package/dist/modules/workspace/file-readers/document-extractor.contract.d.ts.map +1 -0
  590. package/dist/modules/workspace/file-readers/document-extractor.contract.js +5 -0
  591. package/dist/modules/workspace/file-readers/document-extractor.contract.js.map +1 -0
  592. package/dist/modules/workspace/file-readers/document-extractors.d.ts +9 -0
  593. package/dist/modules/workspace/file-readers/document-extractors.d.ts.map +1 -0
  594. package/dist/modules/workspace/file-readers/document-extractors.js +26 -0
  595. package/dist/modules/workspace/file-readers/document-extractors.js.map +1 -0
  596. package/dist/modules/workspace/file-readers/document-formats.d.ts +12 -0
  597. package/dist/modules/workspace/file-readers/document-formats.d.ts.map +1 -0
  598. package/dist/modules/workspace/file-readers/document-formats.js +11 -0
  599. package/dist/modules/workspace/file-readers/document-formats.js.map +1 -0
  600. package/dist/modules/workspace/file-readers/document-reader.d.ts +21 -17
  601. package/dist/modules/workspace/file-readers/document-reader.d.ts.map +1 -1
  602. package/dist/modules/workspace/file-readers/document-reader.js +38 -34
  603. package/dist/modules/workspace/file-readers/document-reader.js.map +1 -1
  604. package/dist/modules/workspace/file-readers/extract-in-worker.d.ts +60 -0
  605. package/dist/modules/workspace/file-readers/extract-in-worker.d.ts.map +1 -0
  606. package/dist/modules/workspace/file-readers/extract-in-worker.js +140 -0
  607. package/dist/modules/workspace/file-readers/extract-in-worker.js.map +1 -0
  608. package/dist/modules/workspace/file-readers/extract-pdf.d.ts +2 -0
  609. package/dist/modules/workspace/file-readers/extract-pdf.d.ts.map +1 -1
  610. package/dist/modules/workspace/file-readers/extract-pdf.js +20 -3
  611. package/dist/modules/workspace/file-readers/extract-pdf.js.map +1 -1
  612. package/dist/modules/workspace/file-readers/extract.worker.d.ts +2 -0
  613. package/dist/modules/workspace/file-readers/extract.worker.d.ts.map +1 -0
  614. package/dist/modules/workspace/file-readers/extract.worker.js +5 -0
  615. package/dist/modules/workspace/file-readers/extract.worker.js.map +1 -0
  616. package/dist/modules/workspace/file-readers/extraction-cache.d.ts +21 -5
  617. package/dist/modules/workspace/file-readers/extraction-cache.d.ts.map +1 -1
  618. package/dist/modules/workspace/file-readers/extraction-cache.js +24 -10
  619. package/dist/modules/workspace/file-readers/extraction-cache.js.map +1 -1
  620. package/dist/modules/workspace/file-readers/extraction-worker.d.ts +42 -0
  621. package/dist/modules/workspace/file-readers/extraction-worker.d.ts.map +1 -0
  622. package/dist/modules/workspace/file-readers/extraction-worker.js +69 -0
  623. package/dist/modules/workspace/file-readers/extraction-worker.js.map +1 -0
  624. package/dist/modules/workspace/file-readers/file-reader.d.ts +13 -4
  625. package/dist/modules/workspace/file-readers/file-reader.d.ts.map +1 -1
  626. package/dist/modules/workspace/file-readers/file-reader.js.map +1 -1
  627. package/dist/modules/workspace/file-readers/file-reader.registry.d.ts +3 -2
  628. package/dist/modules/workspace/file-readers/file-reader.registry.d.ts.map +1 -1
  629. package/dist/modules/workspace/file-readers/file-reader.registry.js +6 -20
  630. package/dist/modules/workspace/file-readers/file-reader.registry.js.map +1 -1
  631. package/dist/modules/workspace/first-run.js +1 -1
  632. package/dist/modules/workspace/first-run.js.map +1 -1
  633. package/dist/modules/workspace/git-internals.middleware.d.ts +1 -1
  634. package/dist/modules/workspace/git-internals.middleware.d.ts.map +1 -1
  635. package/dist/modules/workspace/git-internals.middleware.js +1 -1
  636. package/dist/modules/workspace/git-internals.middleware.js.map +1 -1
  637. package/dist/modules/workspace/index.d.ts +16 -0
  638. package/dist/modules/workspace/index.d.ts.map +1 -1
  639. package/dist/modules/workspace/index.js +13 -0
  640. package/dist/modules/workspace/index.js.map +1 -1
  641. package/dist/modules/workspace/kb-repository.d.ts.map +1 -1
  642. package/dist/modules/workspace/kb-repository.js +1 -1
  643. package/dist/modules/workspace/kb-repository.js.map +1 -1
  644. package/dist/modules/workspace/not-found.d.ts +1 -1
  645. package/dist/modules/workspace/not-found.d.ts.map +1 -1
  646. package/dist/modules/workspace/not-found.js +1 -1
  647. package/dist/modules/workspace/not-found.js.map +1 -1
  648. package/dist/modules/workspace/pattern-matcher.contract.d.ts +1 -1
  649. package/dist/modules/workspace/pattern-matcher.contract.d.ts.map +1 -1
  650. package/dist/modules/workspace/pattern-matcher.contract.js +1 -1
  651. package/dist/modules/workspace/pattern-matcher.contract.js.map +1 -1
  652. package/dist/modules/workspace/routine-write-policy.js +1 -1
  653. package/dist/modules/workspace/routine-write-policy.js.map +1 -1
  654. package/dist/modules/workspace/startup/kb-git.js +1 -1
  655. package/dist/modules/workspace/startup/kb-git.js.map +1 -1
  656. package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
  657. package/dist/modules/workspace/startup/kb-startup-runner.js +1 -2
  658. package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
  659. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js +2 -2
  660. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js.map +1 -1
  661. package/dist/modules/workspace/startup/steps/personal-spaces.step.js +2 -2
  662. package/dist/modules/workspace/startup/steps/personal-spaces.step.js.map +1 -1
  663. package/dist/modules/workspace/startup/steps/plugin-layout.js +1 -1
  664. package/dist/modules/workspace/startup/steps/plugin-layout.js.map +1 -1
  665. package/dist/modules/workspace/startup/steps/roles-yaml.step.js +1 -1
  666. package/dist/modules/workspace/startup/steps/roles-yaml.step.js.map +1 -1
  667. package/dist/modules/workspace/startup/steps/seed-tree.js +2 -2
  668. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  669. package/dist/modules/workspace/startup/steps/template-files.step.d.ts +1 -1
  670. package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
  671. package/dist/modules/workspace/startup/steps/template-files.step.js +2 -2
  672. package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
  673. package/dist/modules/workspace/startup/steps/template-source.js +2 -2
  674. package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
  675. package/dist/modules/workspace/worker-pool.d.ts +100 -0
  676. package/dist/modules/workspace/worker-pool.d.ts.map +1 -0
  677. package/dist/modules/workspace/worker-pool.js +156 -0
  678. package/dist/modules/workspace/worker-pool.js.map +1 -0
  679. package/dist/modules/workspace/workspace.routes.d.ts +7 -8
  680. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  681. package/dist/modules/workspace/workspace.routes.js +4 -6
  682. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  683. package/dist/modules/workspace/workspace.service.d.ts +1 -1
  684. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  685. package/dist/modules/workspace/workspace.service.js +3 -6
  686. package/dist/modules/workspace/workspace.service.js.map +1 -1
  687. package/dist/modules/workspace/workspace.tools.d.ts +7 -7
  688. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  689. package/dist/modules/workspace/workspace.tools.js +45 -27
  690. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  691. package/dist/modules/workspace/write-denial.d.ts +4 -4
  692. package/dist/modules/workspace/write-denial.d.ts.map +1 -1
  693. package/dist/modules/workspace/write-denial.js +2 -3
  694. package/dist/modules/workspace/write-denial.js.map +1 -1
  695. package/dist/modules/write-access/index.d.ts +8 -0
  696. package/dist/modules/write-access/index.d.ts.map +1 -0
  697. package/dist/modules/write-access/index.js +7 -0
  698. package/dist/modules/write-access/index.js.map +1 -0
  699. package/migrations/0020_change_request_body_is_the_description.sql +20 -0
  700. package/migrations/0021_data_migrations_ledger.sql +11 -0
  701. package/migrations/meta/0020_snapshot.json +2321 -0
  702. package/migrations/meta/0021_snapshot.json +2353 -0
  703. package/migrations/meta/_journal.json +14 -0
  704. package/package.json +3 -3
  705. package/src/core/__tests__/damaged-document.tools.test.ts +374 -0
  706. package/src/core/__tests__/public-config.test.ts +5 -0
  707. package/src/core/create-core-server.ts +32 -3
  708. package/src/core/create-core-services.ts +32 -5
  709. package/src/core/lifecycle.ts +10 -0
  710. package/src/core/public-config.ts +10 -0
  711. package/src/modules/access/__tests__/access-requests.routes.test.ts +29 -15
  712. package/src/modules/access/access-control.service.ts +5 -6
  713. package/src/modules/access/access-declarations.ts +1 -1
  714. package/src/modules/access/access-mutation.service.ts +10 -4
  715. package/src/modules/access/access-requests.contract.ts +1 -1
  716. package/src/modules/access/access-requests.routes.ts +10 -15
  717. package/src/modules/access/access-requests.service.ts +29 -71
  718. package/src/modules/access/access-view.ts +1 -1
  719. package/src/modules/access/access.routes.ts +9 -11
  720. package/src/modules/access/admin-locked-commit.ts +3 -2
  721. package/src/modules/access/capability-registry.ts +1 -1
  722. package/src/modules/access/change-read-gate.ts +3 -5
  723. package/src/modules/access/creator-access.ts +3 -5
  724. package/src/modules/access/directory-sync-bot.ts +2 -2
  725. package/src/modules/access/groups-admin.routes.ts +3 -3
  726. package/src/modules/access/groups-admin.service.ts +3 -4
  727. package/src/modules/access/groups-edit.ts +2 -2
  728. package/src/modules/access/index.ts +17 -0
  729. package/src/modules/access/reference-scan.ts +1 -1
  730. package/src/modules/access/roles-admin.service.ts +3 -6
  731. package/src/modules/access/roles-edit.ts +1 -1
  732. package/src/modules/access/synced-groups-committer.ts +4 -4
  733. package/src/modules/access/synced-groups-writer.ts +2 -2
  734. package/src/modules/access/user-access-removal.service.ts +3 -6
  735. package/src/modules/access-model/index.ts +21 -5
  736. package/src/modules/access-model/roles-yaml-guard.ts +1 -1
  737. package/src/modules/admin/admin-access.routes.ts +1 -1
  738. package/src/modules/admin/admin-access.service.ts +2 -2
  739. package/src/modules/admin/index.ts +7 -0
  740. package/src/modules/agent-guide/__tests__/agent-guide.test.ts +5 -0
  741. package/src/modules/agent-guide/agent-guide.tools.ts +4 -6
  742. package/src/modules/agent-guide/agent-guide.ts +1 -1
  743. package/src/modules/agent-guide/index.ts +1 -1
  744. package/src/modules/agent-instructions/read-preamble.ts +1 -1
  745. package/src/modules/audit/agent-audit.service.ts +3 -3
  746. package/src/modules/audit/agent-connection.routes.ts +1 -1
  747. package/src/modules/audit/agent-rest-audit.middleware.ts +1 -1
  748. package/src/modules/audit/audit.routes.ts +4 -4
  749. package/src/modules/auth/account-erasure.service.ts +4 -9
  750. package/src/modules/auth/account-switch-lock.ts +2 -2
  751. package/src/modules/auth/account.routes.ts +3 -3
  752. package/src/modules/auth/auth.service.ts +4 -4
  753. package/src/modules/auth/index.ts +3 -0
  754. package/src/modules/auth/oidc-auth-provider.ts +1 -1
  755. package/src/modules/code-mode/code-mode.tool.ts +1 -1
  756. package/src/modules/connection-probe/connection-probe.service.ts +3 -6
  757. package/src/modules/database/__tests__/legacy-change-request-body.test.ts +118 -0
  758. package/src/modules/database/__tests__/legacy-request-bodies.pg.test.ts +258 -0
  759. package/src/modules/database/__tests__/pii-backfill.pg.test.ts +15 -18
  760. package/src/modules/database/core-schema.ts +43 -36
  761. package/src/modules/database/index.ts +9 -0
  762. package/src/modules/database/migrate.ts +79 -3
  763. package/src/modules/declared-variables/declared-variables.routes.ts +2 -2
  764. package/src/modules/diff/diff.routes.ts +5 -5
  765. package/src/modules/diff/diff.service.ts +2 -2
  766. package/src/modules/diff/index.ts +6 -0
  767. package/src/modules/embed/account-link.service.ts +2 -2
  768. package/src/modules/embed/embed.routes.ts +2 -2
  769. package/src/modules/embed/embed.service.ts +1 -1
  770. package/src/modules/embed/embed.tools.ts +6 -9
  771. package/src/modules/github-app/github-app.connection.ts +1 -1
  772. package/src/modules/github-app/github-app.routes.ts +3 -3
  773. package/src/modules/kb-fs/index.ts +11 -0
  774. package/src/modules/kb-fs/locking-filesystem.ts +1 -1
  775. package/src/modules/kb-sync/kb-sync.routes.ts +3 -3
  776. package/src/modules/kb-sync/kb-sync.service.ts +1 -1
  777. package/src/modules/kb-sync/sync-auth.ts +1 -1
  778. package/src/modules/kb-sync/sync-payload.ts +1 -1
  779. package/src/modules/marketplace/git-http.routes.ts +1 -1
  780. package/src/modules/marketplace/github-facade/github-facade-admin.routes.ts +1 -1
  781. package/src/modules/marketplace/github-facade/github-facade-codes.store.ts +2 -2
  782. package/src/modules/marketplace/github-facade/github-facade-credentials.service.ts +2 -2
  783. package/src/modules/marketplace/github-facade/github-facade.routes.ts +2 -2
  784. package/src/modules/marketplace/github-facade/github-facade.service.ts +2 -2
  785. package/src/modules/marketplace/marketplace-repo.service.ts +2 -2
  786. package/src/modules/mcp/__tests__/read-only-hint.e2e.test.ts +213 -0
  787. package/src/modules/mcp/index.ts +7 -0
  788. package/src/modules/mcp/mcp-auth.middleware.ts +6 -7
  789. package/src/modules/mcp/mcp.routes.ts +3 -5
  790. package/src/modules/mcp/mcp.service.ts +30 -13
  791. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +2 -2
  792. package/src/modules/mcp/oauth/oauth-consent.routes.ts +1 -1
  793. package/src/modules/onboarding/onboarding.routes.ts +1 -1
  794. package/src/modules/onboarding/starter-pack.service.ts +5 -6
  795. package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +2 -1
  796. package/src/modules/plugins/__tests__/plugin-links.service.test.ts +2 -1
  797. package/src/modules/plugins/compile/compile-marketplace.ts +2 -2
  798. package/src/modules/plugins/compile/marketplace-compiler.service.ts +3 -3
  799. package/src/modules/plugins/discovery/bundle-dialect/registry.ts +1 -1
  800. package/src/modules/plugins/index.ts +2 -0
  801. package/src/modules/plugins/join-proposals.ts +2 -2
  802. package/src/modules/plugins/join-request-jobs.service.ts +3 -3
  803. package/src/modules/plugins/join-request-records.store.ts +2 -2
  804. package/src/modules/plugins/join-requests.service.ts +4 -4
  805. package/src/modules/plugins/plugin-links.service.ts +10 -11
  806. package/src/modules/plugins/plugin-links.ts +4 -4
  807. package/src/modules/plugins/plugin-provision.service.ts +4 -5
  808. package/src/modules/plugins/plugin-rename.service.ts +3 -3
  809. package/src/modules/plugins/plugins.contract.ts +1 -1
  810. package/src/modules/plugins/plugins.routes.ts +4 -4
  811. package/src/modules/plugins/plugins.service.ts +5 -5
  812. package/src/modules/plugins/plugins.tools.ts +4 -4
  813. package/src/modules/plugins/teams.routes.ts +3 -3
  814. package/src/modules/secrets-vault/db-secrets-vault.service.ts +2 -2
  815. package/src/modules/secrets-vault/index.ts +2 -0
  816. package/src/modules/secrets-vault/secrets-vault.routes.ts +4 -4
  817. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +88 -1
  818. package/src/modules/settings/connection-check.ts +1 -1
  819. package/src/modules/settings/deployment-settings.service.ts +44 -4
  820. package/src/modules/settings/git-root-folders.ts +1 -1
  821. package/src/modules/settings/index.ts +12 -0
  822. package/src/modules/settings/setup.routes.ts +5 -4
  823. package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +2 -2
  824. package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +6 -3
  825. package/src/modules/skills/allowed-tools-check.ts +2 -6
  826. package/src/modules/skills/index.ts +2 -0
  827. package/src/modules/skills/pending-skills.service.ts +3 -4
  828. package/src/modules/skills/skill-access-requests.routes.ts +10 -17
  829. package/src/modules/skills/skills.routes.ts +1 -1
  830. package/src/modules/skills/skills.service.ts +2 -2
  831. package/src/modules/skills/skills.tools.ts +5 -9
  832. package/src/modules/tool-auth/connection-key-rejection.ts +1 -1
  833. package/src/modules/tool-auth/connection-keys-admin.routes.ts +2 -2
  834. package/src/modules/tool-auth/external-api-key.service.ts +2 -2
  835. package/src/modules/tool-auth/index.ts +14 -0
  836. package/src/modules/tool-auth/tool-auth.middleware.ts +3 -3
  837. package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +2 -2
  838. package/src/modules/tool-helpers/__tests__/can-write.tools.test.ts +2 -2
  839. package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +2 -2
  840. package/src/modules/tool-helpers/default-branch-write.ts +1 -1
  841. package/src/modules/tool-helpers/index.ts +5 -1
  842. package/src/modules/tool-helpers/route-argument-check.ts +1 -1
  843. package/src/modules/tool-helpers/route-tool-schemas.ts +1 -1
  844. package/src/modules/tool-helpers/tool-context.ts +8 -10
  845. package/src/modules/tool-helpers/tool-def.ts +7 -3
  846. package/src/modules/tool-helpers/tool-handler.ts +2 -2
  847. package/src/modules/tool-helpers/tool.contract.ts +2 -2
  848. package/src/modules/tool-helpers/validate-token.ts +2 -3
  849. package/src/modules/tool-manuals/index.ts +6 -0
  850. package/src/modules/tool-manuals/mcp-server-edit.service.ts +2 -2
  851. package/src/modules/tool-manuals/pending-tools.service.ts +2 -2
  852. package/src/modules/tool-manuals/tool-delete.service.ts +5 -6
  853. package/src/modules/tool-manuals/tool-manuals.routes.ts +5 -5
  854. package/src/modules/tool-manuals/tool-manuals.service.ts +3 -3
  855. package/src/modules/tool-manuals/tool-manuals.tools.ts +4 -6
  856. package/src/modules/tool-registry/__tests__/read-only-hints.test.ts +439 -0
  857. package/src/modules/tool-registry/__tests__/tool-registry.test.ts +9 -2
  858. package/src/modules/tool-registry/description-length.ts +2 -2
  859. package/src/modules/tool-registry/index.ts +22 -0
  860. package/src/modules/tool-registry/manual.routes.ts +14 -8
  861. package/src/modules/tool-registry/read-only-hints.contract.ts +54 -0
  862. package/src/modules/tool-registry/read-only-hints.ts +225 -0
  863. package/src/modules/tool-registry/tool.contract.ts +11 -0
  864. package/src/modules/update-check/update-check.routes.ts +2 -2
  865. package/src/modules/workflow/__tests__/event-bus.test.ts +14 -2
  866. package/src/modules/workflow/__tests__/events-delivery.test.ts +778 -0
  867. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +84 -21
  868. package/src/modules/workflow/__tests__/workflow.service.update-change-request.pg.test.ts +120 -0
  869. package/src/modules/workflow/__tests__/workflow.service.update-change-request.test.ts +346 -0
  870. package/src/modules/workflow/agent-tools/__tests__/change-request-read-shape.test.ts +32 -209
  871. package/src/modules/workflow/agent-tools/__tests__/change-request-read.tools.test.ts +16 -245
  872. package/src/modules/workflow/agent-tools/__tests__/update-change-request.parity.test.ts +306 -0
  873. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +33 -57
  874. package/src/modules/workflow/agent-tools/change-request-read-shape.ts +18 -153
  875. package/src/modules/workflow/agent-tools/change-request-read.tools.ts +24 -96
  876. package/src/modules/workflow/agent-tools/change-request-summary.ts +16 -2
  877. package/src/modules/workflow/agent-tools/workflow.tools.ts +49 -75
  878. package/src/modules/workflow/change-request-hooks.ts +1 -1
  879. package/src/modules/workflow/event-bus.ts +3 -1
  880. package/src/modules/workflow/events-delivery.ts +278 -0
  881. package/src/modules/workflow/events.routes.ts +30 -9
  882. package/src/modules/workflow/file-lock.service.ts +2 -2
  883. package/src/modules/workflow/git/__tests__/pull-request.service.getPrDetail.test.ts +24 -9
  884. package/src/modules/workflow/git/git.service.ts +5 -8
  885. package/src/modules/workflow/git/node-git-runner.ts +1 -1
  886. package/src/modules/workflow/git/pull-request.service.ts +34 -29
  887. package/src/modules/workflow/index.ts +15 -2
  888. package/src/modules/workflow/pending-commits.service.ts +2 -2
  889. package/src/modules/workflow/read-on-branch.ts +1 -1
  890. package/src/modules/workflow/recovery-bot.ts +2 -2
  891. package/src/modules/workflow/review-workflow/approval-lock.ts +1 -1
  892. package/src/modules/workflow/review-workflow/review-workflow.interface.ts +3 -35
  893. package/src/modules/workflow/review-workflow/review-workflow.service.ts +6 -165
  894. package/src/modules/workflow/workflow.routes.ts +46 -100
  895. package/src/modules/workflow/workflow.service.ts +272 -191
  896. package/src/modules/workspace/__tests__/agent-downloads.test.ts +2 -1
  897. package/src/modules/workspace/__tests__/agent-uploads.test.ts +87 -1
  898. package/src/modules/workspace/__tests__/escape-sequences.routes.test.ts +2 -1
  899. package/src/modules/workspace/__tests__/file-stat-access.test.ts +2 -1
  900. package/src/modules/workspace/__tests__/git-internals.security.test.ts +2 -1
  901. package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +2 -1
  902. package/src/modules/workspace/__tests__/worker-pool.test.ts +118 -0
  903. package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -2
  904. package/src/modules/workspace/__tests__/workspace.service.ensure-remotes-fetched.test.ts +30 -0
  905. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +2 -1
  906. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +2 -1
  907. package/src/modules/workspace/__tests__/workspace.tools.test.ts +30 -4
  908. package/src/modules/workspace/agent-access.gate.ts +3 -3
  909. package/src/modules/workspace/agent-download.builder.ts +1 -1
  910. package/src/modules/workspace/agent-upload.routes.ts +19 -0
  911. package/src/modules/workspace/agent-upload.store.ts +18 -0
  912. package/src/modules/workspace/bounded-matcher.ts +32 -89
  913. package/src/modules/workspace/file-readers/README.md +9 -0
  914. package/src/modules/workspace/file-readers/__tests__/doc-extract.service.test.ts +165 -0
  915. package/src/modules/workspace/file-readers/__tests__/doc-extract.test.ts +21 -16
  916. package/src/modules/workspace/file-readers/__tests__/extract-in-worker.test.ts +229 -0
  917. package/src/modules/workspace/file-readers/__tests__/file-reader.registry.test.ts +2 -1
  918. package/src/modules/workspace/file-readers/__tests__/fixtures/damaged-pdf.ts +34 -0
  919. package/src/modules/workspace/file-readers/__tests__/fixtures/misbehaving-extract.worker.ts +57 -0
  920. package/src/modules/workspace/file-readers/__tests__/fixtures/pdf-in-trouble.worker.ts +20 -0
  921. package/src/modules/workspace/file-readers/__tests__/fixtures/unloadable-extract.worker.ts +2 -0
  922. package/src/modules/workspace/file-readers/doc-extract.service.ts +95 -20
  923. package/src/modules/workspace/file-readers/doc-extract.types.ts +13 -3
  924. package/src/modules/workspace/file-readers/document-extractor.contract.ts +42 -0
  925. package/src/modules/workspace/file-readers/document-extractors.ts +28 -0
  926. package/src/modules/workspace/file-readers/document-formats.ts +13 -0
  927. package/src/modules/workspace/file-readers/document-reader.ts +40 -36
  928. package/src/modules/workspace/file-readers/extract-in-worker.ts +183 -0
  929. package/src/modules/workspace/file-readers/extract-pdf.ts +23 -4
  930. package/src/modules/workspace/file-readers/extract.worker.ts +5 -0
  931. package/src/modules/workspace/file-readers/extraction-cache.ts +33 -12
  932. package/src/modules/workspace/file-readers/extraction-worker.ts +86 -0
  933. package/src/modules/workspace/file-readers/file-reader.registry.ts +6 -20
  934. package/src/modules/workspace/file-readers/file-reader.ts +14 -4
  935. package/src/modules/workspace/first-run.ts +1 -1
  936. package/src/modules/workspace/git-internals.middleware.ts +1 -1
  937. package/src/modules/workspace/index.ts +17 -0
  938. package/src/modules/workspace/kb-repository.ts +3 -2
  939. package/src/modules/workspace/not-found.ts +1 -1
  940. package/src/modules/workspace/pattern-matcher.contract.ts +1 -1
  941. package/src/modules/workspace/routine-write-policy.ts +1 -1
  942. package/src/modules/workspace/startup/kb-git.ts +1 -1
  943. package/src/modules/workspace/startup/kb-startup-runner.ts +1 -2
  944. package/src/modules/workspace/startup/steps/groups-to-plugins.step.ts +3 -3
  945. package/src/modules/workspace/startup/steps/personal-spaces.step.ts +2 -2
  946. package/src/modules/workspace/startup/steps/plugin-layout.ts +1 -1
  947. package/src/modules/workspace/startup/steps/roles-yaml.step.ts +1 -1
  948. package/src/modules/workspace/startup/steps/seed-tree.ts +2 -2
  949. package/src/modules/workspace/startup/steps/template-files.step.ts +2 -2
  950. package/src/modules/workspace/startup/steps/template-source.ts +2 -2
  951. package/src/modules/workspace/worker-pool.ts +193 -0
  952. package/src/modules/workspace/workspace.routes.ts +9 -12
  953. package/src/modules/workspace/workspace.service.ts +4 -7
  954. package/src/modules/workspace/workspace.tools.ts +53 -34
  955. package/src/modules/workspace/write-denial.ts +4 -5
  956. package/src/modules/write-access/index.ts +7 -0
  957. package/src/shared/__tests__/module-boundaries.lint.test.ts +301 -0
  958. package/src/modules/workflow/__tests__/format-affected-owners.test.ts +0 -85
@@ -0,0 +1,778 @@
1
+ import type { Server as HttpServer } from 'node:http';
2
+ import type { AddressInfo } from 'node:net';
3
+ import express from 'express';
4
+ import { afterEach, describe, expect, it } from 'vitest';
5
+ import type { WorkflowEvent, WorkflowEventPayload } from '@bevel-software/platform-shared';
6
+ import {
7
+ WorkflowEventBus,
8
+ createEventsRoutes,
9
+ EventDelivery,
10
+ createEventAccess,
11
+ type EventAccess,
12
+ type ChangeRequestFacts,
13
+ type EventViewer,
14
+ } from '../index.js';
15
+ import { hashEmail } from '../../../shared/email-identity.js';
16
+
17
+ /** What a `git-sync-failed` says in place of git's words. */
18
+ const REDACTED_REASON = 'The last push did not land.';
19
+
20
+ /**
21
+ * The events route writes an event to a session only when the session's
22
+ * person may read what it names. Two people watch one workspace: Alice may
23
+ * read `Finance/`, Bob may not. Bob still hears everything outside it.
24
+ */
25
+
26
+ const WS = 'main';
27
+ const FINANCE = 'knowledge-base/Finance/Budget.md';
28
+ const PUBLIC = 'knowledge-base/Public/Notes.md';
29
+ /** The same two files as a request names them: KB-repo-relative. */
30
+ const FINANCE_REPO = 'Finance/Budget.md';
31
+ const PUBLIC_REPO = 'Public/Notes.md';
32
+ /** Request #7 changes only `Finance/`; #8 changes `Public/`; #9 is Bob's own, into `Finance/` only. */
33
+ const FINANCE_REQUEST = 7;
34
+ const PUBLIC_REQUEST = 8;
35
+ const BOBS_FINANCE_REQUEST = 9;
36
+
37
+ const USERS: Record<string, { email: string }> = {
38
+ alice: { email: 'alice@example.com' },
39
+ bob: { email: 'bob@example.com' },
40
+ /** A deployment admin. Admin status grants nothing here: events are about what a person may read. */
41
+ root: { email: 'root@example.com' },
42
+ /** Reads the root, like Alice, but not `Finance/`: a folder denied below a readable root. */
43
+ carol: { email: 'carol@example.com' },
44
+ };
45
+
46
+ /** The requests as the request list judges them. */
47
+ const REQUESTS: Record<number, ChangeRequestFacts> = {
48
+ [FINANCE_REQUEST]: { base: 'main', authorId: hashEmail('alice@example.com'), touchedNodeFiles: [{ path: FINANCE_REPO }] },
49
+ [PUBLIC_REQUEST]: { base: 'main', authorId: hashEmail('alice@example.com'), touchedNodeFiles: [{ path: PUBLIC_REPO }] },
50
+ [BOBS_FINANCE_REQUEST]: { base: 'main', authorId: hashEmail('bob@example.com'), touchedNodeFiles: [{ path: FINANCE_REPO }] },
51
+ };
52
+
53
+ /** Fake of the access service the file routes use, and of the change-request scope the tools use. */
54
+ function fakeAccess(): EventAccess & { grantBob: () => void; revokeBob: () => void } {
55
+ let bobReadsFinance = false;
56
+ const reads = (email: string, path: string) =>
57
+ !path.includes('Finance/') || (email === USERS.bob!.email ? bobReadsFinance : email !== USERS.carol!.email);
58
+ return {
59
+ grantBob: () => {
60
+ bobReadsFinance = true;
61
+ },
62
+ revokeBob: () => {
63
+ bobReadsFinance = false;
64
+ },
65
+ mayReadPath: async (_ws, email, path) => reads(email, path),
66
+ mayReadRepoPath: async (_ws, email, repoPath) =>
67
+ repoPath === '' ? email !== USERS.bob!.email : reads(email, `knowledge-base/${repoPath}`),
68
+ readableAtTarget: async (_target, email, repoPaths) =>
69
+ new Set(repoPaths.filter((p) => reads(email, `knowledge-base/${p}`))),
70
+ readableAtBase: async (_base, email, repoPaths) =>
71
+ new Set(repoPaths.filter((p) => reads(email, `knowledge-base/${p}`))),
72
+ changeRequest: async (number) => REQUESTS[number] ?? null,
73
+ };
74
+ }
75
+
76
+ const servers: HttpServer[] = [];
77
+ const streams: AbortController[] = [];
78
+ afterEach(() => {
79
+ for (const s of streams.splice(0)) s.abort();
80
+ for (const s of servers.splice(0)) s.close();
81
+ });
82
+
83
+ function listen(bus: WorkflowEventBus, access: EventAccess): string {
84
+ const app = express();
85
+ const auth: express.RequestHandler = (req, res, next) => {
86
+ const user = USERS[String(req.headers['x-test-user'])];
87
+ if (!user) {
88
+ res.status(401).end();
89
+ return;
90
+ }
91
+ req.userId = String(req.headers['x-test-user']);
92
+ req.userEmail = user.email;
93
+ next();
94
+ };
95
+ app.use('/api', createEventsRoutes(bus, auth, new EventDelivery(access)));
96
+ const server = app.listen(0);
97
+ servers.push(server);
98
+ return `http://127.0.0.1:${(server.address() as AddressInfo).port}`;
99
+ }
100
+
101
+ interface Stream {
102
+ events: WorkflowEvent[];
103
+ /** Resolves once an event matching `pred` has arrived. */
104
+ until: (pred: (e: WorkflowEvent) => boolean) => Promise<void>;
105
+ }
106
+
107
+ async function open(base: string, user: string, sessionId: string, lastEventId?: number): Promise<Stream> {
108
+ const abort = new AbortController();
109
+ streams.push(abort);
110
+ const res = await fetch(`${base}/api/events?session=${sessionId}`, {
111
+ headers: { 'x-test-user': user, ...(lastEventId ? { 'last-event-id': String(lastEventId) } : {}) },
112
+ signal: abort.signal,
113
+ });
114
+ expect(res.status).toBe(200);
115
+ const events: WorkflowEvent[] = [];
116
+ const waiters: Array<{ pred: (e: WorkflowEvent) => boolean; resolve: () => void }> = [];
117
+ void (async () => {
118
+ const decoder = new TextDecoder();
119
+ let buf = '';
120
+ try {
121
+ for await (const chunk of res.body as unknown as AsyncIterable<Uint8Array>) {
122
+ buf += decoder.decode(chunk, { stream: true });
123
+ let end: number;
124
+ while ((end = buf.indexOf('\n\n')) >= 0) {
125
+ const frame = buf.slice(0, end);
126
+ buf = buf.slice(end + 2);
127
+ const data = frame.split('\n').find((l) => l.startsWith('data: '));
128
+ if (!data) continue;
129
+ const event = JSON.parse(data.slice('data: '.length)) as WorkflowEvent;
130
+ events.push(event);
131
+ for (const w of [...waiters]) {
132
+ if (w.pred(event)) {
133
+ waiters.splice(waiters.indexOf(w), 1);
134
+ w.resolve();
135
+ }
136
+ }
137
+ }
138
+ }
139
+ } catch {
140
+ // aborted at teardown
141
+ }
142
+ })();
143
+ return {
144
+ events,
145
+ until: (pred) =>
146
+ events.some(pred) ? Promise.resolve() : new Promise((resolve) => waiters.push({ pred, resolve })),
147
+ };
148
+ }
149
+
150
+ async function focus(base: string, user: string, sessionId: string): Promise<void> {
151
+ const res = await fetch(`${base}/api/events/${sessionId}/focus`, {
152
+ method: 'POST',
153
+ headers: { 'x-test-user': user, 'content-type': 'application/json' },
154
+ body: JSON.stringify({ workspaceId: WS }),
155
+ });
156
+ expect(res.status).toBe(200);
157
+ }
158
+
159
+ const fileChanged = (path: string): WorkflowEventPayload => ({
160
+ kind: 'file-changed',
161
+ workspaceId: WS,
162
+ branch: WS,
163
+ path,
164
+ newSha: 'abc',
165
+ byUserId: 'alice',
166
+ byUserName: 'Alice',
167
+ });
168
+ const lockAcquired = (path: string): WorkflowEventPayload => ({
169
+ kind: 'lock-acquired',
170
+ workspaceId: WS,
171
+ branch: WS,
172
+ path,
173
+ holderUserId: 'alice',
174
+ holderName: 'Alice',
175
+ });
176
+ const lockReleased = (path: string): WorkflowEventPayload => ({ kind: 'lock-released', workspaceId: WS, branch: WS, path });
177
+ const approval = (number: number, path: string): WorkflowEventPayload => ({
178
+ kind: 'approval-changed',
179
+ number,
180
+ path,
181
+ targetBranch: 'main',
182
+ approverUserId: 'alice',
183
+ change: 'added',
184
+ });
185
+ const opened = (number: number): WorkflowEventPayload => ({
186
+ kind: 'change-request-opened',
187
+ number,
188
+ source: 'alice/draft',
189
+ target: 'main',
190
+ authorIdHash: null,
191
+ });
192
+ const documentUnreadable = (path: string): WorkflowEventPayload => ({
193
+ kind: 'document-unreadable',
194
+ workspaceId: WS,
195
+ path,
196
+ reason: 'could not be parsed as a PDF (Invalid XRef stream header)',
197
+ });
198
+ /** Something everybody on the workspace may have; once it arrives, everything emitted before it was judged. */
199
+ const SENTINEL: WorkflowEventPayload = { kind: 'fs-tree-changed', workspaceId: WS, branch: WS };
200
+ const isSentinel = (e: WorkflowEvent) => e.kind === 'fs-tree-changed';
201
+
202
+ /** Emit `payloads`, then the sentinel, and wait for it on every stream. */
203
+ async function emitAndSettle(bus: WorkflowEventBus, payloads: WorkflowEventPayload[], ...on: Stream[]) {
204
+ for (const p of payloads) bus.emit(p);
205
+ const sentinel = bus.emit(SENTINEL);
206
+ await Promise.all(on.map((s) => s.until((e) => e.id === sentinel.id)));
207
+ }
208
+
209
+ const kinds = (s: Stream) => s.events.filter((e) => !isSentinel(e)).map((e) => `${e.kind}:${'path' in e ? e.path : 'number' in e ? e.number : ''}`);
210
+
211
+ describe('events route — delivery rule', () => {
212
+ it('a write, a lock and an approval in a folder reach the reader of the folder, not the other person', async () => {
213
+ const bus = new WorkflowEventBus();
214
+ const base = listen(bus, fakeAccess());
215
+ const alice = await open(base, 'alice', 's-alice');
216
+ const bob = await open(base, 'bob', 's-bob');
217
+ await focus(base, 'alice', 's-alice');
218
+ await focus(base, 'bob', 's-bob');
219
+
220
+ await emitAndSettle(
221
+ bus,
222
+ [fileChanged(FINANCE), lockAcquired(FINANCE), lockReleased(FINANCE), approval(FINANCE_REQUEST, FINANCE_REPO)],
223
+ alice,
224
+ bob,
225
+ );
226
+
227
+ expect(kinds(alice)).toEqual([
228
+ `file-changed:${FINANCE}`,
229
+ `lock-acquired:${FINANCE}`,
230
+ `lock-released:${FINANCE}`,
231
+ `approval-changed:${FINANCE_REPO}`,
232
+ ]);
233
+ expect(kinds(bob)).toEqual([]);
234
+ });
235
+
236
+ it("a document that could not be read is told to the reader of its folder, never to the other person — the notice quotes the parser", async () => {
237
+ // The kind names a path on a workspace, so the structural rule judges it
238
+ // as it judges a write: the same gate the file routes apply, and nothing
239
+ // the rule has to be taught per kind.
240
+ const bus = new WorkflowEventBus();
241
+ const base = listen(bus, fakeAccess());
242
+ const alice = await open(base, 'alice', 's-alice');
243
+ const bob = await open(base, 'bob', 's-bob');
244
+ await focus(base, 'alice', 's-alice');
245
+ await focus(base, 'bob', 's-bob');
246
+
247
+ await emitAndSettle(bus, [documentUnreadable(FINANCE), documentUnreadable(PUBLIC)], alice, bob);
248
+
249
+ expect(kinds(alice)).toEqual([`document-unreadable:${FINANCE}`, `document-unreadable:${PUBLIC}`]);
250
+ expect(kinds(bob)).toEqual([`document-unreadable:${PUBLIC}`]);
251
+ const toBob = bob.events.find((e) => e.kind === 'document-unreadable');
252
+ expect(toBob).toMatchObject({ path: PUBLIC, reason: 'could not be parsed as a PDF (Invalid XRef stream header)' });
253
+ });
254
+
255
+ it('a person keeps every event for what they may read, unchanged and in order', async () => {
256
+ const bus = new WorkflowEventBus();
257
+ const base = listen(bus, fakeAccess());
258
+ const bob = await open(base, 'bob', 's-bob');
259
+ await focus(base, 'bob', 's-bob');
260
+
261
+ const sent = [fileChanged(PUBLIC), lockAcquired(PUBLIC), lockReleased(PUBLIC), approval(PUBLIC_REQUEST, PUBLIC_REPO)];
262
+ await emitAndSettle(bus, sent, bob);
263
+
264
+ expect(bob.events.filter((e) => !isSentinel(e))).toEqual(sent.map((p) => expect.objectContaining(p)));
265
+ });
266
+
267
+ it('a request the person may not see produces no change-request-opened for them; its author always hears of it', async () => {
268
+ const bus = new WorkflowEventBus();
269
+ const base = listen(bus, fakeAccess());
270
+ const alice = await open(base, 'alice', 's-alice');
271
+ const bob = await open(base, 'bob', 's-bob');
272
+ await focus(base, 'alice', 's-alice');
273
+ await focus(base, 'bob', 's-bob');
274
+
275
+ await emitAndSettle(bus, [opened(FINANCE_REQUEST), opened(PUBLIC_REQUEST), opened(BOBS_FINANCE_REQUEST)], alice, bob);
276
+
277
+ // Alice reads `Finance/`: she sees all three.
278
+ expect(kinds(alice)).toEqual([
279
+ `change-request-opened:${FINANCE_REQUEST}`,
280
+ `change-request-opened:${PUBLIC_REQUEST}`,
281
+ `change-request-opened:${BOBS_FINANCE_REQUEST}`,
282
+ ]);
283
+ // Bob may not read `Finance/`: #7 is hidden from him, as the request tools
284
+ // hide it; his own request into it is not.
285
+ expect(kinds(bob)).toEqual([
286
+ `change-request-opened:${PUBLIC_REQUEST}`,
287
+ `change-request-opened:${BOBS_FINANCE_REQUEST}`,
288
+ ]);
289
+ });
290
+
291
+ it('replay after a reconnect obeys the same rule', async () => {
292
+ const bus = new WorkflowEventBus();
293
+ const base = listen(bus, fakeAccess());
294
+ const before = bus.emit(SENTINEL);
295
+ bus.emit(opened(FINANCE_REQUEST));
296
+ bus.emit(approval(FINANCE_REQUEST, FINANCE_REPO));
297
+ bus.emit(opened(PUBLIC_REQUEST));
298
+ const last = bus.emit(approval(PUBLIC_REQUEST, PUBLIC_REPO));
299
+
300
+ const alice = await open(base, 'alice', 's-alice', before.id);
301
+ const bob = await open(base, 'bob', 's-bob', before.id);
302
+ await Promise.all([alice, bob].map((s) => s.until((e) => e.id === last.id)));
303
+
304
+ expect(kinds(alice)).toEqual([
305
+ `change-request-opened:${FINANCE_REQUEST}`,
306
+ `approval-changed:${FINANCE_REPO}`,
307
+ `change-request-opened:${PUBLIC_REQUEST}`,
308
+ `approval-changed:${PUBLIC_REPO}`,
309
+ ]);
310
+ // Neither the request Bob may not see nor its approval is replayed to him.
311
+ expect(kinds(bob)).toEqual([`change-request-opened:${PUBLIC_REQUEST}`, `approval-changed:${PUBLIC_REPO}`]);
312
+ });
313
+
314
+ it('the focus list still decides which workspaces a session hears about', async () => {
315
+ const bus = new WorkflowEventBus();
316
+ const base = listen(bus, fakeAccess());
317
+ const alice = await open(base, 'alice', 's-alice');
318
+ await focus(base, 'alice', 's-alice');
319
+
320
+ bus.emit({ ...fileChanged(PUBLIC), workspaceId: 'elsewhere' } as WorkflowEventPayload);
321
+ await emitAndSettle(bus, [], alice);
322
+
323
+ expect(kinds(alice)).toEqual([]);
324
+ });
325
+
326
+ it('a grant shows on the next event, without a reconnect', async () => {
327
+ const bus = new WorkflowEventBus();
328
+ const access = fakeAccess();
329
+ const base = listen(bus, access);
330
+ const bob = await open(base, 'bob', 's-bob');
331
+ await focus(base, 'bob', 's-bob');
332
+
333
+ await emitAndSettle(bus, [fileChanged(FINANCE)], bob);
334
+ access.grantBob();
335
+ await emitAndSettle(bus, [fileChanged(FINANCE)], bob);
336
+
337
+ expect(kinds(bob)).toEqual([`file-changed:${FINANCE}`]);
338
+ });
339
+
340
+ it('replay after a reconnect asks again: a revocation since the event was first delivered withholds it', async () => {
341
+ const bus = new WorkflowEventBus();
342
+ const access = fakeAccess();
343
+ access.grantBob();
344
+ const base = listen(bus, access);
345
+ const bob = await open(base, 'bob', 's-bob');
346
+ await focus(base, 'bob', 's-bob');
347
+ const before = bus.emit(SENTINEL);
348
+ // Kinds the focus list does not scope, so the replay reaches the rule. The
349
+ // announcement is the control: Bob keeps it, so the replay did run.
350
+ await emitAndSettle(
351
+ bus,
352
+ [approval(FINANCE_REQUEST, FINANCE_REPO), opened(PUBLIC_REQUEST)],
353
+ bob,
354
+ );
355
+ expect(kinds(bob)).toEqual([
356
+ `approval-changed:${FINANCE_REPO}`,
357
+ `change-request-opened:${PUBLIC_REQUEST}`,
358
+ ]);
359
+
360
+ access.revokeBob();
361
+ const again = await open(base, 'bob', 's-bob', before.id);
362
+ await focus(base, 'bob', 's-bob');
363
+ const last = bus.emit(SENTINEL);
364
+ await again.until((e) => e.id === last.id);
365
+
366
+ expect(kinds(again)).toEqual([`change-request-opened:${PUBLIC_REQUEST}`]);
367
+ });
368
+
369
+ it("keeps a session's stream in emission order when a later verdict settles first, live and on replay", async () => {
370
+ const bus = new WorkflowEventBus();
371
+ const base0 = fakeAccess();
372
+ // The verdict on the Finance file takes a while; every other one is immediate.
373
+ const access: EventAccess = {
374
+ ...base0,
375
+ readableAtTarget: (target, email, repoPaths) =>
376
+ repoPaths.includes(FINANCE_REPO)
377
+ ? new Promise((resolve) => setTimeout(() => resolve(base0.readableAtTarget(target, email, repoPaths)), 40))
378
+ : base0.readableAtTarget(target, email, repoPaths),
379
+ };
380
+ const base = listen(bus, access);
381
+ const alice = await open(base, 'alice', 's-alice');
382
+ await focus(base, 'alice', 's-alice');
383
+ const before = bus.emit(SENTINEL);
384
+
385
+ // Kinds the focus list does not scope, so a replay from `before` carries them too.
386
+ const sent = [approval(FINANCE_REQUEST, FINANCE_REPO), approval(PUBLIC_REQUEST, PUBLIC_REPO), opened(PUBLIC_REQUEST)];
387
+ await emitAndSettle(bus, sent, alice);
388
+ const expected = [
389
+ `approval-changed:${FINANCE_REPO}`,
390
+ `approval-changed:${PUBLIC_REPO}`,
391
+ `change-request-opened:${PUBLIC_REQUEST}`,
392
+ ];
393
+ expect(kinds(alice)).toEqual(expected);
394
+
395
+ // The replay queues the same verdicts, and the slow one still goes first.
396
+ const again = await open(base, 'alice', 's-alice-again', before.id);
397
+ await focus(base, 'alice', 's-alice-again');
398
+ const last = bus.emit(SENTINEL);
399
+ await again.until((e) => e.id === last.id);
400
+ expect(kinds(again)).toEqual(expected);
401
+ });
402
+
403
+ it('a request check that fails withholds that approval and that announcement, and nothing after them', async () => {
404
+ const bus = new WorkflowEventBus();
405
+ const unreadable = () => Promise.reject(new Error('access tree unreadable'));
406
+ const access: EventAccess = { ...fakeAccess(), readableAtTarget: unreadable, readableAtBase: unreadable };
407
+ const base = listen(bus, access);
408
+ // Bob: not the request's author, so only the failing check could have shown it to him.
409
+ const bob = await open(base, 'bob', 's-bob');
410
+ await focus(base, 'bob', 's-bob');
411
+
412
+ await emitAndSettle(bus, [approval(PUBLIC_REQUEST, PUBLIC_REPO), fileChanged(PUBLIC), opened(PUBLIC_REQUEST)], bob);
413
+
414
+ expect(kinds(bob)).toEqual([`file-changed:${PUBLIC}`]);
415
+ });
416
+
417
+ it('a lock whose path lacks the knowledge-base/ prefix is judged as the repository path it names', async () => {
418
+ // The real access wiring over a fake access service: Bob may not read `Finance/`.
419
+ const bus = new WorkflowEventBus();
420
+ const access = createEventAccess({
421
+ accessControl: {
422
+ canRead: async (_ws, email, rel) => email !== USERS.bob!.email || !rel.startsWith('Finance/'),
423
+ canReadBatch: async () => new Map(),
424
+ canReadBatchAtRef: async () => null,
425
+ },
426
+ kbDirName: 'knowledge-base',
427
+ getChangeRequest: async () => null,
428
+ workspaces: { hasWorkspace: async () => true, anyWorkspaceId: async () => WS },
429
+ });
430
+ const base = listen(bus, access);
431
+ const alice = await open(base, 'alice', 's-alice');
432
+ const bob = await open(base, 'bob', 's-bob');
433
+ await focus(base, 'alice', 's-alice');
434
+ await focus(base, 'bob', 's-bob');
435
+
436
+ // The lock route takes both spellings; so does a client opening a file by its KB-relative URL.
437
+ await emitAndSettle(
438
+ bus,
439
+ [lockAcquired(FINANCE_REPO), lockReleased(FINANCE_REPO), lockAcquired(`./${FINANCE_REPO}`), lockAcquired('../Finance/Budget.md'), lockAcquired(PUBLIC_REPO)],
440
+ alice,
441
+ bob,
442
+ );
443
+
444
+ expect(kinds(alice)).toEqual([
445
+ `lock-acquired:${FINANCE_REPO}`,
446
+ `lock-released:${FINANCE_REPO}`,
447
+ `lock-acquired:./${FINANCE_REPO}`,
448
+ // A climb the normaliser refuses is withheld from everyone.
449
+ `lock-acquired:${PUBLIC_REPO}`,
450
+ ]);
451
+ expect(kinds(bob)).toEqual([`lock-acquired:${PUBLIC_REPO}`]);
452
+ });
453
+
454
+ it("an agent's tool call reaches its own person through the route, nobody else — an admin included", async () => {
455
+ const bus = new WorkflowEventBus();
456
+ const base = listen(bus, fakeAccess());
457
+ const alice = await open(base, 'alice', 's-alice');
458
+ const bob = await open(base, 'bob', 's-bob');
459
+ const root = await open(base, 'root', 's-root');
460
+ for (const [user, s] of [['alice', 's-alice'], ['bob', 's-bob'], ['root', 's-root']] as const) await focus(base, user, s);
461
+
462
+ await emitAndSettle(
463
+ bus,
464
+ [{ kind: 'agent-tool-call', forUserId: 'alice', threadId: 't', tool: 'write_file', summary: `writing ${FINANCE}` }],
465
+ alice,
466
+ bob,
467
+ root,
468
+ );
469
+
470
+ const toolCalls = (s: Stream) => s.events.filter((e) => e.kind === 'agent-tool-call');
471
+ expect(toolCalls(alice)).toHaveLength(1);
472
+ expect(toolCalls(root)).toEqual([]);
473
+ expect(toolCalls(bob)).toEqual([]);
474
+ });
475
+
476
+ it('fans one event out to 100 sessions through the route, each getting what it may read', async () => {
477
+ const bus = new WorkflowEventBus();
478
+ const base = listen(bus, fakeAccess());
479
+ const sessions = await Promise.all(
480
+ Array.from({ length: 100 }, async (_, i) => {
481
+ const user = i % 2 ? 'bob' : 'alice';
482
+ const stream = await open(base, user, `s-${i}`);
483
+ await focus(base, user, `s-${i}`);
484
+ return stream;
485
+ }),
486
+ );
487
+ await emitAndSettle(bus, [], ...sessions); // every stream is live
488
+
489
+ const samples: number[] = [];
490
+ for (let i = 0; i < 10; i++) {
491
+ const start = performance.now();
492
+ await emitAndSettle(bus, [fileChanged(FINANCE)], ...sessions);
493
+ samples.push(performance.now() - start);
494
+ }
495
+ // Measured and reported, not asserted: this times HTTP writes and the
496
+ // test client's parsing as well as the check, and under a loaded suite
497
+ // that is noise. The check's own 50 ms budget is pinned in `EventDelivery`
498
+ // below, without a socket in the way.
499
+ const { median, max } = spread(samples);
500
+ console.log(`100-session fan-out through the route: median ${median.toFixed(2)} ms, max ${max.toFixed(2)} ms per event`);
501
+ expect(sessions.filter((s) => s.events.some((e) => e.kind === 'file-changed'))).toHaveLength(50);
502
+ });
503
+
504
+ it("git-sync-failed carries git's words only to who may read the root and every conflicted file", async () => {
505
+ const bus = new WorkflowEventBus();
506
+ const base = listen(bus, fakeAccess());
507
+ const people = ['alice', 'bob', 'carol'] as const;
508
+ const [alice, bob, carol] = await Promise.all(people.map((u) => open(base, u, `s-${u}`)));
509
+ for (const u of people) await focus(base, u, `s-${u}`);
510
+
511
+ // A sync conflict's reason quotes its files, as `syncConflictMessage` does;
512
+ // `conflictedPaths` are KB-repo-relative.
513
+ const reason = 'main is not in sync yet: Finance/Budget.md, Public/Notes.md changed both in Hexis and on the git host.';
514
+ await emitAndSettle(
515
+ bus,
516
+ [{ kind: 'git-sync-failed', workspaceId: WS, branch: WS, reason, conflictedPaths: ['Finance/Budget.md', 'Public/Notes.md'] }],
517
+ alice!,
518
+ bob!,
519
+ carol!,
520
+ );
521
+
522
+ const failure = (s: Stream) => s.events.find((e) => e.kind === 'git-sync-failed');
523
+ expect(failure(alice!)).toMatchObject({ reason, conflictedPaths: ['Finance/Budget.md', 'Public/Notes.md'] });
524
+ // Carol reads the root but not `Finance/`: the reason would name its file.
525
+ expect(failure(carol!)).toEqual(
526
+ expect.objectContaining({ workspaceId: WS, branch: WS, reason: REDACTED_REASON, conflictedPaths: ['Public/Notes.md'] }),
527
+ );
528
+ // Bob may not read the root: never git's words, and only the files he may read.
529
+ expect(failure(bob!)).toEqual(
530
+ expect.objectContaining({ workspaceId: WS, branch: WS, reason: REDACTED_REASON, conflictedPaths: ['Public/Notes.md'] }),
531
+ );
532
+ });
533
+
534
+ it('git-sync-failed with no conflict keeps its sentence for a root reader and redacts it for the rest', async () => {
535
+ const bus = new WorkflowEventBus();
536
+ const base = listen(bus, fakeAccess());
537
+ const carol = await open(base, 'carol', 's-carol');
538
+ const bob = await open(base, 'bob', 's-bob');
539
+ await focus(base, 'carol', 's-carol');
540
+ await focus(base, 'bob', 's-bob');
541
+
542
+ await emitAndSettle(bus, [{ kind: 'git-sync-failed', workspaceId: WS, branch: WS, reason: 'The host refused the push.' }], carol, bob);
543
+
544
+ expect(carol.events.find((e) => e.kind === 'git-sync-failed')).toMatchObject({ reason: 'The host refused the push.' });
545
+ const forBob = bob.events.find((e) => e.kind === 'git-sync-failed');
546
+ expect(forBob).toMatchObject({ reason: REDACTED_REASON });
547
+ expect(forBob).not.toHaveProperty('conflictedPaths');
548
+ });
549
+ });
550
+
551
+ describe('EventDelivery', () => {
552
+ const judge = (event: WorkflowEvent, viewer: EventViewer, access: EventAccess) => new EventDelivery(access).judge(event, viewer);
553
+ const stamp = (p: WorkflowEventPayload, id = 1): WorkflowEvent => ({ id, ts: '2026-10-19T00:00:00.000Z', ...p }) as WorkflowEvent;
554
+ const toolCall = stamp({ kind: 'agent-tool-call', forUserId: 'alice', threadId: 't', tool: 'write_file', summary: `writing ${FINANCE}` });
555
+
556
+ it('agent-tool-call reaches the person whose agent made the call, nobody else', async () => {
557
+ const access = fakeAccess();
558
+ expect(await judge(toolCall, { userId: 'alice', email: USERS.alice!.email }, access)).toBe(toolCall);
559
+ expect(await judge(toolCall, { userId: 'root', email: USERS.root!.email }, access)).toBeNull();
560
+ expect(await judge(toolCall, { userId: 'bob', email: USERS.bob!.email }, access)).toBeNull();
561
+ });
562
+
563
+ it('withholds when a verdict cannot be reached', async () => {
564
+ const failing: EventAccess = {
565
+ ...fakeAccess(),
566
+ mayReadPath: () => Promise.reject(new Error('access tree unreadable')),
567
+ mayReadRepoPath: () => Promise.reject(new Error('access tree unreadable')),
568
+ };
569
+ const viewer = { userId: 'alice', email: USERS.alice!.email };
570
+ expect(await judge(stamp(fileChanged(PUBLIC)), viewer, failing)).toBeNull();
571
+ expect(
572
+ await judge(stamp({ kind: 'git-sync-failed', workspaceId: WS, branch: WS, reason: 'git said' }), viewer, failing),
573
+ ).toMatchObject({ reason: REDACTED_REASON });
574
+ });
575
+
576
+ it('withholds a named thing from a session with no email', async () => {
577
+ expect(await judge(stamp(fileChanged(PUBLIC)), { userId: 'x', email: undefined }, fakeAccess())).toBeNull();
578
+ });
579
+
580
+ it('delivers kinds that name nothing as they are', async () => {
581
+ const merged = stamp({ kind: 'change-request-merged', number: FINANCE_REQUEST });
582
+ expect(await judge(merged, { userId: 'bob', email: USERS.bob!.email }, fakeAccess())).toBe(merged);
583
+ });
584
+
585
+ it('judges a 100-session fan-out in under 50 ms per event', async () => {
586
+ // A verdict that costs a real async hop each time, one person per session
587
+ // so the per-person memo saves nothing: the worst case of the check.
588
+ const base = fakeAccess();
589
+ const access: EventAccess = {
590
+ ...base,
591
+ mayReadPath: (ws, email, path) => new Promise((r) => setImmediate(() => r(base.mayReadPath(ws, email, path)))),
592
+ };
593
+ const delivery = new EventDelivery(access);
594
+ const viewers = Array.from({ length: 100 }, (_, i) => ({ userId: `u${i}`, email: i % 2 ? USERS.bob!.email : `u${i}@example.com` }));
595
+ const samples: number[] = [];
596
+ for (let id = 1; id <= 20; id++) {
597
+ const event = stamp(fileChanged(id % 2 ? FINANCE : PUBLIC), id);
598
+ const start = performance.now();
599
+ const verdicts = await Promise.all(viewers.map((v) => delivery.judge(event, v)));
600
+ samples.push(performance.now() - start);
601
+ expect(verdicts.filter(Boolean)).toHaveLength(id % 2 ? 50 : 100);
602
+ }
603
+ const { median, max } = spread(samples);
604
+ console.log(`100-session verdicts: median ${median.toFixed(2)} ms, max ${max.toFixed(2)} ms per event`);
605
+ expect(median).toBeLessThan(50);
606
+ });
607
+
608
+ it('judges a 100-session fan-out of a new request in under 50 ms per event', async () => {
609
+ // The request read and every batch verdict cost a real async hop.
610
+ const base = fakeAccess();
611
+ const hop = <T>(v: Promise<T>) => new Promise<T>((r) => setImmediate(() => r(v)));
612
+ const access: EventAccess = {
613
+ ...base,
614
+ changeRequest: (n) => hop(base.changeRequest(n)),
615
+ readableAtBase: (b, e, ps) => hop(base.readableAtBase(b, e, ps)),
616
+ };
617
+ const delivery = new EventDelivery(access);
618
+ const viewers = Array.from({ length: 100 }, (_, i) => ({ userId: `u${i}`, email: i % 2 ? USERS.bob!.email : `u${i}@example.com` }));
619
+ const samples: number[] = [];
620
+ for (let id = 1; id <= 20; id++) {
621
+ const event = stamp(opened(id % 2 ? FINANCE_REQUEST : PUBLIC_REQUEST), id);
622
+ const start = performance.now();
623
+ const verdicts = await Promise.all(viewers.map((v) => delivery.judge(event, v)));
624
+ samples.push(performance.now() - start);
625
+ expect(verdicts.filter(Boolean)).toHaveLength(id % 2 ? 50 : 100);
626
+ }
627
+ const { median, max } = spread(samples);
628
+ console.log(`100-session request verdicts: median ${median.toFixed(2)} ms, max ${max.toFixed(2)} ms per event`);
629
+ expect(median).toBeLessThan(50);
630
+ });
631
+
632
+ it('judges one person once per event, however many tabs they have', async () => {
633
+ let calls = 0;
634
+ const access: EventAccess = { ...fakeAccess(), mayReadPath: async () => (calls++, true) };
635
+ const delivery = new EventDelivery(access);
636
+ const event = stamp(fileChanged(PUBLIC));
637
+ const viewer = { userId: 'alice', email: USERS.alice!.email };
638
+ await Promise.all([delivery.judge(event, viewer), delivery.judge(event, viewer), delivery.judge(event, viewer)]);
639
+ expect(calls).toBe(1);
640
+ await delivery.judge(stamp(fileChanged(PUBLIC), 2), viewer);
641
+ expect(calls).toBe(2);
642
+ });
643
+
644
+ it('never reuses a settled verdict: judging the same event again asks again', async () => {
645
+ const access = fakeAccess();
646
+ access.grantBob();
647
+ const delivery = new EventDelivery(access);
648
+ const event = stamp(fileChanged(FINANCE));
649
+ const bob = { userId: 'bob', email: USERS.bob!.email };
650
+ expect(await delivery.judge(event, bob)).toBe(event);
651
+ access.revokeBob();
652
+ expect(await delivery.judge(event, bob)).toBeNull();
653
+ });
654
+ });
655
+
656
+ describe('createEventAccess', () => {
657
+ const calls: string[] = [];
658
+ const batches: string[] = [];
659
+ const atRef: string[] = [];
660
+ const requestReads: number[] = [];
661
+ /** The branches the server holds a checkout of: `main` yes, `release` no. */
662
+ const checkedOut = new Set([WS]);
663
+ const access = createEventAccess({
664
+ accessControl: {
665
+ canRead: async (ws, email, rel) => (calls.push(`${ws}|${email}|${rel}`), !rel.startsWith('Finance/')),
666
+ canReadBatch: async (ws, email, paths) => {
667
+ batches.push(`${ws}|${email}|${paths.join(',')}`);
668
+ return new Map(paths.map((p) => [p, !p.startsWith('Finance/')]));
669
+ },
670
+ canReadBatchAtRef: async (ws, ref, email, paths) => {
671
+ atRef.push(`${ws}|${ref}|${email}|${paths.join(',')}`);
672
+ if (ref === 'origin/gone') return null;
673
+ return new Map(paths.map((p) => [p, !p.startsWith('Finance/')]));
674
+ },
675
+ },
676
+ kbDirName: 'knowledge-base',
677
+ getChangeRequest: async (number) => {
678
+ requestReads.push(number);
679
+ await new Promise((r) => setImmediate(r));
680
+ return REQUESTS[number] ?? null;
681
+ },
682
+ workspaces: {
683
+ hasWorkspace: async (workspaceId) => checkedOut.has(workspaceId),
684
+ anyWorkspaceId: async () => WS,
685
+ },
686
+ });
687
+
688
+ it('judges a path as the file routes do, after their normaliser: an unprefixed path is the repository path it names', async () => {
689
+ calls.length = 0;
690
+ expect(await access.mayReadPath(WS, 'a@x', FINANCE)).toBe(false);
691
+ expect(await access.mayReadPath(WS, 'a@x', PUBLIC)).toBe(true);
692
+ expect(await access.mayReadPath(WS, 'a@x', FINANCE_REPO)).toBe(false);
693
+ expect(await access.mayReadPath(WS, 'a@x', `/knowledge-base/${FINANCE_REPO}`)).toBe(false);
694
+ expect(await access.mayReadRepoPath(WS, 'a@x', '')).toBe(true);
695
+ expect(calls).toEqual([
696
+ `${WS}|a@x|${FINANCE_REPO}`,
697
+ `${WS}|a@x|${PUBLIC_REPO}`,
698
+ `${WS}|a@x|${FINANCE_REPO}`,
699
+ `${WS}|a@x|${FINANCE_REPO}`,
700
+ `${WS}|a@x|`,
701
+ ]);
702
+ });
703
+
704
+ it('refuses a path the normaliser refuses, rather than calling it outside the knowledge base', async () => {
705
+ await expect(access.mayReadPath(WS, 'a@x', '../Finance/Budget.md')).rejects.toThrow();
706
+ await expect(access.mayReadPath(WS, 'a@x', '/etc/passwd')).rejects.toThrow();
707
+ });
708
+
709
+ it("judges paths at a target from the target branch's own checkout when the server holds one — one batch, no git", async () => {
710
+ batches.length = 0;
711
+ atRef.length = 0;
712
+ expect(await access.readableAtTarget('main', 'a@x', [PUBLIC_REPO, FINANCE_REPO, PUBLIC_REPO])).toEqual(new Set([PUBLIC_REPO]));
713
+ expect(batches).toEqual([`${WS}|a@x|${PUBLIC_REPO},${FINANCE_REPO}`]);
714
+ expect(atRef).toEqual([]);
715
+ });
716
+
717
+ it('falls back to the published ref, in any clone, for a target with no checkout — and grants nothing on a ref that does not resolve', async () => {
718
+ batches.length = 0;
719
+ atRef.length = 0;
720
+ expect(await access.readableAtTarget('release', 'a@x', [PUBLIC_REPO, FINANCE_REPO])).toEqual(new Set([PUBLIC_REPO]));
721
+ expect(await access.readableAtTarget('gone', 'a@x', [PUBLIC_REPO])).toEqual(new Set());
722
+ expect(await access.readableAtTarget('release', 'a@x', [])).toEqual(new Set());
723
+ expect(batches).toEqual([]);
724
+ expect(atRef).toEqual([`${WS}|origin/release|a@x|${PUBLIC_REPO},${FINANCE_REPO}`, `${WS}|origin/gone|a@x|${PUBLIC_REPO}`]);
725
+ });
726
+
727
+ it("judges a request's files at its published base, as the request tools do — even when the server holds a checkout of it", async () => {
728
+ batches.length = 0;
729
+ atRef.length = 0;
730
+ expect(await access.readableAtBase('main', 'a@x', [PUBLIC_REPO, FINANCE_REPO, PUBLIC_REPO])).toEqual(new Set([PUBLIC_REPO]));
731
+ expect(await access.readableAtBase('gone', 'a@x', [PUBLIC_REPO])).toEqual(new Set());
732
+ expect(batches).toEqual([]);
733
+ expect(atRef).toEqual([`${WS}|origin/main|a@x|${PUBLIC_REPO},${FINANCE_REPO}`, `${WS}|origin/gone|a@x|${PUBLIC_REPO}`]);
734
+ });
735
+
736
+ it("reads a request once for one event's whole fan-out, and again for the next", async () => {
737
+ requestReads.length = 0;
738
+ const delivery = new EventDelivery(access);
739
+ const event = { id: 1, ts: '2026-10-21T00:00:00.000Z', ...opened(FINANCE_REQUEST) } as WorkflowEvent;
740
+ const viewers = Array.from({ length: 100 }, (_, i) => ({ userId: `u${i}`, email: `u${i}@example.com` }));
741
+ // Nobody here reads `Finance/` and nobody wrote #7: hidden from all of them.
742
+ expect((await Promise.all(viewers.map((v) => delivery.judge(event, v)))).filter(Boolean)).toHaveLength(0);
743
+ expect(requestReads).toEqual([FINANCE_REQUEST]);
744
+ // Its author sees it, and that is a fresh read: a settled one is never reused.
745
+ expect(await delivery.judge({ ...event, id: 2 }, { userId: 'alice', email: USERS.alice!.email })).not.toBeNull();
746
+ expect(requestReads).toEqual([FINANCE_REQUEST, FINANCE_REQUEST]);
747
+ });
748
+
749
+ it('hides a request that cannot be found, and a move whose old name is closed', async () => {
750
+ const moved = createEventAccess({
751
+ accessControl: {
752
+ canRead: async () => true,
753
+ canReadBatch: async () => new Map(),
754
+ canReadBatchAtRef: async (_ws, _ref, _email, paths) => new Map(paths.map((p) => [p, !p.startsWith('Finance/')])),
755
+ },
756
+ kbDirName: 'knowledge-base',
757
+ getChangeRequest: async (number) =>
758
+ number === 1
759
+ ? { base: 'main', authorId: hashEmail('alice@example.com'), touchedNodeFiles: [{ path: PUBLIC_REPO, previousPath: FINANCE_REPO }] }
760
+ : number === 3
761
+ ? { base: 'main', authorId: hashEmail('alice@example.com'), touchedNodeFiles: [{ path: PUBLIC_REPO }] }
762
+ : null,
763
+ workspaces: { hasWorkspace: async () => true, anyWorkspaceId: async () => WS },
764
+ });
765
+ const delivery = new EventDelivery(moved);
766
+ const bob = { userId: 'bob', email: USERS.bob!.email };
767
+ const stampOpened = (n: number) => ({ id: n, ts: '2026-10-21T00:00:00.000Z', ...opened(n) }) as WorkflowEvent;
768
+ expect(await delivery.judge(stampOpened(1), bob)).toBeNull();
769
+ expect(await delivery.judge(stampOpened(2), bob)).toBeNull();
770
+ // The control: the same file, not moved, is readable at the base and shows the request.
771
+ expect(await delivery.judge(stampOpened(3), bob)).not.toBeNull();
772
+ });
773
+ });
774
+
775
+ function spread(samples: number[]): { median: number; max: number } {
776
+ const sorted = [...samples].sort((a, b) => a - b);
777
+ return { median: sorted[Math.floor(sorted.length / 2)]!, max: sorted[sorted.length - 1]! };
778
+ }