@bevel-software/platform-core-backend 0.33.0 → 0.35.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 (602) hide show
  1. package/agent-guide/access-control.md +146 -289
  2. package/agent-guide/conventions.md +23 -25
  3. package/agent-guide/directory-structure.md +72 -120
  4. package/agent-guide/drafts-and-change-requests.md +92 -0
  5. package/agent-guide/for-git-users.md +47 -0
  6. package/agent-guide/glossary.md +36 -0
  7. package/agent-guide/how-agents-find-things.md +49 -0
  8. package/agent-guide/html-views.md +239 -8
  9. package/agent-guide/new-knowledge-base.md +9 -8
  10. package/agent-guide/skills.md +67 -42
  11. package/agent-guide/start-here.md +65 -0
  12. package/agent-guide/tool-manuals.md +133 -155
  13. package/agent-guide/tools.md +67 -0
  14. package/agent-guide/where-a-new-file-goes.md +45 -28
  15. package/dist/core/catalog-revision.d.ts +12 -1
  16. package/dist/core/catalog-revision.d.ts.map +1 -1
  17. package/dist/core/catalog-revision.js +23 -3
  18. package/dist/core/catalog-revision.js.map +1 -1
  19. package/dist/core/core-ports.d.ts +41 -0
  20. package/dist/core/core-ports.d.ts.map +1 -1
  21. package/dist/core/core-ports.js.map +1 -1
  22. package/dist/core/create-core-server.d.ts.map +1 -1
  23. package/dist/core/create-core-server.js +15 -8
  24. package/dist/core/create-core-server.js.map +1 -1
  25. package/dist/core/create-core-services.d.ts +22 -5
  26. package/dist/core/create-core-services.d.ts.map +1 -1
  27. package/dist/core/create-core-services.js +44 -16
  28. package/dist/core/create-core-services.js.map +1 -1
  29. package/dist/core/lifecycle.d.ts +16 -0
  30. package/dist/core/lifecycle.d.ts.map +1 -1
  31. package/dist/core/lifecycle.js +12 -2
  32. package/dist/core/lifecycle.js.map +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js.map +1 -1
  36. package/dist/modules/access/access-control.interface.d.ts +39 -9
  37. package/dist/modules/access/access-control.interface.d.ts.map +1 -1
  38. package/dist/modules/access/access-control.service.d.ts +15 -3
  39. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  40. package/dist/modules/access/access-control.service.js +239 -75
  41. package/dist/modules/access/access-control.service.js.map +1 -1
  42. package/dist/modules/access/access-mutation.service.d.ts +22 -24
  43. package/dist/modules/access/access-mutation.service.d.ts.map +1 -1
  44. package/dist/modules/access/access-mutation.service.js +48 -51
  45. package/dist/modules/access/access-mutation.service.js.map +1 -1
  46. package/dist/modules/access/access-view.d.ts.map +1 -1
  47. package/dist/modules/access/access-view.js +12 -11
  48. package/dist/modules/access/access-view.js.map +1 -1
  49. package/dist/modules/access/access.routes.d.ts +3 -0
  50. package/dist/modules/access/access.routes.d.ts.map +1 -1
  51. package/dist/modules/access/access.routes.js +58 -33
  52. package/dist/modules/access/access.routes.js.map +1 -1
  53. package/dist/modules/access/groups-admin.routes.d.ts.map +1 -1
  54. package/dist/modules/access/groups-admin.routes.js +4 -2
  55. package/dist/modules/access/groups-admin.routes.js.map +1 -1
  56. package/dist/modules/access/groups-admin.service.d.ts +44 -13
  57. package/dist/modules/access/groups-admin.service.d.ts.map +1 -1
  58. package/dist/modules/access/groups-admin.service.js +80 -38
  59. package/dist/modules/access/groups-admin.service.js.map +1 -1
  60. package/dist/modules/access/groups-edit.d.ts +1 -1
  61. package/dist/modules/access/groups-edit.d.ts.map +1 -1
  62. package/dist/modules/access/groups-edit.js +1 -1
  63. package/dist/modules/access/groups-edit.js.map +1 -1
  64. package/dist/modules/access/index.d.ts +1 -1
  65. package/dist/modules/access/index.d.ts.map +1 -1
  66. package/dist/modules/access/reference-scan.d.ts +116 -24
  67. package/dist/modules/access/reference-scan.d.ts.map +1 -1
  68. package/dist/modules/access/reference-scan.js +305 -44
  69. package/dist/modules/access/reference-scan.js.map +1 -1
  70. package/dist/modules/access/roles-admin.service.d.ts +17 -8
  71. package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
  72. package/dist/modules/access/roles-admin.service.js +32 -23
  73. package/dist/modules/access/roles-admin.service.js.map +1 -1
  74. package/dist/modules/access-model/access-grammar.d.ts +35 -10
  75. package/dist/modules/access-model/access-grammar.d.ts.map +1 -1
  76. package/dist/modules/access-model/access-grammar.js +60 -20
  77. package/dist/modules/access-model/access-grammar.js.map +1 -1
  78. package/dist/modules/access-model/access-splice.d.ts +22 -18
  79. package/dist/modules/access-model/access-splice.d.ts.map +1 -1
  80. package/dist/modules/access-model/access-splice.js +20 -14
  81. package/dist/modules/access-model/access-splice.js.map +1 -1
  82. package/dist/modules/access-model/group-files.d.ts +1 -0
  83. package/dist/modules/access-model/group-files.d.ts.map +1 -1
  84. package/dist/modules/access-model/group-files.js +5 -1
  85. package/dist/modules/access-model/group-files.js.map +1 -1
  86. package/dist/modules/agent-guide/agent-guide.d.ts +47 -7
  87. package/dist/modules/agent-guide/agent-guide.d.ts.map +1 -1
  88. package/dist/modules/agent-guide/agent-guide.js +103 -13
  89. package/dist/modules/agent-guide/agent-guide.js.map +1 -1
  90. package/dist/modules/agent-guide/agent-guide.tools.d.ts +6 -2
  91. package/dist/modules/agent-guide/agent-guide.tools.d.ts.map +1 -1
  92. package/dist/modules/agent-guide/agent-guide.tools.js +46 -22
  93. package/dist/modules/agent-guide/agent-guide.tools.js.map +1 -1
  94. package/dist/modules/agent-guide/guide-budget.d.ts +48 -0
  95. package/dist/modules/agent-guide/guide-budget.d.ts.map +1 -0
  96. package/dist/modules/agent-guide/guide-budget.js +67 -0
  97. package/dist/modules/agent-guide/guide-budget.js.map +1 -0
  98. package/dist/modules/agent-guide/index.d.ts +2 -1
  99. package/dist/modules/agent-guide/index.d.ts.map +1 -1
  100. package/dist/modules/agent-guide/index.js +2 -1
  101. package/dist/modules/agent-guide/index.js.map +1 -1
  102. package/dist/modules/agent-instructions/compose.d.ts +3 -1
  103. package/dist/modules/agent-instructions/compose.d.ts.map +1 -1
  104. package/dist/modules/agent-instructions/compose.js +7 -1
  105. package/dist/modules/agent-instructions/compose.js.map +1 -1
  106. package/dist/modules/agent-instructions/shared-file-rules.d.ts +5 -1
  107. package/dist/modules/agent-instructions/shared-file-rules.d.ts.map +1 -1
  108. package/dist/modules/agent-instructions/shared-file-rules.js +26 -9
  109. package/dist/modules/agent-instructions/shared-file-rules.js.map +1 -1
  110. package/dist/modules/agent-scope/agent-scope.contract.d.ts +67 -0
  111. package/dist/modules/agent-scope/agent-scope.contract.d.ts.map +1 -0
  112. package/dist/modules/agent-scope/agent-scope.contract.js +27 -0
  113. package/dist/modules/agent-scope/agent-scope.contract.js.map +1 -0
  114. package/dist/modules/agent-scope/connection-scope.d.ts +111 -0
  115. package/dist/modules/agent-scope/connection-scope.d.ts.map +1 -0
  116. package/dist/modules/agent-scope/connection-scope.js +165 -0
  117. package/dist/modules/agent-scope/connection-scope.js.map +1 -0
  118. package/dist/modules/agent-scope/index.d.ts +3 -0
  119. package/dist/modules/agent-scope/index.d.ts.map +1 -0
  120. package/dist/modules/agent-scope/index.js +3 -0
  121. package/dist/modules/agent-scope/index.js.map +1 -0
  122. package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
  123. package/dist/modules/audit/agent-audit.service.js +2 -0
  124. package/dist/modules/audit/agent-audit.service.js.map +1 -1
  125. package/dist/modules/audit/audit.contract.d.ts +6 -0
  126. package/dist/modules/audit/audit.contract.d.ts.map +1 -1
  127. package/dist/modules/audit/audit.contract.js.map +1 -1
  128. package/dist/modules/auth/account-admission.d.ts +12 -0
  129. package/dist/modules/auth/account-admission.d.ts.map +1 -1
  130. package/dist/modules/auth/account-admission.js +15 -0
  131. package/dist/modules/auth/account-admission.js.map +1 -1
  132. package/dist/modules/auth/auth.middleware.d.ts +27 -1
  133. package/dist/modules/auth/auth.middleware.d.ts.map +1 -1
  134. package/dist/modules/auth/auth.middleware.js +42 -4
  135. package/dist/modules/auth/auth.middleware.js.map +1 -1
  136. package/dist/modules/auth/auth.routes.d.ts +13 -9
  137. package/dist/modules/auth/auth.routes.d.ts.map +1 -1
  138. package/dist/modules/auth/auth.routes.js +35 -29
  139. package/dist/modules/auth/auth.routes.js.map +1 -1
  140. package/dist/modules/auth/auth.service.d.ts +55 -6
  141. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  142. package/dist/modules/auth/auth.service.js +128 -34
  143. package/dist/modules/auth/auth.service.js.map +1 -1
  144. package/dist/modules/auth/index.d.ts +1 -1
  145. package/dist/modules/auth/index.d.ts.map +1 -1
  146. package/dist/modules/auth/index.js +1 -1
  147. package/dist/modules/auth/index.js.map +1 -1
  148. package/dist/modules/auth/oidc-auth-provider.d.ts.map +1 -1
  149. package/dist/modules/auth/oidc-auth-provider.js +2 -9
  150. package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
  151. package/dist/modules/code-mode/code-mode.tool.js +2 -2
  152. package/dist/modules/code-mode/code-mode.tool.js.map +1 -1
  153. package/dist/modules/connection-probe/connection-probe.service.d.ts +0 -12
  154. package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
  155. package/dist/modules/connection-probe/connection-probe.service.js +1 -38
  156. package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
  157. package/dist/modules/database/core-schema.d.ts +68 -0
  158. package/dist/modules/database/core-schema.d.ts.map +1 -1
  159. package/dist/modules/database/core-schema.js +33 -0
  160. package/dist/modules/database/core-schema.js.map +1 -1
  161. package/dist/modules/declared-variables/declared-variables.routes.d.ts +8 -1
  162. package/dist/modules/declared-variables/declared-variables.routes.d.ts.map +1 -1
  163. package/dist/modules/declared-variables/declared-variables.routes.js +13 -2
  164. package/dist/modules/declared-variables/declared-variables.routes.js.map +1 -1
  165. package/dist/modules/embed/embed.tools.d.ts.map +1 -1
  166. package/dist/modules/embed/embed.tools.js +5 -0
  167. package/dist/modules/embed/embed.tools.js.map +1 -1
  168. package/dist/modules/kb-fs/index.d.ts +2 -0
  169. package/dist/modules/kb-fs/index.d.ts.map +1 -1
  170. package/dist/modules/kb-fs/index.js +1 -0
  171. package/dist/modules/kb-fs/index.js.map +1 -1
  172. package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
  173. package/dist/modules/kb-fs/locking-filesystem.js +7 -1
  174. package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
  175. package/dist/modules/kb-fs/repo-path.d.ts +26 -6
  176. package/dist/modules/kb-fs/repo-path.d.ts.map +1 -1
  177. package/dist/modules/kb-fs/repo-path.js +22 -7
  178. package/dist/modules/kb-fs/repo-path.js.map +1 -1
  179. package/dist/modules/kb-fs/tmp-ref.d.ts +36 -0
  180. package/dist/modules/kb-fs/tmp-ref.d.ts.map +1 -0
  181. package/dist/modules/kb-fs/tmp-ref.js +76 -0
  182. package/dist/modules/kb-fs/tmp-ref.js.map +1 -0
  183. package/dist/modules/mcp/mcp-auth.middleware.d.ts +7 -0
  184. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
  185. package/dist/modules/mcp/mcp-auth.middleware.js +14 -1
  186. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
  187. package/dist/modules/mcp/mcp.routes.d.ts +7 -1
  188. package/dist/modules/mcp/mcp.routes.d.ts.map +1 -1
  189. package/dist/modules/mcp/mcp.routes.js +39 -4
  190. package/dist/modules/mcp/mcp.routes.js.map +1 -1
  191. package/dist/modules/mcp/mcp.service.d.ts +11 -0
  192. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  193. package/dist/modules/mcp/mcp.service.js +74 -48
  194. package/dist/modules/mcp/mcp.service.js.map +1 -1
  195. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +24 -1
  196. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  197. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +45 -10
  198. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  199. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +9 -0
  200. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -1
  201. package/dist/modules/mcp/oauth/oauth-consent.routes.js +34 -1
  202. package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -1
  203. package/dist/modules/plugins/index.d.ts +1 -1
  204. package/dist/modules/plugins/index.d.ts.map +1 -1
  205. package/dist/modules/plugins/index.js.map +1 -1
  206. package/dist/modules/plugins/plugin-links.d.ts +18 -2
  207. package/dist/modules/plugins/plugin-links.d.ts.map +1 -1
  208. package/dist/modules/plugins/plugin-links.js.map +1 -1
  209. package/dist/modules/plugins/plugins.routes.d.ts +5 -1
  210. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  211. package/dist/modules/plugins/plugins.routes.js +32 -5
  212. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  213. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts +11 -1
  214. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts.map +1 -1
  215. package/dist/modules/secrets-vault/db-secrets-vault.service.js +159 -24
  216. package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -1
  217. package/dist/modules/secrets-vault/index.d.ts +1 -1
  218. package/dist/modules/secrets-vault/index.d.ts.map +1 -1
  219. package/dist/modules/secrets-vault/index.js +1 -1
  220. package/dist/modules/secrets-vault/index.js.map +1 -1
  221. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts +53 -11
  222. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts.map +1 -1
  223. package/dist/modules/secrets-vault/secrets-vault.contract.js +27 -0
  224. package/dist/modules/secrets-vault/secrets-vault.contract.js.map +1 -1
  225. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +9 -0
  226. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  227. package/dist/modules/secrets-vault/secrets-vault.routes.js +100 -42
  228. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  229. package/dist/modules/settings/oidc-check.d.ts.map +1 -1
  230. package/dist/modules/settings/oidc-check.js +5 -17
  231. package/dist/modules/settings/oidc-check.js.map +1 -1
  232. package/dist/modules/skills/index.d.ts +3 -3
  233. package/dist/modules/skills/index.d.ts.map +1 -1
  234. package/dist/modules/skills/index.js +0 -2
  235. package/dist/modules/skills/index.js.map +1 -1
  236. package/dist/modules/skills/skills.contract.d.ts +16 -0
  237. package/dist/modules/skills/skills.contract.d.ts.map +1 -1
  238. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  239. package/dist/modules/skills/skills.service.js +6 -1
  240. package/dist/modules/skills/skills.service.js.map +1 -1
  241. package/dist/modules/skills/skills.tools.d.ts.map +1 -1
  242. package/dist/modules/skills/skills.tools.js +25 -13
  243. package/dist/modules/skills/skills.tools.js.map +1 -1
  244. package/dist/modules/tool-auth/external-api-key.interface.d.ts +11 -0
  245. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
  246. package/dist/modules/tool-auth/external-api-key.interface.js.map +1 -1
  247. package/dist/modules/tool-auth/external-api-key.service.d.ts +1 -0
  248. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  249. package/dist/modules/tool-auth/external-api-key.service.js +4 -1
  250. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  251. package/dist/modules/tool-auth/index.d.ts +1 -1
  252. package/dist/modules/tool-auth/index.d.ts.map +1 -1
  253. package/dist/modules/tool-auth/internal-token.service.d.ts +9 -0
  254. package/dist/modules/tool-auth/internal-token.service.d.ts.map +1 -1
  255. package/dist/modules/tool-auth/internal-token.service.js +1 -0
  256. package/dist/modules/tool-auth/internal-token.service.js.map +1 -1
  257. package/dist/modules/tool-auth/tool-auth.middleware.d.ts +27 -3
  258. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
  259. package/dist/modules/tool-auth/tool-auth.middleware.js +32 -6
  260. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
  261. package/dist/modules/tool-helpers/tool-context.d.ts +7 -0
  262. package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
  263. package/dist/modules/tool-helpers/tool-context.js +3 -0
  264. package/dist/modules/tool-helpers/tool-context.js.map +1 -1
  265. package/dist/modules/tool-helpers/tool-def.js +1 -1
  266. package/dist/modules/tool-helpers/tool-def.js.map +1 -1
  267. package/dist/modules/tool-helpers/tool-handler.d.ts +15 -0
  268. package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
  269. package/dist/modules/tool-helpers/tool-handler.js +19 -0
  270. package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
  271. package/dist/modules/tool-helpers/tool.contract.d.ts +10 -0
  272. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
  273. package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
  274. package/dist/modules/tool-helpers/validate-token.d.ts +3 -1
  275. package/dist/modules/tool-helpers/validate-token.d.ts.map +1 -1
  276. package/dist/modules/tool-helpers/validate-token.js +1 -1
  277. package/dist/modules/tool-helpers/validate-token.js.map +1 -1
  278. package/dist/modules/tool-manuals/index.d.ts +3 -3
  279. package/dist/modules/tool-manuals/index.d.ts.map +1 -1
  280. package/dist/modules/tool-manuals/index.js +0 -2
  281. package/dist/modules/tool-manuals/index.js.map +1 -1
  282. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +7 -1
  283. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
  284. package/dist/modules/tool-manuals/mcp-json-discovery.js +69 -38
  285. package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
  286. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +46 -6
  287. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
  288. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +7 -1
  289. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
  290. package/dist/modules/tool-manuals/tool-manuals.routes.js +41 -4
  291. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
  292. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +24 -13
  293. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  294. package/dist/modules/tool-manuals/tool-manuals.service.js +138 -59
  295. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  296. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +8 -2
  297. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  298. package/dist/modules/tool-manuals/tool-manuals.tools.js +56 -20
  299. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  300. package/dist/modules/tool-registry/manual.routes.d.ts +8 -1
  301. package/dist/modules/tool-registry/manual.routes.d.ts.map +1 -1
  302. package/dist/modules/tool-registry/manual.routes.js +27 -7
  303. package/dist/modules/tool-registry/manual.routes.js.map +1 -1
  304. package/dist/modules/tool-registry/tool.contract.d.ts +7 -0
  305. package/dist/modules/tool-registry/tool.contract.d.ts.map +1 -1
  306. package/dist/modules/tool-registry/tool.contract.js.map +1 -1
  307. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  308. package/dist/modules/workflow/agent-tools/workflow.tools.js +36 -27
  309. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  310. package/dist/modules/workflow/git/git.service.d.ts +2 -2
  311. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  312. package/dist/modules/workflow/git/git.service.js +20 -35
  313. package/dist/modules/workflow/git/git.service.js.map +1 -1
  314. package/dist/modules/workflow/workflow.service.d.ts +2 -1
  315. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  316. package/dist/modules/workflow/workflow.service.js +3 -0
  317. package/dist/modules/workflow/workflow.service.js.map +1 -1
  318. package/dist/modules/workspace/agent-access.gate.d.ts +1 -1
  319. package/dist/modules/workspace/agent-access.gate.d.ts.map +1 -1
  320. package/dist/modules/workspace/agent-access.gate.js +1 -1
  321. package/dist/modules/workspace/agent-access.gate.js.map +1 -1
  322. package/dist/modules/workspace/file-readers/doc-extract.service.d.ts +28 -4
  323. package/dist/modules/workspace/file-readers/doc-extract.service.d.ts.map +1 -1
  324. package/dist/modules/workspace/file-readers/doc-extract.service.js +61 -40
  325. package/dist/modules/workspace/file-readers/doc-extract.service.js.map +1 -1
  326. package/dist/modules/workspace/index.d.ts +8 -0
  327. package/dist/modules/workspace/index.d.ts.map +1 -1
  328. package/dist/modules/workspace/index.js +8 -0
  329. package/dist/modules/workspace/index.js.map +1 -1
  330. package/dist/modules/workspace/nul-scan.d.ts +19 -0
  331. package/dist/modules/workspace/nul-scan.d.ts.map +1 -0
  332. package/dist/modules/workspace/nul-scan.js +55 -0
  333. package/dist/modules/workspace/nul-scan.js.map +1 -0
  334. package/dist/modules/workspace/pattern-matcher.contract.d.ts +110 -27
  335. package/dist/modules/workspace/pattern-matcher.contract.d.ts.map +1 -1
  336. package/dist/modules/workspace/pattern-matcher.contract.js +30 -13
  337. package/dist/modules/workspace/pattern-matcher.contract.js.map +1 -1
  338. package/dist/modules/workspace/ripgrep-search.d.ts +54 -0
  339. package/dist/modules/workspace/ripgrep-search.d.ts.map +1 -0
  340. package/dist/modules/workspace/ripgrep-search.js +657 -0
  341. package/dist/modules/workspace/ripgrep-search.js.map +1 -0
  342. package/dist/modules/workspace/ripgrep-version.d.ts +15 -0
  343. package/dist/modules/workspace/ripgrep-version.d.ts.map +1 -0
  344. package/dist/modules/workspace/ripgrep-version.js +31 -0
  345. package/dist/modules/workspace/ripgrep-version.js.map +1 -0
  346. package/dist/modules/workspace/startup/beside-checkout.d.ts +8 -5
  347. package/dist/modules/workspace/startup/beside-checkout.d.ts.map +1 -1
  348. package/dist/modules/workspace/startup/beside-checkout.js +14 -5
  349. package/dist/modules/workspace/startup/beside-checkout.js.map +1 -1
  350. package/dist/modules/workspace/worker-pool.d.ts +3 -4
  351. package/dist/modules/workspace/worker-pool.d.ts.map +1 -1
  352. package/dist/modules/workspace/worker-pool.js.map +1 -1
  353. package/dist/modules/workspace/workspace-tmp.d.ts +146 -0
  354. package/dist/modules/workspace/workspace-tmp.d.ts.map +1 -0
  355. package/dist/modules/workspace/workspace-tmp.js +435 -0
  356. package/dist/modules/workspace/workspace-tmp.js.map +1 -0
  357. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  358. package/dist/modules/workspace/workspace.routes.js +5 -26
  359. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  360. package/dist/modules/workspace/workspace.service.d.ts +47 -6
  361. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  362. package/dist/modules/workspace/workspace.service.js +86 -6
  363. package/dist/modules/workspace/workspace.service.js.map +1 -1
  364. package/dist/modules/workspace/workspace.tools.d.ts +3 -2
  365. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  366. package/dist/modules/workspace/workspace.tools.js +531 -137
  367. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  368. package/dist/shared/oauth-token-error.d.ts +23 -0
  369. package/dist/shared/oauth-token-error.d.ts.map +1 -0
  370. package/dist/shared/oauth-token-error.js +47 -0
  371. package/dist/shared/oauth-token-error.js.map +1 -0
  372. package/dist/shared/path-order.d.ts +28 -8
  373. package/dist/shared/path-order.d.ts.map +1 -1
  374. package/dist/shared/path-order.js +37 -8
  375. package/dist/shared/path-order.js.map +1 -1
  376. package/dist/shared/read-capped.d.ts +19 -0
  377. package/dist/shared/read-capped.d.ts.map +1 -0
  378. package/dist/shared/read-capped.js +45 -0
  379. package/dist/shared/read-capped.js.map +1 -0
  380. package/migrations/0022_session_version.sql +6 -0
  381. package/migrations/0023_agent_path.sql +3 -0
  382. package/migrations/meta/0022_snapshot.json +2360 -0
  383. package/migrations/meta/0023_snapshot.json +2378 -0
  384. package/migrations/meta/_journal.json +14 -0
  385. package/package.json +4 -3
  386. package/src/__tests__/hexis-catalog.ts +144 -0
  387. package/src/__tests__/pg-scratch.test.ts +69 -0
  388. package/src/__tests__/pg-scratch.ts +31 -0
  389. package/src/__tests__/real-disk.ts +21 -0
  390. package/src/__tests__/slow-ripgrep.ts +65 -0
  391. package/src/__tests__/tokens.ts +19 -0
  392. package/src/__tests__/tool-manuals.ts +32 -0
  393. package/src/__tests__/tool-wiring.ts +25 -0
  394. package/src/core/__tests__/boot-without-ripgrep.test.ts +34 -0
  395. package/src/core/__tests__/catalog-revision.test.ts +89 -0
  396. package/src/core/__tests__/damaged-document.tools.test.ts +2 -2
  397. package/src/core/__tests__/gated-boot.test.ts +8 -1
  398. package/src/core/__tests__/lifecycle.test.ts +46 -13
  399. package/src/core/__tests__/oauth-sign-in-real-file.test.ts +179 -0
  400. package/src/core/catalog-revision.ts +24 -2
  401. package/src/core/core-ports.ts +42 -0
  402. package/src/core/create-core-server.ts +14 -1
  403. package/src/core/create-core-services.ts +62 -15
  404. package/src/core/lifecycle.ts +26 -2
  405. package/src/index.ts +1 -1
  406. package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +12 -0
  407. package/src/modules/access/__tests__/access-control.colliding-name-cases.test.ts +113 -0
  408. package/src/modules/access/__tests__/access-control.frontmatter-head.test.ts +117 -0
  409. package/src/modules/access/__tests__/access-control.group-named-admin.test.ts +122 -0
  410. package/src/modules/access/__tests__/access-control.preview-relocation.test.ts +50 -0
  411. package/src/modules/access/__tests__/access-declarations.test.ts +19 -0
  412. package/src/modules/access/__tests__/access-groups.test.ts +55 -22
  413. package/src/modules/access/__tests__/access-mutation.service.test.ts +85 -59
  414. package/src/modules/access/__tests__/access-restrict-here.test.ts +7 -5
  415. package/src/modules/access/__tests__/access.routes.admins.test.ts +1 -0
  416. package/src/modules/access/__tests__/access.routes.batch.test.ts +2 -0
  417. package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +2 -0
  418. package/src/modules/access/__tests__/access.routes.group-grant.test.ts +50 -14
  419. package/src/modules/access/__tests__/access.routes.overrides.test.ts +2 -1
  420. package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +1 -0
  421. package/src/modules/access/__tests__/access.routes.prospective.test.ts +52 -10
  422. package/src/modules/access/__tests__/access.routes.revoke.test.ts +18 -13
  423. package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +2 -0
  424. package/src/modules/access/__tests__/grant-sources.test.ts +20 -15
  425. package/src/modules/access/__tests__/groups-admin.routes.test.ts +61 -0
  426. package/src/modules/access/__tests__/groups-admin.service.test.ts +211 -18
  427. package/src/modules/access/__tests__/holder-changes.test.ts +127 -0
  428. package/src/modules/access/__tests__/reference-scan.test.ts +366 -14
  429. package/src/modules/access/__tests__/roles-admin.security.test.ts +1 -1
  430. package/src/modules/access/__tests__/roles-admin.service.test.ts +43 -22
  431. package/src/modules/access/__tests__/roles-capabilities.test.ts +6 -2
  432. package/src/modules/access/__tests__/roles.routes.test.ts +1 -1
  433. package/src/modules/access/access-control.interface.ts +43 -10
  434. package/src/modules/access/access-control.service.ts +250 -72
  435. package/src/modules/access/access-mutation.service.ts +48 -53
  436. package/src/modules/access/access-view.ts +12 -10
  437. package/src/modules/access/access.routes.ts +66 -37
  438. package/src/modules/access/groups-admin.routes.ts +4 -2
  439. package/src/modules/access/groups-admin.service.ts +114 -44
  440. package/src/modules/access/groups-edit.ts +1 -1
  441. package/src/modules/access/index.ts +1 -1
  442. package/src/modules/access/reference-scan.ts +319 -46
  443. package/src/modules/access/roles-admin.service.ts +43 -26
  444. package/src/modules/access/synced-groups-writer.ts +1 -1
  445. package/src/modules/access-model/__tests__/access-grammar.test.ts +38 -1
  446. package/src/modules/access-model/__tests__/access-splice.test.ts +50 -8
  447. package/src/modules/access-model/access-grammar.ts +65 -20
  448. package/src/modules/access-model/access-splice.ts +31 -23
  449. package/src/modules/access-model/group-files.ts +5 -0
  450. package/src/modules/agent-guide/__tests__/agent-guide.test.ts +110 -25
  451. package/src/modules/agent-guide/__tests__/agent-guide.tools.test.ts +38 -11
  452. package/src/modules/agent-guide/__tests__/guide-budget.test.ts +95 -0
  453. package/src/modules/agent-guide/__tests__/guide-eval.test.ts +182 -0
  454. package/src/modules/agent-guide/__tests__/guide-matches-code.test.ts +263 -0
  455. package/src/modules/agent-guide/__tests__/tool-surface.json +514 -0
  456. package/src/modules/agent-guide/__tests__/tool-surface.test.ts +75 -0
  457. package/src/modules/agent-guide/agent-guide.tools.ts +51 -22
  458. package/src/modules/agent-guide/agent-guide.ts +120 -13
  459. package/src/modules/agent-guide/guide-budget.ts +73 -0
  460. package/src/modules/agent-guide/index.ts +12 -0
  461. package/src/modules/agent-instructions/__tests__/shared-file-rules.test.ts +5 -4
  462. package/src/modules/agent-instructions/compose.ts +7 -1
  463. package/src/modules/agent-instructions/shared-file-rules.ts +27 -9
  464. package/src/modules/agent-scope/__tests__/agent-surfaces.connect-as.test.ts +421 -0
  465. package/src/modules/agent-scope/__tests__/connection-scope.test.ts +46 -0
  466. package/src/modules/agent-scope/__tests__/in-memory-kb.ts +148 -0
  467. package/src/modules/agent-scope/agent-scope.contract.ts +83 -0
  468. package/src/modules/agent-scope/connection-scope.ts +199 -0
  469. package/src/modules/agent-scope/index.ts +15 -0
  470. package/src/modules/audit/agent-audit.service.ts +2 -0
  471. package/src/modules/audit/audit.contract.ts +6 -0
  472. package/src/modules/auth/__tests__/auth.middleware.test.ts +30 -2
  473. package/src/modules/auth/__tests__/auth.routes.test.ts +71 -5
  474. package/src/modules/auth/__tests__/auth.service.test.ts +90 -9
  475. package/src/modules/auth/__tests__/password-change-sessions.pg.test.ts +269 -0
  476. package/src/modules/auth/account-admission.ts +19 -0
  477. package/src/modules/auth/auth.middleware.ts +45 -4
  478. package/src/modules/auth/auth.routes.ts +46 -29
  479. package/src/modules/auth/auth.service.ts +135 -34
  480. package/src/modules/auth/index.ts +2 -0
  481. package/src/modules/auth/oidc-auth-provider.ts +2 -9
  482. package/src/modules/code-mode/code-mode.tool.ts +2 -2
  483. package/src/modules/connection-probe/__tests__/connection-probe.service.test.ts +5 -24
  484. package/src/modules/connection-probe/connection-probe.service.ts +1 -34
  485. package/src/modules/database/__tests__/session-version-migration.pg.test.ts +133 -0
  486. package/src/modules/database/core-schema.ts +33 -0
  487. package/src/modules/declared-variables/__tests__/declared-variables.route.test.ts +44 -1
  488. package/src/modules/declared-variables/declared-variables.routes.ts +12 -1
  489. package/src/modules/embed/__tests__/embed.tools.test.ts +12 -0
  490. package/src/modules/embed/embed.tools.ts +5 -0
  491. package/src/modules/kb-fs/__tests__/locking-filesystem.test.ts +25 -0
  492. package/src/modules/kb-fs/__tests__/repo-path.test.ts +53 -8
  493. package/src/modules/kb-fs/index.ts +2 -0
  494. package/src/modules/kb-fs/locking-filesystem.ts +7 -1
  495. package/src/modules/kb-fs/repo-path.ts +33 -7
  496. package/src/modules/kb-fs/tmp-ref.ts +81 -0
  497. package/src/modules/mcp/__tests__/connect-as.pg.test.ts +137 -0
  498. package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +29 -5
  499. package/src/modules/mcp/__tests__/mcp-routes-harness.ts +8 -0
  500. package/src/modules/mcp/__tests__/mcp.connect-as.test.ts +195 -0
  501. package/src/modules/mcp/__tests__/mcp.routes.connect-as.test.ts +192 -0
  502. package/src/modules/mcp/__tests__/oauth-consent.connect-as.test.ts +146 -0
  503. package/src/modules/mcp/mcp-auth.middleware.ts +19 -2
  504. package/src/modules/mcp/mcp.routes.ts +39 -3
  505. package/src/modules/mcp/mcp.service.ts +112 -52
  506. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +46 -8
  507. package/src/modules/mcp/oauth/oauth-consent.routes.ts +41 -1
  508. package/src/modules/plugins/__tests__/plugins.tools.test.ts +38 -2
  509. package/src/modules/plugins/index.ts +1 -1
  510. package/src/modules/plugins/plugin-links.ts +19 -2
  511. package/src/modules/plugins/plugins.routes.ts +35 -4
  512. package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +113 -0
  513. package/src/modules/secrets-vault/__tests__/db-secrets-vault.oauth.test.ts +430 -3
  514. package/src/modules/secrets-vault/__tests__/oauth-live-declaration.route.test.ts +218 -0
  515. package/src/modules/secrets-vault/__tests__/oauth-return-to.route.test.ts +39 -6
  516. package/src/modules/secrets-vault/db-secrets-vault.service.ts +170 -27
  517. package/src/modules/secrets-vault/index.ts +1 -1
  518. package/src/modules/secrets-vault/secrets-vault.contract.ts +61 -11
  519. package/src/modules/secrets-vault/secrets-vault.routes.ts +114 -42
  520. package/src/modules/settings/oidc-check.ts +5 -18
  521. package/src/modules/skills/__tests__/skills.service.test.ts +34 -0
  522. package/src/modules/skills/index.ts +7 -2
  523. package/src/modules/skills/skills.contract.ts +17 -0
  524. package/src/modules/skills/skills.service.ts +5 -1
  525. package/src/modules/skills/skills.tools.ts +45 -14
  526. package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +4 -0
  527. package/src/modules/tool-auth/external-api-key.interface.ts +11 -1
  528. package/src/modules/tool-auth/external-api-key.service.ts +5 -2
  529. package/src/modules/tool-auth/index.ts +1 -1
  530. package/src/modules/tool-auth/internal-token.service.ts +10 -0
  531. package/src/modules/tool-auth/tool-auth.middleware.ts +45 -3
  532. package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +19 -11
  533. package/src/modules/tool-helpers/__tests__/can-write.tools.test.ts +3 -1
  534. package/src/modules/tool-helpers/__tests__/route-tool-schemas.catalog.test.ts +38 -0
  535. package/src/modules/tool-helpers/tool-context.ts +10 -0
  536. package/src/modules/tool-helpers/tool-def.ts +1 -1
  537. package/src/modules/tool-helpers/tool-handler.ts +34 -0
  538. package/src/modules/tool-helpers/tool.contract.ts +10 -0
  539. package/src/modules/tool-helpers/validate-token.ts +4 -2
  540. package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +80 -4
  541. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +197 -11
  542. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +42 -0
  543. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +99 -8
  544. package/src/modules/tool-manuals/index.ts +6 -2
  545. package/src/modules/tool-manuals/mcp-json-discovery.ts +73 -34
  546. package/src/modules/tool-manuals/tool-manuals.contract.ts +40 -6
  547. package/src/modules/tool-manuals/tool-manuals.routes.ts +40 -3
  548. package/src/modules/tool-manuals/tool-manuals.service.ts +169 -61
  549. package/src/modules/tool-manuals/tool-manuals.tools.ts +81 -25
  550. package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +6 -113
  551. package/src/modules/tool-registry/manual.routes.ts +26 -5
  552. package/src/modules/tool-registry/tool.contract.ts +7 -0
  553. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +1 -1
  554. package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +1 -1
  555. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +54 -3
  556. package/src/modules/workflow/agent-tools/workflow.tools.ts +36 -27
  557. package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +130 -3
  558. package/src/modules/workflow/git/git.service.ts +29 -48
  559. package/src/modules/workflow/workflow.service.ts +5 -0
  560. package/src/modules/workspace/__tests__/git-internals.security.test.ts +2 -2
  561. package/src/modules/workspace/__tests__/holds-nul.test.ts +66 -0
  562. package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +3 -3
  563. package/src/modules/workspace/__tests__/ripgrep-search.test.ts +570 -0
  564. package/src/modules/workspace/__tests__/ripgrep-version.test.ts +29 -0
  565. package/src/modules/workspace/__tests__/workspace-tmp.tools.test.ts +928 -0
  566. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +17 -37
  567. package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +20 -8
  568. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +10 -12
  569. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +22 -10
  570. package/src/modules/workspace/__tests__/workspace.tools.test.ts +549 -162
  571. package/src/modules/workspace/agent-access.gate.ts +1 -1
  572. package/src/modules/workspace/file-readers/__tests__/doc-extract.service.test.ts +10 -0
  573. package/src/modules/workspace/file-readers/doc-extract.service.ts +71 -38
  574. package/src/modules/workspace/index.ts +20 -0
  575. package/src/modules/workspace/nul-scan.ts +50 -0
  576. package/src/modules/workspace/pattern-matcher.contract.ts +123 -32
  577. package/src/modules/workspace/ripgrep-search.ts +715 -0
  578. package/src/modules/workspace/ripgrep-version.ts +35 -0
  579. package/src/modules/workspace/startup/__tests__/beside-checkout.test.ts +11 -0
  580. package/src/modules/workspace/startup/beside-checkout.ts +13 -5
  581. package/src/modules/workspace/worker-pool.ts +3 -4
  582. package/src/modules/workspace/workspace-tmp.ts +457 -0
  583. package/src/modules/workspace/workspace.routes.ts +6 -27
  584. package/src/modules/workspace/workspace.service.ts +92 -15
  585. package/src/modules/workspace/workspace.tools.ts +574 -176
  586. package/src/shared/__tests__/read-capped.test.ts +68 -0
  587. package/src/shared/oauth-token-error.ts +46 -0
  588. package/src/shared/path-order.ts +37 -8
  589. package/src/shared/read-capped.ts +40 -0
  590. package/starter-packs/engineering/Plugins/engineering-starter/access.md +1 -1
  591. package/starter-packs/general/Plugins/general-starter/access.md +1 -1
  592. package/starter-packs/operations/Plugins/operations-starter/access.md +1 -1
  593. package/starter-packs/sales/Plugins/sales-starter/access.md +1 -1
  594. package/starter-packs/support/Plugins/support-starter/access.md +1 -1
  595. package/agent-guide/finding-things.md +0 -7
  596. package/agent-guide/introduction.md +0 -27
  597. package/dist/modules/workspace/bounded-matcher.d.ts +0 -73
  598. package/dist/modules/workspace/bounded-matcher.d.ts.map +0 -1
  599. package/dist/modules/workspace/bounded-matcher.js +0 -200
  600. package/dist/modules/workspace/bounded-matcher.js.map +0 -1
  601. package/src/modules/workspace/__tests__/bounded-matcher.test.ts +0 -213
  602. package/src/modules/workspace/bounded-matcher.ts +0 -271
@@ -47,6 +47,15 @@ export interface InternalTokenClaim {
47
47
  * internal token.
48
48
  */
49
49
  connectionId?: string;
50
+ /**
51
+ * The agent configuration the external caller's connection was made as (a
52
+ * repo-relative knowledge-base path), copied at mint from the verified
53
+ * grant or connection — the hosted proxy's loopback token and the local
54
+ * server's exchanged grant both carry it, so every agent surface narrows
55
+ * their calls to that agent's scope (`modules/agent-scope`). Absent is
56
+ * Everything. Carried, never decided, like `connectionId`.
57
+ */
58
+ agentPath?: string;
50
59
  }
51
60
 
52
61
  interface SignedPayload extends InternalTokenClaim {
@@ -148,6 +157,7 @@ export class InternalTokenService {
148
157
  ...(typeof payload.focusedBranch === 'string' ? { focusedBranch: payload.focusedBranch } : {}),
149
158
  ...(payload.externalProxy === true ? { externalProxy: true } : {}),
150
159
  ...(typeof payload.connectionId === 'string' ? { connectionId: payload.connectionId } : {}),
160
+ ...(typeof payload.agentPath === 'string' && payload.agentPath ? { agentPath: payload.agentPath } : {}),
151
161
  };
152
162
  }
153
163
 
@@ -47,6 +47,13 @@ export interface ToolAuth {
47
47
  * recorder attributes a direct tool call to.
48
48
  */
49
49
  connectionId?: string;
50
+ /**
51
+ * The agent configuration an EXTERNAL caller's connection was made as — a
52
+ * connection key's `api_tokens.agent_path`, or the one an `externalProxy`
53
+ * token carries for an agent connection. Absent is Everything. Every agent
54
+ * surface resolves it to the connection's scope (`modules/agent-scope`).
55
+ */
56
+ agentPath?: string;
50
57
  /** Always `'write'` now (the middleware sets it for both internal + external — neither credential carries scope). The read path is dormant until consumer agents are removed. */
51
58
  scope: 'read' | 'write';
52
59
  }
@@ -114,6 +121,14 @@ export type VerifyResult =
114
121
  | { ok: true; auth: ToolAuth }
115
122
  | { ok: false; status: number; message: string; challenge?: string };
116
123
 
124
+ /**
125
+ * A live agent connection's current "Connect as" choice, or null when it is
126
+ * gone or revoked — what `BevelOAuthProvider.liveConnectionChoice` answers.
127
+ */
128
+ export interface ConnectionChoices {
129
+ liveConnectionChoice(connectionId: string): Promise<{ agentPath: string | null } | null>;
130
+ }
131
+
117
132
  /**
118
133
  * The framework-agnostic verify core: bearer token (the value AFTER `Bearer `) →
119
134
  * normalized `ToolAuth`, accepting EITHER a `bevel_…` connection key (external —
@@ -135,6 +150,14 @@ export function createTokenVerifier(
135
150
  * it; absent, internal tokens are judged on their signature alone.
136
151
  */
137
152
  accounts?: Pick<AuthService, 'isActive'>,
153
+ /**
154
+ * Where an `externalProxy` token that names an agent connection reads the
155
+ * connection's CURRENT choice: the token outlives a re-consent, so the
156
+ * agent it was minted with may no longer be the one chosen. A
157
+ * connection no longer live (revoked, deleted) refuses the token. Absent,
158
+ * the token's own choice stands.
159
+ */
160
+ connections?: ConnectionChoices,
138
161
  ): (token: string | undefined) => Promise<VerifyResult> {
139
162
  const missing = { ok: false as const, status: 401, message: 'A connection key or internal token is required' };
140
163
  return async (token) => {
@@ -152,6 +175,13 @@ export function createTokenVerifier(
152
175
  if (accounts && !(await accounts.isActive(claim.userId))) {
153
176
  return { ok: false, status: 401, message: ACCOUNT_DEACTIVATED_MESSAGE };
154
177
  }
178
+ let agentPath = claim.agentPath;
179
+ if (claim.externalProxy && claim.connectionId && connections) {
180
+ const live = await connections.liveConnectionChoice(claim.connectionId);
181
+ // A revoked connection's token is dead here too, as it is at the MCP endpoint.
182
+ if (!live) return { ok: false, status: 401, message: 'Access for this agent was revoked' };
183
+ agentPath = live.agentPath ?? undefined;
184
+ }
155
185
  return claim.externalProxy
156
186
  ? {
157
187
  ok: true,
@@ -159,6 +189,7 @@ export function createTokenVerifier(
159
189
  source: 'external',
160
190
  userId: claim.userId,
161
191
  ...(claim.connectionId ? { connectionId: claim.connectionId } : {}),
192
+ ...(agentPath ? { agentPath } : {}),
162
193
  scope: 'write',
163
194
  },
164
195
  }
@@ -169,7 +200,16 @@ export function createTokenVerifier(
169
200
  if (externalApiKeyService.looksLikeExternalApiKey(token)) {
170
201
  const resolved = await externalApiKeyService.verifyAndLoadToken(token);
171
202
  if (resolved) {
172
- return { ok: true, auth: { source: 'external', userId: resolved.user.id, tokenId: resolved.tokenId, scope: 'write' } };
203
+ return {
204
+ ok: true,
205
+ auth: {
206
+ source: 'external',
207
+ userId: resolved.user.id,
208
+ tokenId: resolved.tokenId,
209
+ ...(resolved.agentPath ? { agentPath: resolved.agentPath } : {}),
210
+ scope: 'write',
211
+ },
212
+ };
173
213
  }
174
214
  // A live key of a switched-off account is told so, not sent to mint another.
175
215
  if (await externalApiKeyService.isKeyOfSwitchedOffAccount?.(token)) {
@@ -192,8 +232,9 @@ export function createToolAuthMiddleware(
192
232
  externalApiKeyService: IExternalApiKeyService,
193
233
  internalTokenService: InternalTokenService,
194
234
  accounts?: Pick<AuthService, 'isActive'>,
235
+ connections?: ConnectionChoices,
195
236
  ): RequestHandler {
196
- const verify = createTokenVerifier(externalApiKeyService, internalTokenService, accounts);
237
+ const verify = createTokenVerifier(externalApiKeyService, internalTokenService, accounts, connections);
197
238
  return async (req: Request, res: Response, next: NextFunction) => {
198
239
  const header = req.headers.authorization;
199
240
  if (!header || !header.toLowerCase().startsWith('bearer ')) {
@@ -233,8 +274,9 @@ export function createManualAuthMiddleware(
233
274
  externalApiKeyService: IExternalApiKeyService,
234
275
  internalTokenService: InternalTokenService,
235
276
  authService: Pick<AuthService, 'isActive' | 'resolveSession'>,
277
+ connections?: ConnectionChoices,
236
278
  ): RequestHandler {
237
- const verify = createTokenVerifier(externalApiKeyService, internalTokenService, authService);
279
+ const verify = createTokenVerifier(externalApiKeyService, internalTokenService, authService, connections);
238
280
  return async (req: Request, res: Response, next: NextFunction) => {
239
281
  const header = req.headers.authorization;
240
282
  if (!header || !header.toLowerCase().startsWith('bearer ')) {
@@ -4,21 +4,27 @@ import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import express from 'express';
6
6
  import { afterEach, beforeEach, describe, expect, it } from 'vitest';
7
- import { ToolRegistry } from '../../tool-registry/tool-registry.js';
8
- import { InternalTokenService } from '../../tool-auth/internal-token.service.js';
9
- import { createToolAuthMiddleware } from '../../tool-auth/tool-auth.middleware.js';
7
+ import { ToolRegistry } from '../../tool-registry/index.js';
8
+ import {
9
+ InternalTokenService,
10
+ RoutineWritePolicyService,
11
+ WorkflowHooks,
12
+ createToolAuthMiddleware,
13
+ loadActiveGroups,
14
+ registerWorkspaceTools,
15
+ } from '../../../__tests__/tool-wiring.js';
10
16
  import { createToolContextResolver } from '../tool-context.js';
11
17
  import { createToolHandlerFactory } from '../tool-handler.js';
12
- import { registerWorkspaceTools } from '../../workspace/workspace.tools.js';
13
- import { RoutineWritePolicyService } from '../../workspace/routine-write-policy.js';
14
- import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
15
- import { ToolDescriptionNotes } from '../../workspace/agent-access.gate.js';
16
- import { SpillStore } from '../../workspace/spill-store.js';
17
- import { DocExtractService, WorkerDocumentExtractor } from '../../workspace/index.js';
18
- import { NEW_ROLE_GUIDANCE } from '../../access-model/roles-yaml-guard.js';
19
- import { loadActiveGroups } from '../../access/access-control.service.js';
18
+ import { DocExtractService, SpillStore, ToolDescriptionNotes, WorkerDocumentExtractor } from '../../workspace/index.js';
20
19
  import { testKbContext } from '../../../__tests__/kb-context.js';
21
20
 
21
+ /**
22
+ * The sentence a refused role creation carries to the agent, as the agent
23
+ * guide states it too: asserted as the words a person reads, not as the
24
+ * module's constant, so a reworded refusal is a visible change here.
25
+ */
26
+ const NEW_ROLE_GUIDANCE = 'add people to existing roles, and use a GROUP for a task- or team-scoped set of people';
27
+
22
28
  /**
23
29
  * The agent's file tools over the production context resolver and a real
24
30
  * workspace on disk: a roles.yaml write that creates a role is refused with a
@@ -71,6 +77,8 @@ async function start(): Promise<string> {
71
77
  canReadBatch: async (_w: string, _u: string, paths: string[]) => new Map(paths.map((p) => [p, true])),
72
78
  // The `after` half of a move's or copy's preview — allowing everything, like the gates above.
73
79
  previewAccessAfterRelocation: async () => ({ read: true, write: true, download: true, owner: true }),
80
+ // Who else loses or gains access in a move: nobody, here.
81
+ prospectiveHolderChanges: async () => ({ lose: [], gain: [] }),
74
82
  } as never;
75
83
  registerWorkspaceTools(registry, router, toolAuth, createToolHandlerFactory(resolve), new SpillStore(path.join(os.tmpdir(), 'bevel-test-spills')), new DocExtractService(docCache, new WorkerDocumentExtractor()), allowAll, testKbContext({ kbDirName: KB }), {
76
84
  // No hook registered: the agent-access gate refuses nothing here.
@@ -24,7 +24,9 @@ import { NodeFs } from '../../kb-fs/node-fs.js';
24
24
  import { workspaceIdForBranch } from '../../../shared/workspace-id.js';
25
25
  import { BranchNotFoundError } from '../../../shared/domain-errors.js';
26
26
  import type { WorkspaceService } from '../../workspace/workspace.service.js';
27
- import { SkillService, registerSkillsTools } from '../../skills/index.js';
27
+ import { registerSkillsTools } from '../../skills/index.js';
28
+ // The service itself, from its file: the module entry offers it as a type only.
29
+ import { SkillService } from '../../skills/skills.service.js';
28
30
  import { defaultBranchWriteVerdicts } from '../index.js';
29
31
 
30
32
  /**
@@ -0,0 +1,38 @@
1
+ import { compileCheck, exampleArguments } from '@bevel-software/platform-mcp-core';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { hexisCatalog } from '../../../__tests__/hexis-catalog.js';
4
+ import { routeToolSchemas } from '../route-tool-schemas.js';
5
+
6
+ /**
7
+ * Every tool a route mounts declares two schemas: the one a client sees
8
+ * (`inputs`, with the platform tools' arguments under `body`) and the FLAT one
9
+ * the route itself checks a call against. The `Call:` line at the top of each
10
+ * description is generated from the first; the route refuses by the second.
11
+ * The two must agree, or a call written from the example is refused one
12
+ * layer in, with nothing in the description to say why.
13
+ *
14
+ * Held here, over the whole catalog Hexis registers, because the flat schema
15
+ * is this module's: `routeToolSchemas` is how a mounted route finds its own,
16
+ * and no other module reads it.
17
+ */
18
+ describe('the flat schema a route checks against accepts the call its own example shows', () => {
19
+ it('for every tool Hexis mounts on a route', async () => {
20
+ const { internal } = await hexisCatalog();
21
+ const mounted = internal.filter((tool) => routeToolSchemas(tool.name) !== undefined);
22
+ // The catalog is the real one: the family every scenario names is in it.
23
+ for (const name of ['read_file', 'write_file', 'list_files', 'grep', 'move_file']) {
24
+ expect(mounted.some((t) => t.name === name), name).toBe(true);
25
+ }
26
+ expect(mounted.length).toBeGreaterThan(12);
27
+ for (const tool of mounted) {
28
+ // The client's schema is the flat one in its envelope (`bodyEnvelope`),
29
+ // so the client's example and the route's check meet on the flat schema:
30
+ // an example written from it must pass the check made from it.
31
+ const flat = routeToolSchemas(tool.name)!.flat;
32
+ const check = compileCheck(flat);
33
+ expect(check.checkable, `${tool.name} (flat): ${check.checkable ? '' : check.reason}`).toBe(true);
34
+ if (!check.checkable) throw new Error(check.reason);
35
+ expect(check.check(exampleArguments(flat)), `${tool.name} (flat)`).toEqual([]);
36
+ }
37
+ });
38
+ });
@@ -17,6 +17,7 @@ import type { WorkflowEventBus } from '../workflow/index.js';
17
17
  import type { AuthService } from '../auth/index.js';
18
18
  import { ToolError, type ToolContext } from './tool.contract.js';
19
19
  import type { ToolAuth } from '../tool-auth/index.js';
20
+ import { resolveConnectionScope, type IAgentScopeResolver } from '../agent-scope/index.js';
20
21
 
21
22
  export interface ToolContextDeps {
22
23
  authService: AuthService;
@@ -40,6 +41,12 @@ export interface ToolContextDeps {
40
41
  loadActiveGroups?: (
41
42
  read: (filename: string) => Promise<string | null>,
42
43
  ) => Promise<{ groups: GroupsIndex; sourceFile: string; health: { ok: boolean } }>;
44
+ /**
45
+ * Resolves the scope of a connection made as an agent configuration. Every
46
+ * deployment passes it. Absent, a credential that names an agent loads
47
+ * nothing — a narrowing that cannot be read is never read as Everything.
48
+ */
49
+ agentScope?: Pick<IAgentScopeResolver, 'resolve'>;
43
50
  }
44
51
 
45
52
  /** A file's text, or null when it does not exist. Any other failure throws. */
@@ -149,9 +156,12 @@ export function createToolContextResolver(deps: ToolContextDeps): ResolveToolCon
149
156
  return fs;
150
157
  };
151
158
 
159
+ const connectionScope = await resolveConnectionScope(deps.agentScope, user.email, auth.agentPath);
160
+
152
161
  return {
153
162
  user,
154
163
  scope: auth.scope,
164
+ connectionScope,
155
165
  source: auth.source,
156
166
  tokenId: auth.tokenId,
157
167
  // For `internal` callers the signed token claim is the ONLY trustworthy
@@ -16,7 +16,7 @@ const toolSerializer = new ToolSerializer();
16
16
  export const BRANCH_INPUT: JsonSchema = {
17
17
  type: 'string',
18
18
  minLength: 1,
19
- description: 'The branch (draft) whose workspace this operates on — pass the branch you are currently working on.',
19
+ description: 'The branch to work on: the default branch (`get_agent_guide` names it) or your draft.',
20
20
  };
21
21
 
22
22
  /**
@@ -13,6 +13,8 @@ import { branchHandlingFor, type BranchHandling } from './tool-def.js';
13
13
  import { domainErrorBody } from '../../shared/http-errors.js';
14
14
  import type { ResolveToolContext } from './tool-context.js';
15
15
  import { argumentsRefusal } from './route-argument-check.js';
16
+ import { routeToolName, routeToolSchemasForRequest } from './route-tool-schemas.js';
17
+ import { ConnectionScope, NOT_AVAILABLE_TO_CONNECTION } from '../agent-scope/index.js';
16
18
  import { alwaysWritable, READ_ONLY_CODE, refuseWriteTool, type IWriteAccess } from '../write-access/index.js';
17
19
  import '../tool-auth/index.js'; // Express Request.toolAuth augmentation
18
20
 
@@ -40,6 +42,19 @@ export interface ToolHandlerOptions {
40
42
  * being refused).
41
43
  */
42
44
  branch?: BranchHandling;
45
+ /**
46
+ * The route is ALSO a discovery read of the connection's surface, which
47
+ * both MCP servers make whatever tools the connection is offered:
48
+ * `list_skills` and `get_skill` are how `prompts/list` and `prompts/get`
49
+ * are built, and `list_local_tools` is how the local server learns which
50
+ * connectors it must materialize. A connection's `platformTools` decides
51
+ * which tools its agent is OFFERED — the MCP listing and `tools/call`
52
+ * refuse the rest by name — not what its surface holds, so such a route is
53
+ * not refused for want of a `platformTools` entry. Its answer is still
54
+ * narrowed to the connection's skills or connectors by the handler, and a
55
+ * connection that loads nothing is refused it like any other route.
56
+ */
57
+ discovery?: boolean;
43
58
  }
44
59
 
45
60
  /**
@@ -255,6 +270,23 @@ export function createToolHandlerFactory(
255
270
  ? withoutBranch(args)
256
271
  : args;
257
272
  const ctx = await resolve(auth, abort.signal, sessionId);
273
+ // The connection's scope, before the tool runs, for every caller of a
274
+ // hosted platform tool — MCP, a chain, the local server, a script with
275
+ // a key. A connection made as an agent configuration that does not
276
+ // list this tool is refused it by name: the ONE policy,
277
+ // `ConnectionScope.platformToolRefusal`, which the platform-tool routes
278
+ // this handler does not host (the plugin-creation routes) ask as well.
279
+ const toolName = routeToolSchemasForRequest(req.originalUrl)?.name ?? routeToolName(req.originalUrl);
280
+ const scope =
281
+ ctx.connectionScope ?? (auth.agentPath ? ConnectionScope.gone(auth.agentPath) : ConnectionScope.everything());
282
+ // The handler narrows by the scope decided here, so a context built
283
+ // without one cannot read as Everything inside the tool either.
284
+ ctx.connectionScope = scope;
285
+ const refusal = scope.platformToolRefusal(toolName, { discovery: opts.discovery === true });
286
+ if (refusal) {
287
+ res.status(403).json(refusal);
288
+ return;
289
+ }
258
290
  if (resolved) ctx.branch = resolved.branch;
259
291
  let out = await handler(toolArgs, ctx);
260
292
  // A defaulted call's answer says which branch it ran on, so a caller
@@ -315,3 +347,5 @@ function withoutBranch(args: Record<string, unknown>): Record<string, unknown> {
315
347
  }
316
348
 
317
349
  export type ToolHandlerFactory = ReturnType<typeof createToolHandlerFactory>;
350
+
351
+ export { NOT_AVAILABLE_TO_CONNECTION };
@@ -1,4 +1,5 @@
1
1
  import type { AuthUser, IWorkflowService } from '@bevel-software/platform-shared';
2
+ import type { ConnectionScope } from '../agent-scope/index.js';
2
3
  import type { LocalFilesystem } from '@mastra/core/workspace';
3
4
  import type { WorkspaceService } from '../workspace/index.js';
4
5
  import type { WorkflowEventBus } from '../workflow/index.js';
@@ -58,6 +59,15 @@ export interface ToolContext {
58
59
  * tool that takes no branch.
59
60
  */
60
61
  branch?: string;
62
+ /**
63
+ * What the caller's connection may load (`modules/agent-scope`): resolved
64
+ * once per call from the agent configuration its credential connects as. The
65
+ * tool handler refuses a platform tool outside it before the tool runs; the
66
+ * tools that list skills and connectors narrow by it. Absent is Everything
67
+ * — and a context built without it for a credential that names an agent is
68
+ * refused every tool by the handler, never served Everything.
69
+ */
70
+ connectionScope?: ConnectionScope;
61
71
  abortSignal: AbortSignal;
62
72
  workspaceService: WorkspaceService;
63
73
  workflowService: IWorkflowService;
@@ -1,4 +1,4 @@
1
- import type { IExternalApiKeyService, InternalTokenService } from '../tool-auth/index.js';
1
+ import type { IExternalApiKeyService, InternalTokenService, ConnectionChoices } from '../tool-auth/index.js';
2
2
  import { createTokenVerifier } from '../tool-auth/index.js';
3
3
  import { createToolContextResolver, type ToolContextDeps } from './tool-context.js';
4
4
  import { ToolError, type ToolContext } from './tool.contract.js';
@@ -6,6 +6,8 @@ import { ToolError, type ToolContext } from './tool.contract.js';
6
6
  export interface ToolValidatorDeps extends ToolContextDeps {
7
7
  externalApiKeyService: IExternalApiKeyService;
8
8
  internalTokenService: InternalTokenService;
9
+ /** Where an agent connection's current "Connect as" choice is read (see `createTokenVerifier`). */
10
+ connections?: ConnectionChoices;
9
11
  }
10
12
 
11
13
  /**
@@ -34,7 +36,7 @@ export type ValidateToken = (
34
36
  ) => Promise<ToolContext>;
35
37
 
36
38
  export function createToolValidator(deps: ToolValidatorDeps): ValidateToken {
37
- const verify = createTokenVerifier(deps.externalApiKeyService, deps.internalTokenService, deps.authService);
39
+ const verify = createTokenVerifier(deps.externalApiKeyService, deps.internalTokenService, deps.authService, deps.connections);
38
40
  const resolve = createToolContextResolver(deps);
39
41
  return async (token, signal) => {
40
42
  let result;
@@ -12,6 +12,7 @@ import type { WorkspaceService } from '../../workspace/workspace.service.js';
12
12
  import type { IAccessControl } from '../../access/access-control.interface.js';
13
13
  import type { IToolManualService } from '../tool-manuals.contract.js';
14
14
  import { testKbContext } from '../../../__tests__/kb-context.js';
15
+ import { ConnectionScope, type IAgentScopeResolver } from '../../agent-scope/index.js';
15
16
 
16
17
  /**
17
18
  * `GET /agent/plugins/:folder/archive` — error taxonomy of the plugin-folder
@@ -27,10 +28,20 @@ let httpServer: HttpServer | undefined;
27
28
  let root: string;
28
29
  let wsDir: string;
29
30
 
30
- async function baseUrl(pluginIndex?: { catalog(): Promise<{ name: string; folders: string[] }[]> }): Promise<string> {
31
+ async function baseUrl(
32
+ pluginIndex?: { catalog(): Promise<{ name: string; folders: string[] }[]> },
33
+ /** The connection's `.agent` choice; absent is Everything. */
34
+ connection?: {
35
+ agentPath: string;
36
+ agentScope?: Pick<IAgentScopeResolver, 'resolve'>;
37
+ /** Whether the person may read the plugin's files; default yes. */
38
+ readable?: boolean;
39
+ },
40
+ toolManualService: IToolManualService = {} as unknown as IToolManualService,
41
+ ): Promise<string> {
31
42
  const app = express();
32
43
  const manualAuth: express.RequestHandler = (req, _res, next) => {
33
- req.toolAuth = { userId: 'u-1' } as never;
44
+ req.toolAuth = { userId: 'u-1', ...(connection ? { agentPath: connection.agentPath } : {}) } as never;
34
45
  next();
35
46
  };
36
47
  const workspaceService = {
@@ -39,16 +50,17 @@ async function baseUrl(pluginIndex?: { catalog(): Promise<{ name: string; folder
39
50
  } as unknown as WorkspaceService;
40
51
  const accessControl = {
41
52
  canReadBatch: vi.fn(async (_ws: string, _email: string, rels: string[]) => {
42
- return new Map(rels.map((r) => [r, true]));
53
+ return new Map(rels.map((r) => [r, connection?.readable ?? true]));
43
54
  }),
44
55
  } as unknown as IAccessControl;
45
56
  app.use(
46
57
  '/api',
47
58
  createToolManualsAgentRoutes(
48
- {} as unknown as IToolManualService,
59
+ toolManualService,
49
60
  manualAuth,
50
61
  async () => 'ali@example.com',
51
62
  { workspaceService, accessControl, kb: testKbContext({ kbDirName: KB }), disk: new NodeFs(), pluginIndex: pluginIndex as never },
63
+ connection?.agentScope,
52
64
  ),
53
65
  );
54
66
  httpServer = await new Promise<HttpServer>((resolve) => {
@@ -71,7 +83,53 @@ afterEach(async () => {
71
83
  await fs.rm(root, { recursive: true, force: true });
72
84
  });
73
85
 
86
+ const OPS = { path: 'Agents/ops.agent', name: 'Ops' };
87
+ /** A resolver that narrows every connection to `connectors`. */
88
+ function loading(connectors: string[]): Pick<IAgentScopeResolver, 'resolve'> {
89
+ return { resolve: async () => ConnectionScope.narrowed(OPS, { skills: [], connectors, platformTools: null }, 'fp') };
90
+ }
91
+
74
92
  describe('GET /agent/plugins/:folder/archive', () => {
93
+ it("a connection made as an .agent file archives only a plugin defining a connector the file loads", async () => {
94
+ const pluginDir = path.join(wsDir, KB, 'Plugins', 'GTM');
95
+ await fs.mkdir(pluginDir, { recursive: true });
96
+ await fs.writeFile(path.join(pluginDir, 'mcp.json'), '{"mcpServers":{}}', 'utf-8');
97
+ const archive = async (connectors: string[] | null) => {
98
+ const base = await baseUrl(undefined, {
99
+ agentPath: OPS.path,
100
+ ...(connectors ? { agentScope: loading(connectors) } : {}),
101
+ });
102
+ const res = await fetch(`${base}/api/agent/plugins/GTM/archive`);
103
+ await new Promise<void>((r) => httpServer!.close(() => r()));
104
+ httpServer = undefined;
105
+ return res;
106
+ };
107
+ // The plugin's own definition file, the plugin folder, a folder above it.
108
+ expect((await archive(['Plugins/GTM/mcp.json'])).status).toBe(200);
109
+ expect((await archive(['Plugins/GTM'])).status).toBe(200);
110
+ expect((await archive(['Plugins'])).status).toBe(200);
111
+ // A connector elsewhere: refused by name, before anything is read.
112
+ const refused = await archive(['Plugins/Other']);
113
+ expect(refused.status).toBe(403);
114
+ const body = (await refused.json()) as { error: string; code: string };
115
+ expect(body.code).toBe('not_available_to_connection');
116
+ expect(body.error).toContain('The plugin "GTM" is not available to this connection.');
117
+ // A narrowed connection with no resolver wired loads nothing.
118
+ expect((await archive(null)).status).toBe(403);
119
+ });
120
+
121
+ it('an out-of-scope plugin folder the person cannot read answers the 404 an absent one does', async () => {
122
+ const pluginDir = path.join(wsDir, KB, 'Plugins', 'Private');
123
+ await fs.mkdir(pluginDir, { recursive: true });
124
+ await fs.writeFile(path.join(pluginDir, 'mcp.json'), '{"mcpServers":{}}', 'utf-8');
125
+ const base = await baseUrl(undefined, { agentPath: OPS.path, agentScope: loading(['Plugins/Other']), readable: false });
126
+ const existing = await fetch(`${base}/api/agent/plugins/Private/archive`);
127
+ const absent = await fetch(`${base}/api/agent/plugins/Nowhere/archive`);
128
+ expect(existing.status).toBe(404);
129
+ expect(await existing.json()).toEqual(await absent.json());
130
+ expect(absent.status).toBe(404);
131
+ });
132
+
75
133
  it('zips a readable plugin folder', async () => {
76
134
  const pluginDir = path.join(wsDir, KB, 'Plugins', 'GTM');
77
135
  await fs.mkdir(pluginDir, { recursive: true });
@@ -119,3 +177,21 @@ describe('GET /agent/plugins/:folder/archive', () => {
119
177
  expect(await res.json()).toEqual({ error: 'Failed to archive plugin' });
120
178
  });
121
179
  });
180
+
181
+ describe('GET /tools/:slug/manual', () => {
182
+ it("narrows an inline manual read to the connectors the connection's .agent file loads", async () => {
183
+ const resolveInlineManual = vi.fn(async () => ({ utcp_version: '1.1.0', manual_version: '1.0.0', tools: [] }));
184
+ const service = { resolveInlineManual } as unknown as IToolManualService;
185
+ // Everything asks exactly what it asked before: no narrowing at all.
186
+ let base = await baseUrl(undefined, undefined, service);
187
+ expect((await fetch(`${base}/api/tools/weather/manual`)).status).toBe(200);
188
+ expect(resolveInlineManual).toHaveBeenLastCalledWith('ali@example.com', 'weather', undefined);
189
+ await new Promise<void>((r) => httpServer!.close(() => r()));
190
+
191
+ base = await baseUrl(undefined, { agentPath: OPS.path, agentScope: loading(['Plugins/GTM']) }, service);
192
+ expect((await fetch(`${base}/api/tools/weather/manual`)).status).toBe(200);
193
+ const within = (resolveInlineManual.mock.calls.at(-1) as unknown[])[2] as { within: (p: string) => boolean };
194
+ expect(within.within('Plugins/GTM/weather.tool')).toBe(true);
195
+ expect(within.within('Plugins/Other/weather.tool')).toBe(false);
196
+ });
197
+ });