@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
@@ -1,4 +1,3 @@
1
- import express from 'express';
2
1
  import { describe, expect, it } from 'vitest';
3
2
  import {
4
3
  CALL_TOOL_CHAIN_NAME,
@@ -9,21 +8,9 @@ import {
9
8
  splitCallLine,
10
9
  } from '@bevel-software/platform-mcp-core';
11
10
  import { testKbContext } from '../../../__tests__/kb-context.js';
12
- import { EXTERNAL_KB_MANUAL_NAME } from '../../tool-manuals/tool-manuals.contract.js';
13
- import { ToolRegistry } from '../tool-registry.js';
11
+ import { EXTERNAL_KB_MANUAL_NAME } from '../../tool-manuals/index.js';
14
12
  import type { UtcpTool } from '../tool.contract.js';
15
- import { createToolHandlerFactory } from '../../tool-helpers/tool-handler.js';
16
- import type { ToolAuth } from '../../tool-auth/tool-auth.middleware.js';
17
- import { registerWorkspaceTools } from '../../workspace/workspace.tools.js';
18
- import { WorkerPatternMatcher } from '../../workspace/bounded-matcher.js';
19
- import { registerWorkflowTools } from '../../workflow/agent-tools/workflow.tools.js';
20
- import { registerPluginsTools } from '../../plugins/plugins.tools.js';
21
- import { registerSkillsTools } from '../../skills/skills.tools.js';
22
- import { registerToolManualsTools } from '../../tool-manuals/tool-manuals.tools.js';
23
- import { ToolDescriptionNotes } from '../../workspace/agent-access.gate.js';
24
- import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
25
- import { UuidSessionSink } from '../../workspace/session-sink.js';
26
- import { RoutineWritePolicyService } from '../../workspace/routine-write-policy.js';
13
+ import type { registerSkillsTools } from '../../skills/index.js';
27
14
  import { CLIENT_SHORT_CUT, TOOL_DESCRIPTION_CAP, clientVisibleLength, firstSentenceEnd } from '../description-length.js';
28
15
  import { CAN_WRITE_CLAUSE } from '../../tool-helpers/index.js';
29
16
  import {
@@ -31,9 +18,8 @@ import {
31
18
  sharedFileRules,
32
19
  } from '../../agent-instructions/index.js';
33
20
  import { isPlatformFile, platformFilesByDepth } from '@bevel-software/platform-shared';
34
- import { GET_AGENT_GUIDE_TOOL, GUIDE_FIRST_SENTENCE, guideFirstDescription } from '../guide-first.js';
35
- import { registerAgentGuideTool } from '../../agent-guide/agent-guide.tools.js';
36
- import { agentGuideSections } from '../../agent-guide/agent-guide.js';
21
+ import { GET_AGENT_GUIDE_TOOL, GUIDE_FIRST_SENTENCE } from '../guide-first.js';
22
+ import { emptySkills, hexisTools, servedMetaTools, unused } from '../../../__tests__/hexis-catalog.js';
37
23
 
38
24
  /**
39
25
  * The cap exists because clients cut a long tool description, and they cut it
@@ -43,104 +29,11 @@ import { agentGuideSections } from '../../agent-guide/agent-guide.js';
43
29
  * NAMING the tool: the next paragraph someone appends to a description has to
44
30
  * answer to this test rather than to an agent's truncated catalog.
45
31
  *
46
- * Every registrar Hexis owns is mounted here, on stand-ins, because the
47
- * descriptions are the only thing under test: a stand-in that is never called
48
- * is honest about that. Tools PROXIED from connected MCP servers are not
32
+ * The catalog is every registrar Hexis owns, mounted on stand-ins (see
33
+ * `hexis-catalog.ts`). Tools PROXIED from connected MCP servers are not
49
34
  * measured — their text is the other server's.
50
35
  */
51
36
 
52
- /** Dependencies the registrars take but never touch while they are only building defs. */
53
- const unused = <T,>(): T => ({}) as T;
54
-
55
- /** A `.tool` catalog with nothing in it: the shortest honest answer for a listing. */
56
- const emptyManuals = {
57
- listLocalOnly: async () => [],
58
- listAll: async () => [],
59
- list: async () => [],
60
- listInvalid: async () => [],
61
- } as unknown as Parameters<typeof registerToolManualsTools>[4];
62
-
63
- /** A skill catalog with nothing in it — the per-user skill line is then one fixed sentence. */
64
- const emptySkills = { listSkills: async () => [] } as unknown as Parameters<typeof registerSkillsTools>[4];
65
-
66
- /**
67
- * The meta-tools as the hosted endpoint builds them (`mcp.service.ts`):
68
- * examples written against the namespace it registers the knowledge-base tools
69
- * under and against the catalog it serves, and the chain without the rules it
70
- * states only in the shared places. So the chain description measured here
71
- * carries the worked call a client is really sent, which is its longest form.
72
- */
73
- function servedMetaTools(external: readonly UtcpTool[]) {
74
- return codeModeMetaTools(
75
- EXTERNAL_KB_MANUAL_NAME,
76
- external.map((t) => ({ utcpName: `${EXTERNAL_KB_MANUAL_NAME}.${t.name}`, inputSchema: t.inputs })),
77
- { sharedRulesPointer: '' },
78
- // As the hosted endpoint serves them: opening with the guide-first
79
- // sentence, through the one helper the endpoint itself uses.
80
- ).map((t) => ({ ...t, description: guideFirstDescription(t.description) }));
81
- }
82
-
83
- /** Every tool Hexis itself registers, on both surfaces, deduplicated by name. */
84
- async function hexisTools(skills: Parameters<typeof registerSkillsTools>[4] = emptySkills): Promise<UtcpTool[]> {
85
- const registry = new ToolRegistry();
86
- const router = express.Router();
87
- const toolAuth = ((_req, _res, next) => next()) as unknown as ToolAuth;
88
- const toolHandler = createToolHandlerFactory(unused());
89
- const kb = testKbContext();
90
- const gate = { recoveryBotEmail: 'bot@x', hooks: new WorkflowHooks(), notes: new ToolDescriptionNotes() };
91
-
92
- registerWorkspaceTools(
93
- registry,
94
- router,
95
- toolAuth,
96
- toolHandler,
97
- unused(),
98
- unused(),
99
- unused(),
100
- kb,
101
- gate,
102
- new RoutineWritePolicyService(),
103
- new UuidSessionSink(),
104
- undefined,
105
- undefined,
106
- // The two upload tools are mounted only when a store is supplied, and
107
- // every real composition supplies one: without it they would be the two
108
- // descriptions this suite never measured.
109
- unused(),
110
- // The guide reader, not needed to build defs; then the download store,
111
- // mounted on the same terms as the upload one.
112
- undefined,
113
- unused(),
114
- // Starter packs and the tree walk, not needed; then the grep matcher,
115
- // mounted on the same terms (it spawns no worker until a search runs).
116
- undefined,
117
- undefined,
118
- new WorkerPatternMatcher(),
119
- );
120
- registerWorkflowTools(registry, router, toolAuth, toolHandler, kb, async () => true, { canRead: async () => true, canReadAtRef: async () => true, canReadBatch: async () => new Map(), canReadBatchAtRef: async () => new Map(), canWrite: async () => true } as never, { recoveryBotEmail: 'recovery@x', hooks: { runAgentRead: async () => undefined }, notes: { onChange: () => undefined } } as never);
121
- registerPluginsTools(registry, kb);
122
- registerSkillsTools(registry, router, toolAuth, toolHandler, skills);
123
- registerToolManualsTools(registry, router, toolAuth, toolHandler, emptyManuals, {
124
- accessControl: unused(),
125
- variableStatus: unused(),
126
- kb,
127
- });
128
- // The guide's own tool, with the platform's sections: the one description
129
- // that lists the sections is measured with the list it really carries.
130
- registerAgentGuideTool(registry, router, toolAuth, toolHandler, () => agentGuideSections(kb.layout));
131
-
132
- const byName = new Map<string, UtcpTool>();
133
- // The meta-tools as a client is served them (`mcp.service.ts` opens each
134
- // with the guide-first sentence at the mount), so the catalog measured here
135
- // is the catalog that goes out rather than the bare constant.
136
- const external = (await registry.listExternal()) as UtcpTool[];
137
- const metaTools = servedMetaTools(external);
138
- for (const tool of [...(await registry.listInternal()), ...external, ...metaTools]) {
139
- byName.set(tool.name, tool as UtcpTool);
140
- }
141
- return [...byName.values()];
142
- }
143
-
144
37
  describe('no Hexis tool description is long enough to be cut', () => {
145
38
  it(`keeps every description a client is handed within ${TOOL_DESCRIPTION_CAP} characters`, async () => {
146
39
  const over = (await hexisTools())
@@ -2,6 +2,7 @@ import express, { type Request, type RequestHandler } from 'express';
2
2
  import { UtcpManualSerializer } from '@utcp/sdk';
3
3
  import { declaresWrite, type IToolRegistry, type ToolManualContext, type UtcpTool } from './tool.contract.js';
4
4
  import { requireInternalSource } from '../tool-auth/index.js';
5
+ import { resolveConnectionScope, type IAgentScopeResolver } from '../agent-scope/index.js';
5
6
  import type { IToolReadOnlyHints } from './read-only-hints.contract.js';
6
7
 
7
8
  /** Resolve a connection-key/internal-token user id to its email (for per-caller provider defs). */
@@ -62,6 +63,12 @@ export function createManualRoutes(
62
63
  * Absent, the manual carries the tools' own tags only.
63
64
  */
64
65
  readOnlyHints?: Pick<IToolReadOnlyHints, 'apply'>,
66
+ /**
67
+ * Resolves the scope of a connection made as an agent configuration: the external
68
+ * manual then lists only the platform tools it loads, and the providers word
69
+ * their descriptions for it (`modules/agent-scope`).
70
+ */
71
+ agentScope?: Pick<IAgentScopeResolver, 'resolve'>,
65
72
  ): express.Router {
66
73
  const router = express.Router();
67
74
 
@@ -71,17 +78,31 @@ export function createManualRoutes(
71
78
  async function context(req: Request): Promise<ToolManualContext> {
72
79
  const userId = req.toolAuth?.userId;
73
80
  if (!userId) return {};
74
- if (!resolveUserEmail) return { userId };
81
+ let userEmail: string | undefined;
75
82
  try {
76
- return { userId, userEmail: await resolveUserEmail(userId) };
83
+ userEmail = resolveUserEmail ? await resolveUserEmail(userId) : undefined;
77
84
  } catch {
78
- return { userId };
85
+ userEmail = undefined;
79
86
  }
87
+ // Everything adds nothing to the context, so its providers are asked
88
+ // exactly what they were asked before connections could be narrowed.
89
+ const agentPath = req.toolAuth?.agentPath;
90
+ const connectionScope = agentPath ? await resolveConnectionScope(agentScope, userEmail, agentPath) : undefined;
91
+ return {
92
+ userId,
93
+ ...(userEmail !== undefined ? { userEmail } : {}),
94
+ ...(connectionScope ? { connectionScope } : {}),
95
+ };
80
96
  }
81
97
 
82
98
  router.get('/agent/utcp', manualAuth, async (req, res) => {
83
- const tools = await registry.listExternal(await context(req));
84
- res.json(toManual(readOnlyHints ? readOnlyHints.apply(tools) : tools));
99
+ const ctx = await context(req);
100
+ const tools = await registry.listExternal(ctx);
101
+ // A connection made as an agent configuration is offered only the platform
102
+ // tools that file loads; a call to another is refused at its route.
103
+ const scope = ctx.connectionScope;
104
+ const offered = scope ? tools.filter((t) => scope.allowsPlatformTool(t.name)) : tools;
105
+ res.json(toManual(readOnlyHints ? readOnlyHints.apply(offered) : offered));
85
106
  });
86
107
  router.get('/agent/internal/utcp', manualAuth, requireInternalSource, async (req, res) => {
87
108
  const internal = await registry.listInternal(await context(req));
@@ -1,4 +1,5 @@
1
1
  import type { JsonSchema, Tool as UtcpTool } from '@utcp/sdk';
2
+ import type { ConnectionScope } from '../agent-scope/index.js';
2
3
 
3
4
  export type { JsonSchema, UtcpTool };
4
5
 
@@ -23,6 +24,12 @@ export interface ToolManualContext {
23
24
  userEmail?: string;
24
25
  /** The requesting user's id, when it could be resolved (for per-user gating). */
25
26
  userId?: string;
27
+ /**
28
+ * What the requesting connection may load, when it was made as an agent configuration
29
+ * file (`modules/agent-scope`): a provider that names skills or connectors
30
+ * in its description names only those. Absent is Everything.
31
+ */
32
+ connectionScope?: ConnectionScope;
26
33
  }
27
34
 
28
35
  /**
@@ -250,7 +250,7 @@ function makeReviewWorkflow(): IReviewWorkflowService {
250
250
  describe('WorkflowService — branch delegation', () => {
251
251
  it('listBranches delegates to git.listBranches', async () => {
252
252
  const git = makeGit();
253
- const branches = [{ name: 'main', isCurrent: true, isProtected: true, ahead: 0, behind: 0, hasRemote: true }];
253
+ const branches = [{ name: 'main', isCurrent: true, isProtected: true, hasRemote: true }];
254
254
  (git.listBranches as ReturnType<typeof vi.fn>).mockResolvedValue(branches);
255
255
 
256
256
  const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
@@ -344,7 +344,7 @@ describe('WorkflowService.retireRemoteGoneClone — what can bring the branch ba
344
344
  }),
345
345
  createBranch: vi.fn(async (_ws: string, name: string) => {
346
346
  order.push('create');
347
- return { name, isProtected: false, ahead: 0, behind: 0, hasRemote: true };
347
+ return { name, isProtected: false, hasRemote: true };
348
348
  }),
349
349
  } as unknown as GitService;
350
350
  const workspaceService = {
@@ -104,6 +104,9 @@ const workspaceService = {
104
104
  const workflowService = {
105
105
  listBranches: async (ws: string) => {
106
106
  calls.push(['listBranches', ws]);
107
+ // A real listing fetches first; mark when that fetch has landed.
108
+ await new Promise((r) => setTimeout(r, 0));
109
+ calls.push(['listBranches:fetched', ws]);
107
110
  return [{ name: 'main', isProtected: true }];
108
111
  },
109
112
  commitChange: async (ws: string, user: { id: string }, body: unknown) => {
@@ -117,7 +120,7 @@ const workflowService = {
117
120
  },
118
121
  createBranch: async (ws: string, name: string) => {
119
122
  calls.push(['createBranch', ws, name]);
120
- return { name, isProtected: false, ahead: 0, behind: 0, hasRemote: true };
123
+ return { name, isProtected: false, hasRemote: true };
121
124
  },
122
125
  acquireLock: async (ws: string, branch: string, path: string) => {
123
126
  calls.push(['acquireLock', ws, branch, path]);
@@ -206,6 +209,10 @@ const workflowService = {
206
209
  calls.push(['branchStatus', ws]);
207
210
  return { branch: ws, hasUpstream: true, unmergedFromUpstream: true };
208
211
  },
212
+ branchCounts: async (ws: string) => {
213
+ calls.push(['branchCounts', ws]);
214
+ return { ahead: 3, behind: 1 };
215
+ },
209
216
  listPendingChangePaths: async (ws: string) => {
210
217
  calls.push(['listPendingChangePaths', ws]);
211
218
  return ['knowledge-base/KnowledgeBase/Pending.md'];
@@ -518,6 +525,24 @@ describe('registerWorkflowTools', () => {
518
525
  expect(calls).toContainEqual(['listBranches', 'existing-ws']);
519
526
  });
520
527
 
528
+ it('list_branches declares names, protection and remote presence, and no commit counts', async () => {
529
+ await start();
530
+ for (const tools of [await registryRef!.listInternal(), await registryRef!.listExternal()]) {
531
+ const listBranches = tools.find((t) => t.name === 'list_branches')!;
532
+ const branch = (listBranches.outputs as { properties: { branches: { items: { properties: object; required: string[] } } } })
533
+ .properties.branches.items;
534
+ expect(Object.keys(branch.properties).sort()).toEqual(['hasRemote', 'isProtected', 'name']);
535
+ expect([...branch.required].sort()).toEqual(['hasRemote', 'isProtected', 'name']);
536
+ expect(listBranches.description).toContain('{ name, isProtected, hasRemote }');
537
+ expect(listBranches.description).not.toMatch(/\bahead\b,|\bbehind\b,/);
538
+ // The counts are still `branch_status`'s answer, for its one branch.
539
+ const branchStatus = tools.find((t) => t.name === 'branch_status')!;
540
+ expect((branchStatus.outputs as { required: string[] }).required).toEqual(
541
+ expect.arrayContaining(['ahead', 'behind', 'behindRemote']),
542
+ );
543
+ }
544
+ });
545
+
521
546
  it('open_change_request acts on the SOURCE branch\'s workspace', async () => {
522
547
  const base = await start();
523
548
  const res = await post(`${base}/api/agent/tools/open_change_request`, writeTok(), {
@@ -1008,6 +1033,26 @@ describe('save_file and the repository folder', () => {
1008
1033
  expect(calls.some((c) => c[0] === 'acquireLock')).toBe(false);
1009
1034
  });
1010
1035
 
1036
+ it('refuses a tmp ref in every path input, before any lock — save_file, the history tools and update_branch\'s resolutions alike', async () => {
1037
+ const base = await start();
1038
+ const calls_: Array<[string, Record<string, unknown>]> = [
1039
+ ['save_file', { path: '__tmp__/chat-uploads/plan.xlsx' }],
1040
+ ['read_file_at', { path: '__tmp__/chat-uploads/plan.xlsx', at: 'HEAD' }],
1041
+ ['compare_file', { path: '__tmp__/chat-uploads/plan.xlsx' }],
1042
+ ['list_file_changes', { path: '__tmp__/chat-uploads/plan.xlsx' }],
1043
+ ['update_branch', { resolutions: [{ path: '__tmp__/chat-uploads/plan.xlsx', choose: 'ours' }] }],
1044
+ ];
1045
+ for (const [tool, args] of calls_) {
1046
+ const res = await post(`${base}/api/agent/tools/${tool}`, writeTok(), { ...args, branch: WS });
1047
+ expect(res.status, tool).toBe(400);
1048
+ const body = (await res.json()) as { error: string; kind: string };
1049
+ expect(body.kind, tool).toBe('tmp-ref-read-only');
1050
+ expect(body.error).toContain(`${tool} does not take one there`);
1051
+ expect(body.error).toContain('copy_file');
1052
+ }
1053
+ expect(calls.some((c) => c[0] === 'acquireLock')).toBe(false);
1054
+ });
1055
+
1011
1056
  it('answers a missing path with a 400, not a crash', async () => {
1012
1057
  const base = await start();
1013
1058
  const res = await post(`${base}/api/agent/tools/save_file`, writeTok(), { branch: WS });
@@ -1165,8 +1210,9 @@ describe('history and syncing tools', () => {
1165
1210
  // The listing double names only `main`, so the draft's own entry is unknown.
1166
1211
  isProtected: false,
1167
1212
  hasRemote: true,
1168
- ahead: null,
1169
- behind: null,
1213
+ // Counted for the draft alone, by its own workspace — not read off a listing.
1214
+ ahead: 3,
1215
+ behind: 1,
1170
1216
  behindRemote: true,
1171
1217
  uncommittedPaths: ['KnowledgeBase/Pending.md'],
1172
1218
  forkBase: 'main',
@@ -1175,6 +1221,11 @@ describe('history and syncing tools', () => {
1175
1221
  withheldPaths: 0,
1176
1222
  });
1177
1223
  expect(calls).toContainEqual(['changedPathsBetweenBranches', DRAFT_WS, 'main', DRAFT]);
1224
+ expect(calls).toContainEqual(['branchCounts', DRAFT_WS]);
1225
+ // Counted only once the listing's fetch has refreshed the remote-tracking refs.
1226
+ const fetched = calls.findIndex((c) => c[0] === 'listBranches:fetched' && c[1] === DRAFT_WS);
1227
+ expect(fetched).toBeGreaterThanOrEqual(0);
1228
+ expect(calls.findIndex((c) => c[0] === 'branchCounts')).toBeGreaterThan(fetched);
1178
1229
 
1179
1230
  calls = [];
1180
1231
  const named = await post(tool(base, 'branch_status'), writeTok(), { branch: DRAFT, base: 'release' });
@@ -36,11 +36,9 @@ const branchSchema: JsonSchema = {
36
36
  properties: {
37
37
  name: { type: 'string' },
38
38
  isProtected: { type: 'boolean' },
39
- ahead: { type: ['integer', 'null'], description: 'Commits ahead of upstream / nearest protected base; null if unresolved.' },
40
- behind: { type: ['integer', 'null'], description: 'Commits behind; null if unresolved.' },
41
39
  hasRemote: { type: 'boolean', description: 'True iff `origin/<name>` exists after the last fetch.' },
42
40
  },
43
- required: ['name', 'isProtected', 'ahead', 'behind', 'hasRemote'],
41
+ required: ['name', 'isProtected', 'hasRemote'],
44
42
  };
45
43
 
46
44
  const commitSchema: JsonSchema = {
@@ -239,7 +237,9 @@ export function registerWorkflowTools(
239
237
  // `getFilesystem` — so the branch-less call the tool handler refuses
240
238
  // before this runs would otherwise commit to, or fork from, a
241
239
  // workspace literally named "undefined".
242
- (args, ctx) => spec.handler(normalizePathArgs(args, kbDirName), ctx),
240
+ // The normaliser also refuses a tmp ref (`__tmp__/…`) in every path
241
+ // input: none of these tools takes one (see `kb-fs/tmp-ref.ts`).
242
+ (args, ctx) => spec.handler(normalizePathArgs(args, kbDirName, { tool: spec.name }), ctx),
243
243
  { write: spec.write },
244
244
  ),
245
245
  );
@@ -258,7 +258,8 @@ export function registerWorkflowTools(
258
258
  name: 'list_branches',
259
259
  description:
260
260
  'List every draft known to the repository (protected versions + unprotected drafts, ' +
261
- 'local and on the shared remote). Returns `{ branches: [{ name, isProtected, ahead, behind, hasRemote }] }`. ' +
261
+ 'local and on the shared remote). Returns `{ branches: [{ name, isProtected, hasRemote }] }`; ' +
262
+ 'how far one branch is ahead or behind is `branch_status`\'s answer. ' +
262
263
  'Takes no arguments — branch listing is repo-global, not scoped to any one draft.',
263
264
  // Repo-global: the branch set is the same from any clone, so don't require
264
265
  // (and risk cloning) a model-named branch — resolve any existing workspace.
@@ -278,9 +279,10 @@ export function registerWorkflowTools(
278
279
  mount({
279
280
  name: 'commit_change',
280
281
  description:
281
- 'Save the currently-pending file edits as a new change on the current branch. Each change ' +
282
- 'must affect exactly one file — if multiple files are dirty, returns a structured error ' +
283
- 'listing them; commit them one at a time. Refused on protected branches without write permission.',
282
+ 'Commit, as you, the one file left uncommitted on `branch`, without sharing it. Writes commit and share ' +
283
+ 'on their own moments later (`branch_status` lists those still landing); `unzip` leaves its files uncommitted. ' +
284
+ 'If several files are uncommitted, returns a structured error listing them; commit them one at a time. ' +
285
+ 'Refused on protected branches without write permission.',
284
286
  inputs: {
285
287
  type: 'object',
286
288
  properties: {
@@ -308,7 +310,7 @@ export function registerWorkflowTools(
308
310
  name: 'save_file',
309
311
  description:
310
312
  'Schedule the file at <path> for commit + push using whatever bytes are on disk (no content ' +
311
- 'rewrite) — for binary uploads or files left uncommitted. On lock contention returns ' +
313
+ 'rewrite) — for files left uncommitted, such as those `unzip` extracts. On lock contention returns ' +
312
314
  '`{ saved: false, reason }` rather than throwing. The commit lands asynchronously.',
313
315
  inputs: {
314
316
  type: 'object',
@@ -356,8 +358,9 @@ export function registerWorkflowTools(
356
358
  mount({
357
359
  name: 'share_current_branch',
358
360
  description:
359
- 'Publish the current branch to the shared remote so teammates and any change request pick up ' +
360
- 'your commits. No arguments. Refused on protected branches without write permission.',
361
+ 'Publish `branch` to the shared remote so teammates and any change request pick up its commits. ' +
362
+ 'Writes already share on their own: this is for sharing again after a refused push (`branch_status` shows ' +
363
+ 'the branch ahead). Refused on protected branches without write permission.',
361
364
  inputs: { type: 'object', properties: {}, additionalProperties: false },
362
365
  outputs: {
363
366
  type: 'object',
@@ -376,10 +379,11 @@ export function registerWorkflowTools(
376
379
  description:
377
380
  'Create a new unprotected draft named `name`, forked from the existing branch `branch`. The ' +
378
381
  `backend rejects protected names (${protectedInline(kb)}) and filesystem-invalid names — surface ` +
379
- 'those errors verbatim. Convention: `<email-localpart>/<kebab-slug>`. Does NOT switch the ' +
380
- 'agent onto the new draft.',
382
+ 'those errors verbatim. Name it `<you>/<kebab-slug>`: `<you>` is the person\'s email before the @, in lower case, ' +
383
+ 'with each run of characters other than letters and digits as one `-` (`paul.brandt@` gives `paul-brandt/`). ' +
384
+ 'Only that prefix makes the draft theirs, to delete later. Does NOT switch the agent onto the new draft.',
381
385
  // `branch` here is the fork BASE — its own meaning — so skip the generic
382
- // workspace-`branch` injection ("the branch you are currently working on"),
386
+ // workspace-`branch` injection ("the branch to work on: ... or your draft"),
383
387
  // whose wording invites filling in the draft being created instead.
384
388
  skipBranch: true,
385
389
  // The handler refuses a missing `name` with a message that says what the
@@ -388,7 +392,7 @@ export function registerWorkflowTools(
388
392
  inputs: {
389
393
  type: 'object',
390
394
  properties: {
391
- name: { type: 'string', minLength: 1, description: 'Name of the draft to create (`<email-localpart>/<kebab-slug>` for user drafts). Must not exist yet.' },
395
+ name: { type: 'string', minLength: 1, description: 'Name of the draft to create (`<you>/<kebab-slug>` for user drafts, as the description says). Must not exist yet.' },
392
396
  branch: { type: 'string', minLength: 1, description: 'Existing branch to fork the new draft from — usually the branch you are currently on.' },
393
397
  },
394
398
  required: ['name', 'branch'],
@@ -436,7 +440,7 @@ export function registerWorkflowTools(
436
440
  description:
437
441
  'Open a change request from a draft branch into a target branch. Auto-merges the latest target ' +
438
442
  'into the source first, pushes, then creates the CR. On conflicts returns a ' +
439
- '`change-request-conflicts` error with affected paths. The author marker is injected server-side. ' +
443
+ '`change-request-conflicts` error with affected paths. ' +
440
444
  'Answers a SUMMARY, not the request\'s content: `url` first (hand it to the user), then `number`, ' +
441
445
  '`title`, `state`, `sourceBranch`, `targetBranch`, `approvals` (who must approve each file), ' +
442
446
  '`mergeBlockedReasons` (what blocks the merge), and `files` — the changed paths with their kind of ' +
@@ -548,12 +552,13 @@ export function registerWorkflowTools(
548
552
  name: 'merge_branch',
549
553
  description:
550
554
  'Merge branch `source` into branch `target` as you, and publish `target`. An agent proposes and syncs; ' +
551
- 'a person merges: this tool never lands a change request. It refuses while a change request from `source` ' +
555
+ 'a person merges: this never lands a change request. It refuses while a change request from `source` ' +
552
556
  'into `target` is open (naming it): ask the user to review it in the app. It refuses ' +
553
- 'when `target` is a protected branch unless you could commit every changed file directly to it. ' +
557
+ 'when `target` is a protected branch unless you could commit every changed file directly to it (never ' +
558
+ 'for a change to `roles.yaml`). ' +
554
559
  'SYNC: merging the target into your draft (`source` = the change request\'s target, `target` = your draft) ' +
555
560
  'is always allowed, even with the draft\'s request open. ' +
556
- 'Writes are committed asynchronously; the merge first waits up to 20s for those on `source`. ' +
561
+ 'Writes are committed asynchronously; it waits up to 20s for those on `source`. ' +
557
562
  'Returns `merged` with the merge commit; `nothing-to-merge` with `target`\'s tip when it already holds ' +
558
563
  'all of `source`; `pending-commits` (nothing merged) when writes are still committing — retry shortly — ' +
559
564
  'or one failed (`needsAttention`: tell the user); or `conflicts-need-resolution` with the conflicting ' +
@@ -617,7 +622,7 @@ export function registerWorkflowTools(
617
622
  name: 'delete_branch',
618
623
  description:
619
624
  'Delete branch `name` from the shared repository and the server. Allowed for the ' +
620
- 'branch\'s author (`<email-localpart>/…`, or your own `suggestions/…` bundle) or an Admin. Refuses a ' +
625
+ 'branch\'s author (`<you>/…` per `create_branch`, or your own `suggestions/…` bundle) or an Admin. Refuses a ' +
621
626
  'protected branch, a name that is not a branch, a branch with saves still landing or a file held ' +
622
627
  '(retry once they land). An open change request from or into it that proposes nothing is closed and the ' +
623
628
  'delete goes ahead; one that still proposes something refuses it, naming and linking it: its author ' +
@@ -835,13 +840,13 @@ export function registerWorkflowTools(
835
840
  'One file as it was at a point in history: `at` is a commit (from `list_file_changes`, on `branch`\'s ' +
836
841
  'own history) or the name of another branch (its published tip). Answers `content` (null when the ' +
837
842
  'file was not there) and `sha`, the commit it was read at; for a commit, also `before`, the file ' +
838
- 'just before that commit. To put an earlier version back, write it with `write_file`. Takes the read ' +
839
- 'the file takes at that point.',
843
+ 'just before that commit. To put an earlier version back, write it with `write_file`. Takes your ' +
844
+ 'read of the file on `branch` now and, for a branch, also at its tip.',
840
845
  inputs: {
841
846
  type: 'object',
842
847
  properties: {
843
848
  path: { type: 'string', minLength: 1, description: 'The file, workspace-relative.' },
844
- at: { type: 'string', minLength: 1, description: 'A commit sha, or a branch name.' },
849
+ at: { type: 'string', minLength: 1, description: 'A full commit sha (40 or 64 hex characters), or a branch name.' },
845
850
  sessionId: SESSION_ID_INPUT,
846
851
  },
847
852
  required: ['path', 'at'],
@@ -978,9 +983,13 @@ export function registerWorkflowTools(
978
983
  // and a save or sync landing between two of them is tolerated — the
979
984
  // next call reports it. (The one answer that must be exact, what a
980
985
  // merge is of, is taken under one reservation by `update_branch`.)
981
- const [status, branches, pending, forkBase] = await Promise.all([
986
+ // The counts alone wait for the listing: its fetch refreshes the
987
+ // remote-tracking refs they are measured against.
988
+ const [status, [branches, counts], pending, forkBase] = await Promise.all([
982
989
  ctx.workflowService.branchStatus(workspaceId),
983
- ctx.workflowService.listBranches(workspaceId),
990
+ ctx.workflowService
991
+ .listBranches(workspaceId)
992
+ .then(async (listed) => [listed, await ctx.workflowService.branchCounts(workspaceId)] as const),
984
993
  ctx.workflowService.listPendingChangePaths(workspaceId),
985
994
  ctx.workflowService.resolveForkBase(workspaceId, branch),
986
995
  ]);
@@ -1000,8 +1009,8 @@ export function registerWorkflowTools(
1000
1009
  branch,
1001
1010
  isProtected: info?.isProtected ?? kb.protectedBranches.has(branch),
1002
1011
  hasRemote: info?.hasRemote ?? status.hasUpstream,
1003
- ahead: info?.ahead ?? null,
1004
- behind: info?.behind ?? null,
1012
+ ahead: counts.ahead,
1013
+ behind: counts.behind,
1005
1014
  behindRemote: status.unmergedFromUpstream,
1006
1015
  uncommittedPaths,
1007
1016
  forkBase,