@bevel-software/platform-core-backend 0.34.0 → 0.36.1

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 (908) hide show
  1. package/agent-guide/access-control.md +146 -300
  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 +16 -11
  9. package/agent-guide/new-knowledge-base.md +9 -8
  10. package/agent-guide/onboarding.md +111 -0
  11. package/agent-guide/skills.md +67 -42
  12. package/agent-guide/start-here.md +66 -0
  13. package/agent-guide/tool-manuals.md +133 -154
  14. package/agent-guide/tools.md +67 -0
  15. package/agent-guide/where-a-new-file-goes.md +45 -28
  16. package/dist/core/catalog-cache-invalidation.d.ts +2 -2
  17. package/dist/core/catalog-cache-invalidation.d.ts.map +1 -1
  18. package/dist/core/compose-embed.d.ts +2 -2
  19. package/dist/core/compose-embed.d.ts.map +1 -1
  20. package/dist/core/compose-embed.js +1 -1
  21. package/dist/core/compose-embed.js.map +1 -1
  22. package/dist/core/core-ports.d.ts +19 -4
  23. package/dist/core/core-ports.d.ts.map +1 -1
  24. package/dist/core/core-ports.js.map +1 -1
  25. package/dist/core/create-core-server.d.ts.map +1 -1
  26. package/dist/core/create-core-server.js +27 -25
  27. package/dist/core/create-core-server.js.map +1 -1
  28. package/dist/core/create-core-services.d.ts +25 -13
  29. package/dist/core/create-core-services.d.ts.map +1 -1
  30. package/dist/core/create-core-services.js +75 -60
  31. package/dist/core/create-core-services.js.map +1 -1
  32. package/dist/core/lifecycle.d.ts +4 -4
  33. package/dist/core/lifecycle.d.ts.map +1 -1
  34. package/dist/core/lifecycle.js +5 -5
  35. package/dist/core/lifecycle.js.map +1 -1
  36. package/dist/core-config.d.ts +2 -2
  37. package/dist/core-config.js +3 -3
  38. package/dist/core-config.js.map +1 -1
  39. package/dist/index.d.ts +4 -4
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +3 -3
  42. package/dist/index.js.map +1 -1
  43. package/dist/modules/access/access-control.interface.d.ts +22 -0
  44. package/dist/modules/access/access-control.interface.d.ts.map +1 -1
  45. package/dist/modules/access/access-control.service.d.ts +3 -1
  46. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  47. package/dist/modules/access/access-control.service.js +76 -1
  48. package/dist/modules/access/access-control.service.js.map +1 -1
  49. package/dist/modules/access/access-declarations.d.ts +2 -2
  50. package/dist/modules/access/access-declarations.d.ts.map +1 -1
  51. package/dist/modules/access/access-declarations.js +2 -2
  52. package/dist/modules/access/access-declarations.js.map +1 -1
  53. package/dist/modules/access/access-mutation.service.d.ts +2 -2
  54. package/dist/modules/access/access-mutation.service.d.ts.map +1 -1
  55. package/dist/modules/access/access-mutation.service.js +2 -2
  56. package/dist/modules/access/access-mutation.service.js.map +1 -1
  57. package/dist/modules/access/access-requests.routes.d.ts +2 -2
  58. package/dist/modules/access/access-requests.routes.d.ts.map +1 -1
  59. package/dist/modules/access/access-requests.routes.js +5 -5
  60. package/dist/modules/access/access-requests.routes.js.map +1 -1
  61. package/dist/modules/access/access-requests.service.d.ts +2 -2
  62. package/dist/modules/access/access-requests.service.d.ts.map +1 -1
  63. package/dist/modules/access/access-requests.service.js +11 -11
  64. package/dist/modules/access/access-requests.service.js.map +1 -1
  65. package/dist/modules/access/access.routes.d.ts +2 -2
  66. package/dist/modules/access/access.routes.d.ts.map +1 -1
  67. package/dist/modules/access/access.routes.js +32 -13
  68. package/dist/modules/access/access.routes.js.map +1 -1
  69. package/dist/modules/access/admin-locked-commit.d.ts +5 -5
  70. package/dist/modules/access/admin-locked-commit.d.ts.map +1 -1
  71. package/dist/modules/access/admin-locked-commit.js +7 -7
  72. package/dist/modules/access/admin-locked-commit.js.map +1 -1
  73. package/dist/modules/access/admin-route-helpers.d.ts +1 -1
  74. package/dist/modules/access/admin-route-helpers.js +5 -5
  75. package/dist/modules/access/admin-route-helpers.js.map +1 -1
  76. package/dist/modules/access/change-read-gate.d.ts +1 -1
  77. package/dist/modules/access/change-read-gate.js +1 -1
  78. package/dist/modules/access/groups-admin.service.d.ts +7 -7
  79. package/dist/modules/access/groups-admin.service.d.ts.map +1 -1
  80. package/dist/modules/access/groups-admin.service.js +6 -6
  81. package/dist/modules/access/groups-admin.service.js.map +1 -1
  82. package/dist/modules/access/index.d.ts +1 -1
  83. package/dist/modules/access/index.d.ts.map +1 -1
  84. package/dist/modules/access/reference-scan.d.ts +1 -1
  85. package/dist/modules/access/roles-admin.service.d.ts +7 -7
  86. package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
  87. package/dist/modules/access/roles-admin.service.js +8 -8
  88. package/dist/modules/access/roles-admin.service.js.map +1 -1
  89. package/dist/modules/access/synced-groups-committer.d.ts +4 -4
  90. package/dist/modules/access/synced-groups-committer.d.ts.map +1 -1
  91. package/dist/modules/access/synced-groups-committer.js +7 -7
  92. package/dist/modules/access/synced-groups-committer.js.map +1 -1
  93. package/dist/modules/access/user-access-removal.service.d.ts +6 -6
  94. package/dist/modules/access/user-access-removal.service.d.ts.map +1 -1
  95. package/dist/modules/access/user-access-removal.service.js +4 -4
  96. package/dist/modules/access/user-access-removal.service.js.map +1 -1
  97. package/dist/modules/access-model/access-errors.d.ts +4 -4
  98. package/dist/modules/access-model/access-errors.d.ts.map +1 -1
  99. package/dist/modules/access-model/access-errors.js +4 -4
  100. package/dist/modules/access-model/access-errors.js.map +1 -1
  101. package/dist/modules/access-model/access-grammar.d.ts +1 -1
  102. package/dist/modules/access-model/access-grammar.js +4 -4
  103. package/dist/modules/access-model/change-gate.d.ts +1 -1
  104. package/dist/modules/access-model/change-gate.js +1 -1
  105. package/dist/modules/access-model/roles-yaml-guard.d.ts +4 -4
  106. package/dist/modules/access-model/roles-yaml-guard.d.ts.map +1 -1
  107. package/dist/modules/access-model/roles-yaml-guard.js +4 -4
  108. package/dist/modules/access-model/roles-yaml-guard.js.map +1 -1
  109. package/dist/modules/agent-guide/agent-guide.d.ts +63 -18
  110. package/dist/modules/agent-guide/agent-guide.d.ts.map +1 -1
  111. package/dist/modules/agent-guide/agent-guide.js +144 -30
  112. package/dist/modules/agent-guide/agent-guide.js.map +1 -1
  113. package/dist/modules/agent-guide/agent-guide.tools.d.ts +6 -2
  114. package/dist/modules/agent-guide/agent-guide.tools.d.ts.map +1 -1
  115. package/dist/modules/agent-guide/agent-guide.tools.js +45 -31
  116. package/dist/modules/agent-guide/agent-guide.tools.js.map +1 -1
  117. package/dist/modules/agent-guide/guide-budget.d.ts +51 -0
  118. package/dist/modules/agent-guide/guide-budget.d.ts.map +1 -0
  119. package/dist/modules/agent-guide/guide-budget.js +71 -0
  120. package/dist/modules/agent-guide/guide-budget.js.map +1 -0
  121. package/dist/modules/agent-guide/index.d.ts +2 -1
  122. package/dist/modules/agent-guide/index.d.ts.map +1 -1
  123. package/dist/modules/agent-guide/index.js +2 -1
  124. package/dist/modules/agent-guide/index.js.map +1 -1
  125. package/dist/modules/agent-instructions/agent-instructions.routes.d.ts +12 -5
  126. package/dist/modules/agent-instructions/agent-instructions.routes.d.ts.map +1 -1
  127. package/dist/modules/agent-instructions/agent-instructions.routes.js +13 -6
  128. package/dist/modules/agent-instructions/agent-instructions.routes.js.map +1 -1
  129. package/dist/modules/agent-instructions/compose.d.ts +15 -8
  130. package/dist/modules/agent-instructions/compose.d.ts.map +1 -1
  131. package/dist/modules/agent-instructions/compose.js +28 -10
  132. package/dist/modules/agent-instructions/compose.js.map +1 -1
  133. package/dist/modules/agent-instructions/shared-file-rules.d.ts +14 -6
  134. package/dist/modules/agent-instructions/shared-file-rules.d.ts.map +1 -1
  135. package/dist/modules/agent-instructions/shared-file-rules.js +60 -18
  136. package/dist/modules/agent-instructions/shared-file-rules.js.map +1 -1
  137. package/dist/modules/auth/account-erasure.service.d.ts +36 -7
  138. package/dist/modules/auth/account-erasure.service.d.ts.map +1 -1
  139. package/dist/modules/auth/account-erasure.service.js +30 -10
  140. package/dist/modules/auth/account-erasure.service.js.map +1 -1
  141. package/dist/modules/auth/account-hooks.d.ts +20 -0
  142. package/dist/modules/auth/account-hooks.d.ts.map +1 -1
  143. package/dist/modules/auth/account-hooks.js +10 -0
  144. package/dist/modules/auth/account-hooks.js.map +1 -1
  145. package/dist/modules/auth/account-switch-lock.js +2 -2
  146. package/dist/modules/auth/account-switch-lock.js.map +1 -1
  147. package/dist/modules/auth/account.routes.d.ts +7 -2
  148. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  149. package/dist/modules/auth/account.routes.js +23 -4
  150. package/dist/modules/auth/account.routes.js.map +1 -1
  151. package/dist/modules/auth/auth.service.d.ts +1 -1
  152. package/dist/modules/auth/auth.service.js +4 -4
  153. package/dist/modules/auth/auth.service.js.map +1 -1
  154. package/dist/modules/auth/index.d.ts +1 -0
  155. package/dist/modules/auth/index.d.ts.map +1 -1
  156. package/dist/modules/code-mode/code-mode.tool.js +2 -2
  157. package/dist/modules/code-mode/code-mode.tool.js.map +1 -1
  158. package/dist/modules/connection-probe/connection-probe.service.d.ts +0 -12
  159. package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
  160. package/dist/modules/connection-probe/connection-probe.service.js +1 -38
  161. package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
  162. package/dist/modules/database/core-schema.js +2 -2
  163. package/dist/modules/database/core-schema.js.map +1 -1
  164. package/dist/modules/diff/diff.routes.d.ts +3 -3
  165. package/dist/modules/diff/diff.routes.d.ts.map +1 -1
  166. package/dist/modules/diff/diff.routes.js +7 -7
  167. package/dist/modules/diff/diff.routes.js.map +1 -1
  168. package/dist/modules/embed/embed.routes.js +1 -1
  169. package/dist/modules/embed/embed.routes.js.map +1 -1
  170. package/dist/modules/embed/embed.service.d.ts +4 -4
  171. package/dist/modules/embed/embed.service.d.ts.map +1 -1
  172. package/dist/modules/embed/embed.service.js +18 -18
  173. package/dist/modules/embed/embed.service.js.map +1 -1
  174. package/dist/modules/kb-fs/branch-name.js +8 -8
  175. package/dist/modules/kb-fs/branch-name.js.map +1 -1
  176. package/dist/modules/kb-fs/file-change-notifier.d.ts +2 -2
  177. package/dist/modules/kb-fs/locking-filesystem.d.ts +9 -9
  178. package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
  179. package/dist/modules/kb-fs/locking-filesystem.js +27 -27
  180. package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
  181. package/dist/modules/kb-fs/repo-path.js +5 -5
  182. package/dist/modules/kb-fs/repo-path.js.map +1 -1
  183. package/dist/modules/kb-fs/tmp-ref.d.ts +2 -2
  184. package/dist/modules/kb-fs/tmp-ref.d.ts.map +1 -1
  185. package/dist/modules/kb-fs/tmp-ref.js +2 -2
  186. package/dist/modules/kb-fs/tmp-ref.js.map +1 -1
  187. package/dist/modules/kb-sync/index.d.ts +1 -1
  188. package/dist/modules/kb-sync/index.d.ts.map +1 -1
  189. package/dist/modules/kb-sync/kb-sync.interface.d.ts +3 -3
  190. package/dist/modules/kb-sync/kb-sync.interface.d.ts.map +1 -1
  191. package/dist/modules/kb-sync/kb-sync.service.d.ts +3 -3
  192. package/dist/modules/kb-sync/kb-sync.service.d.ts.map +1 -1
  193. package/dist/modules/kb-sync/kb-sync.service.js +10 -10
  194. package/dist/modules/kb-sync/kb-sync.service.js.map +1 -1
  195. package/dist/modules/mcp/mcp.service.d.ts +11 -4
  196. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  197. package/dist/modules/mcp/mcp.service.js +80 -53
  198. package/dist/modules/mcp/mcp.service.js.map +1 -1
  199. package/dist/modules/onboarding/onboarding.contract.d.ts +1 -1
  200. package/dist/modules/onboarding/onboarding.routes.js +2 -2
  201. package/dist/modules/onboarding/onboarding.routes.js.map +1 -1
  202. package/dist/modules/onboarding/starter-pack.service.d.ts +4 -4
  203. package/dist/modules/onboarding/starter-pack.service.d.ts.map +1 -1
  204. package/dist/modules/onboarding/starter-pack.service.js +4 -4
  205. package/dist/modules/onboarding/starter-pack.service.js.map +1 -1
  206. package/dist/modules/plugins/join-request-jobs.service.d.ts +2 -2
  207. package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -1
  208. package/dist/modules/plugins/join-request-jobs.service.js +7 -7
  209. package/dist/modules/plugins/join-request-jobs.service.js.map +1 -1
  210. package/dist/modules/plugins/join-requests.service.d.ts +3 -3
  211. package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
  212. package/dist/modules/plugins/join-requests.service.js +5 -5
  213. package/dist/modules/plugins/join-requests.service.js.map +1 -1
  214. package/dist/modules/plugins/plugin-rename.service.js +1 -1
  215. package/dist/modules/plugins/plugin-rename.service.js.map +1 -1
  216. package/dist/modules/plugins/plugins.routes.d.ts +2 -2
  217. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  218. package/dist/modules/plugins/plugins.routes.js +8 -8
  219. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  220. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts +87 -2
  221. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts.map +1 -1
  222. package/dist/modules/secrets-vault/db-secrets-vault.service.js +635 -74
  223. package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -1
  224. package/dist/modules/secrets-vault/index.d.ts +3 -2
  225. package/dist/modules/secrets-vault/index.d.ts.map +1 -1
  226. package/dist/modules/secrets-vault/index.js +2 -1
  227. package/dist/modules/secrets-vault/index.js.map +1 -1
  228. package/dist/modules/secrets-vault/managed-sign-in-erasure.d.ts +36 -0
  229. package/dist/modules/secrets-vault/managed-sign-in-erasure.d.ts.map +1 -0
  230. package/dist/modules/secrets-vault/managed-sign-in-erasure.js +37 -0
  231. package/dist/modules/secrets-vault/managed-sign-in-erasure.js.map +1 -0
  232. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts +205 -11
  233. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts.map +1 -1
  234. package/dist/modules/secrets-vault/secrets-vault.contract.js +27 -0
  235. package/dist/modules/secrets-vault/secrets-vault.contract.js.map +1 -1
  236. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +7 -1
  237. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  238. package/dist/modules/secrets-vault/secrets-vault.routes.js +206 -45
  239. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  240. package/dist/modules/settings/connection-check.js +1 -1
  241. package/dist/modules/settings/connection-check.js.map +1 -1
  242. package/dist/modules/settings/deployment-settings.service.js +1 -1
  243. package/dist/modules/settings/git-root-folders.js +1 -1
  244. package/dist/modules/settings/git-root-folders.js.map +1 -1
  245. package/dist/modules/settings/oidc-check.d.ts.map +1 -1
  246. package/dist/modules/settings/oidc-check.js +5 -17
  247. package/dist/modules/settings/oidc-check.js.map +1 -1
  248. package/dist/modules/settings/setup.routes.d.ts +1 -1
  249. package/dist/modules/settings/setup.routes.js +1 -1
  250. package/dist/modules/skills/pending-skills.service.d.ts +3 -3
  251. package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
  252. package/dist/modules/skills/pending-skills.service.js +4 -4
  253. package/dist/modules/skills/pending-skills.service.js.map +1 -1
  254. package/dist/modules/skills/skill-access-requests.routes.d.ts +2 -2
  255. package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
  256. package/dist/modules/skills/skill-access-requests.routes.js +5 -5
  257. package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
  258. package/dist/modules/skills/skills.tools.js +1 -1
  259. package/dist/modules/skills/skills.tools.js.map +1 -1
  260. package/dist/modules/tool-helpers/tool-context.d.ts +4 -4
  261. package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
  262. package/dist/modules/tool-helpers/tool-context.js +2 -2
  263. package/dist/modules/tool-helpers/tool-context.js.map +1 -1
  264. package/dist/modules/tool-helpers/tool-def.js +1 -1
  265. package/dist/modules/tool-helpers/tool-def.js.map +1 -1
  266. package/dist/modules/tool-helpers/tool-handler.js +2 -2
  267. package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
  268. package/dist/modules/tool-helpers/tool.contract.d.ts +4 -4
  269. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
  270. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +7 -1
  271. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
  272. package/dist/modules/tool-manuals/mcp-json-discovery.js +69 -38
  273. package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
  274. package/dist/modules/tool-manuals/mcp-server-edit.service.js +1 -1
  275. package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -1
  276. package/dist/modules/tool-manuals/pending-tools.service.d.ts +3 -3
  277. package/dist/modules/tool-manuals/pending-tools.service.d.ts.map +1 -1
  278. package/dist/modules/tool-manuals/pending-tools.service.js +4 -4
  279. package/dist/modules/tool-manuals/pending-tools.service.js.map +1 -1
  280. package/dist/modules/tool-manuals/tool-delete.service.js +1 -1
  281. package/dist/modules/tool-manuals/tool-delete.service.js.map +1 -1
  282. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +70 -3
  283. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
  284. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +18 -8
  285. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  286. package/dist/modules/tool-manuals/tool-manuals.service.js +166 -49
  287. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  288. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +11 -2
  289. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  290. package/dist/modules/tool-manuals/tool-manuals.tools.js +66 -24
  291. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  292. package/dist/modules/version-control/agent-tools/change-request-read-shape.d.ts.map +1 -0
  293. package/dist/modules/version-control/agent-tools/change-request-read-shape.js.map +1 -0
  294. package/dist/modules/version-control/agent-tools/change-request-read.tools.d.ts.map +1 -0
  295. package/dist/modules/{workflow → version-control}/agent-tools/change-request-read.tools.js +2 -2
  296. package/dist/modules/version-control/agent-tools/change-request-read.tools.js.map +1 -0
  297. package/dist/modules/version-control/agent-tools/change-request-summary.d.ts.map +1 -0
  298. package/dist/modules/version-control/agent-tools/change-request-summary.js.map +1 -0
  299. package/dist/modules/{workflow/agent-tools/workflow.tools.d.ts → version-control/agent-tools/version-control.tools.d.ts} +4 -4
  300. package/dist/modules/version-control/agent-tools/version-control.tools.d.ts.map +1 -0
  301. package/dist/modules/{workflow/agent-tools/workflow.tools.js → version-control/agent-tools/version-control.tools.js} +53 -49
  302. package/dist/modules/version-control/agent-tools/version-control.tools.js.map +1 -0
  303. package/dist/modules/{workflow → version-control}/change-request-hooks.d.ts +1 -1
  304. package/dist/modules/version-control/change-request-hooks.d.ts.map +1 -0
  305. package/dist/modules/version-control/change-request-hooks.js.map +1 -0
  306. package/dist/modules/version-control/change-request-review/approval-lock.d.ts.map +1 -0
  307. package/dist/modules/version-control/change-request-review/approval-lock.js.map +1 -0
  308. package/dist/modules/{workflow/review-workflow/review-workflow.interface.d.ts → version-control/change-request-review/change-request-review.interface.d.ts} +2 -2
  309. package/dist/modules/version-control/change-request-review/change-request-review.interface.d.ts.map +1 -0
  310. package/dist/modules/version-control/change-request-review/change-request-review.interface.js +2 -0
  311. package/dist/modules/version-control/change-request-review/change-request-review.interface.js.map +1 -0
  312. package/dist/modules/{workflow/review-workflow/review-workflow.service.d.ts → version-control/change-request-review/change-request-review.service.d.ts} +3 -3
  313. package/dist/modules/version-control/change-request-review/change-request-review.service.d.ts.map +1 -0
  314. package/dist/modules/{workflow/review-workflow/review-workflow.service.js → version-control/change-request-review/change-request-review.service.js} +26 -26
  315. package/dist/modules/version-control/change-request-review/change-request-review.service.js.map +1 -0
  316. package/dist/modules/{workflow → version-control}/event-bus.d.ts +8 -8
  317. package/dist/modules/version-control/event-bus.d.ts.map +1 -0
  318. package/dist/modules/{workflow → version-control}/event-bus.js +4 -4
  319. package/dist/modules/version-control/event-bus.js.map +1 -0
  320. package/dist/modules/{workflow → version-control}/events-delivery.d.ts +4 -4
  321. package/dist/modules/version-control/events-delivery.d.ts.map +1 -0
  322. package/dist/modules/version-control/events-delivery.js.map +1 -0
  323. package/dist/modules/{workflow → version-control}/events.routes.d.ts +4 -4
  324. package/dist/modules/version-control/events.routes.d.ts.map +1 -0
  325. package/dist/modules/version-control/events.routes.js.map +1 -0
  326. package/dist/modules/{workflow → version-control}/file-lock.service.d.ts +2 -2
  327. package/dist/modules/version-control/file-lock.service.d.ts.map +1 -0
  328. package/dist/modules/{workflow → version-control}/file-lock.service.js +6 -6
  329. package/dist/modules/version-control/file-lock.service.js.map +1 -0
  330. package/dist/modules/version-control/git/change-request-link.d.ts.map +1 -0
  331. package/dist/modules/version-control/git/change-request-link.js.map +1 -0
  332. package/dist/modules/version-control/git/git-version.d.ts.map +1 -0
  333. package/dist/modules/version-control/git/git-version.js.map +1 -0
  334. package/dist/modules/{workflow → version-control}/git/git.service.d.ts +8 -8
  335. package/dist/modules/version-control/git/git.service.d.ts.map +1 -0
  336. package/dist/modules/{workflow → version-control}/git/git.service.js +53 -53
  337. package/dist/modules/version-control/git/git.service.js.map +1 -0
  338. package/dist/modules/version-control/git/merge-commit.d.ts.map +1 -0
  339. package/dist/modules/version-control/git/merge-commit.js.map +1 -0
  340. package/dist/modules/version-control/git/node-git-runner.d.ts.map +1 -0
  341. package/dist/modules/{workflow → version-control}/git/node-git-runner.js +1 -1
  342. package/dist/modules/version-control/git/node-git-runner.js.map +1 -0
  343. package/dist/modules/{workflow → version-control}/git/pull-request.service.d.ts +5 -5
  344. package/dist/modules/version-control/git/pull-request.service.d.ts.map +1 -0
  345. package/dist/modules/{workflow → version-control}/git/pull-request.service.js +10 -10
  346. package/dist/modules/version-control/git/pull-request.service.js.map +1 -0
  347. package/dist/modules/{workflow → version-control}/index.d.ts +6 -5
  348. package/dist/modules/version-control/index.d.ts.map +1 -0
  349. package/dist/modules/{workflow → version-control}/index.js +3 -2
  350. package/dist/modules/version-control/index.js.map +1 -0
  351. package/dist/modules/{workflow → version-control}/pending-commits.service.d.ts +2 -2
  352. package/dist/modules/version-control/pending-commits.service.d.ts.map +1 -0
  353. package/dist/modules/{workflow → version-control}/pending-commits.service.js +2 -2
  354. package/dist/modules/version-control/pending-commits.service.js.map +1 -0
  355. package/dist/modules/{workflow → version-control}/pending-commits.worker.d.ts +5 -5
  356. package/dist/modules/version-control/pending-commits.worker.d.ts.map +1 -0
  357. package/dist/modules/{workflow → version-control}/pending-commits.worker.js +3 -3
  358. package/dist/modules/version-control/pending-commits.worker.js.map +1 -0
  359. package/dist/modules/{workflow → version-control}/read-on-branch.d.ts +2 -2
  360. package/dist/modules/version-control/read-on-branch.d.ts.map +1 -0
  361. package/dist/modules/{workflow → version-control}/read-on-branch.js +2 -2
  362. package/dist/modules/version-control/read-on-branch.js.map +1 -0
  363. package/dist/modules/version-control/recovery-bot.d.ts.map +1 -0
  364. package/dist/modules/version-control/recovery-bot.js.map +1 -0
  365. package/dist/modules/version-control/sanitize-error.d.ts.map +1 -0
  366. package/dist/modules/version-control/sanitize-error.js.map +1 -0
  367. package/dist/modules/{workflow/workflow-hooks.d.ts → version-control/version-control-hooks.d.ts} +4 -4
  368. package/dist/modules/version-control/version-control-hooks.d.ts.map +1 -0
  369. package/dist/modules/{workflow/workflow-hooks.js → version-control/version-control-hooks.js} +3 -3
  370. package/dist/modules/version-control/version-control-hooks.js.map +1 -0
  371. package/dist/modules/{workflow/workflow.routes.d.ts → version-control/version-control.routes.d.ts} +6 -5
  372. package/dist/modules/version-control/version-control.routes.d.ts.map +1 -0
  373. package/dist/modules/{workflow/workflow.routes.js → version-control/version-control.routes.js} +61 -60
  374. package/dist/modules/version-control/version-control.routes.js.map +1 -0
  375. package/dist/modules/{workflow/workflow.service.d.ts → version-control/version-control.service.d.ts} +26 -31
  376. package/dist/modules/version-control/version-control.service.d.ts.map +1 -0
  377. package/dist/modules/{workflow/workflow.service.js → version-control/version-control.service.js} +89 -94
  378. package/dist/modules/version-control/version-control.service.js.map +1 -0
  379. package/dist/modules/workspace/agent-access.gate.d.ts +6 -6
  380. package/dist/modules/workspace/agent-access.gate.d.ts.map +1 -1
  381. package/dist/modules/workspace/agent-access.gate.js +2 -2
  382. package/dist/modules/workspace/agent-access.gate.js.map +1 -1
  383. package/dist/modules/workspace/git-internals.middleware.d.ts +1 -1
  384. package/dist/modules/workspace/git-internals.middleware.js +2 -2
  385. package/dist/modules/workspace/kb-repository.js +1 -1
  386. package/dist/modules/workspace/kb-repository.js.map +1 -1
  387. package/dist/modules/workspace/startup/kb-git.d.ts +1 -1
  388. package/dist/modules/workspace/startup/kb-git.d.ts.map +1 -1
  389. package/dist/modules/workspace/startup/kb-git.js +1 -1
  390. package/dist/modules/workspace/startup/kb-git.js.map +1 -1
  391. package/dist/modules/workspace/startup/steps/seed-tree.d.ts +2 -2
  392. package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
  393. package/dist/modules/workspace/startup/steps/seed-tree.js +1 -1
  394. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  395. package/dist/modules/workspace/startup/steps/template-files.step.d.ts +2 -2
  396. package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
  397. package/dist/modules/workspace/startup/steps/template-files.step.js +2 -2
  398. package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
  399. package/dist/modules/workspace/startup/steps/template-source.d.ts +17 -4
  400. package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -1
  401. package/dist/modules/workspace/startup/steps/template-source.js +8 -5
  402. package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
  403. package/dist/modules/workspace/workspace-tmp.js +3 -3
  404. package/dist/modules/workspace/workspace-tmp.js.map +1 -1
  405. package/dist/modules/workspace/workspace.routes.d.ts +4 -4
  406. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  407. package/dist/modules/workspace/workspace.routes.js +22 -22
  408. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  409. package/dist/modules/workspace/workspace.service.d.ts +6 -6
  410. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  411. package/dist/modules/workspace/workspace.service.js +11 -11
  412. package/dist/modules/workspace/workspace.service.js.map +1 -1
  413. package/dist/modules/workspace/workspace.tools.d.ts +5 -3
  414. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  415. package/dist/modules/workspace/workspace.tools.js +85 -30
  416. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  417. package/dist/shared/canonical-file-identity.d.ts +2 -2
  418. package/dist/shared/canonical-file-identity.js +5 -5
  419. package/dist/shared/canonical-file-identity.js.map +1 -1
  420. package/dist/shared/domain-errors.d.ts +39 -39
  421. package/dist/shared/domain-errors.d.ts.map +1 -1
  422. package/dist/shared/domain-errors.js +44 -44
  423. package/dist/shared/domain-errors.js.map +1 -1
  424. package/dist/shared/git.contract.d.ts +1 -1
  425. package/dist/shared/git.contract.js +1 -1
  426. package/dist/shared/http-errors.d.ts +3 -3
  427. package/dist/shared/http-errors.d.ts.map +1 -1
  428. package/dist/shared/http-errors.js +1 -1
  429. package/dist/shared/http-errors.js.map +1 -1
  430. package/dist/shared/oauth-token-error.d.ts +23 -0
  431. package/dist/shared/oauth-token-error.d.ts.map +1 -0
  432. package/dist/shared/oauth-token-error.js +47 -0
  433. package/dist/shared/oauth-token-error.js.map +1 -0
  434. package/dist/shared/pending-proposals.d.ts +3 -3
  435. package/dist/shared/pending-proposals.d.ts.map +1 -1
  436. package/dist/shared/pending-proposals.js +2 -2
  437. package/dist/shared/pending-proposals.js.map +1 -1
  438. package/dist/shared/read-capped.d.ts +19 -0
  439. package/dist/shared/read-capped.d.ts.map +1 -0
  440. package/dist/shared/read-capped.js +45 -0
  441. package/dist/shared/read-capped.js.map +1 -0
  442. package/dist/tenancy/static-tenant-source.js +1 -1
  443. package/dist/tenancy/static-tenant-source.js.map +1 -1
  444. package/migrations/0012_agent_audit.sql +40 -40
  445. package/migrations/0013_agent_identity_and_key_soft_delete.sql +29 -29
  446. package/migrations/meta/0012_snapshot.json +2246 -2246
  447. package/migrations/meta/0013_snapshot.json +2258 -2258
  448. package/package.json +5 -4
  449. package/src/__tests__/account-admin.ts +27 -0
  450. package/src/__tests__/hexis-catalog.ts +144 -0
  451. package/src/__tests__/kb-context.ts +30 -30
  452. package/src/__tests__/kb-layout-config.test.ts +21 -0
  453. package/src/__tests__/open-change-gate.ts +1 -1
  454. package/src/__tests__/real-disk.ts +21 -0
  455. package/src/__tests__/tokens.ts +19 -0
  456. package/src/__tests__/tool-handler.ts +15 -0
  457. package/src/__tests__/tool-manuals.ts +32 -0
  458. package/src/__tests__/tool-wiring.ts +31 -0
  459. package/src/__tests__/workspace-service.ts +1 -1
  460. package/src/core/__tests__/catalog-cache-invalidation.test.ts +3 -3
  461. package/src/core/__tests__/compose-embed.test.ts +1 -1
  462. package/src/core/__tests__/damaged-document.tools.test.ts +3 -3
  463. package/src/core/__tests__/erasure-slices-wired-once.test.ts +46 -0
  464. package/src/core/__tests__/gated-boot.test.ts +2 -2
  465. package/src/core/__tests__/lifecycle.test.ts +9 -9
  466. package/src/core/__tests__/oauth-sign-in-real-file.test.ts +179 -0
  467. package/src/core/catalog-cache-invalidation.ts +2 -2
  468. package/src/core/compose-embed.ts +3 -3
  469. package/src/core/core-ports.ts +19 -4
  470. package/src/core/create-core-server.ts +40 -26
  471. package/src/core/create-core-services.ts +92 -66
  472. package/src/core/lifecycle.ts +9 -9
  473. package/src/core-config.ts +3 -3
  474. package/src/index.ts +5 -5
  475. package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +4 -4
  476. package/src/modules/access/__tests__/access-own-read-grant.test.ts +14 -14
  477. package/src/modules/access/__tests__/access-requests.routes.test.ts +20 -20
  478. package/src/modules/access/__tests__/access.routes.admins.test.ts +4 -4
  479. package/src/modules/access/__tests__/access.routes.batch.test.ts +4 -4
  480. package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +6 -6
  481. package/src/modules/access/__tests__/access.routes.group-grant.test.ts +6 -6
  482. package/src/modules/access/__tests__/access.routes.overrides.test.ts +5 -5
  483. package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +6 -6
  484. package/src/modules/access/__tests__/access.routes.prospective.test.ts +54 -14
  485. package/src/modules/access/__tests__/access.routes.revoke.test.ts +6 -6
  486. package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +6 -6
  487. package/src/modules/access/__tests__/admin-locked-commit.test.ts +6 -6
  488. package/src/modules/access/__tests__/admin-route-helpers.test.ts +5 -5
  489. package/src/modules/access/__tests__/groups-admin.service.test.ts +27 -27
  490. package/src/modules/access/__tests__/holder-changes.test.ts +127 -0
  491. package/src/modules/access/__tests__/roles-admin.security.test.ts +14 -13
  492. package/src/modules/access/__tests__/roles-admin.service.test.ts +27 -27
  493. package/src/modules/access/__tests__/roles-capabilities.test.ts +19 -19
  494. package/src/modules/access/__tests__/roles.routes.test.ts +6 -6
  495. package/src/modules/access/__tests__/synced-groups-committer.test.ts +13 -13
  496. package/src/modules/access/__tests__/user-access-removal.service.test.ts +29 -29
  497. package/src/modules/access/access-control.interface.ts +26 -0
  498. package/src/modules/access/access-control.service.ts +93 -1
  499. package/src/modules/access/access-declarations.ts +2 -2
  500. package/src/modules/access/access-mutation.service.ts +2 -2
  501. package/src/modules/access/access-requests.routes.ts +7 -7
  502. package/src/modules/access/access-requests.service.ts +13 -13
  503. package/src/modules/access/access.routes.ts +34 -15
  504. package/src/modules/access/admin-locked-commit.ts +11 -11
  505. package/src/modules/access/admin-route-helpers.ts +5 -5
  506. package/src/modules/access/change-read-gate.ts +1 -1
  507. package/src/modules/access/groups-admin.service.ts +7 -7
  508. package/src/modules/access/index.ts +1 -1
  509. package/src/modules/access/reference-scan.ts +1 -1
  510. package/src/modules/access/roles-admin.service.ts +9 -9
  511. package/src/modules/access/synced-groups-committer.ts +11 -11
  512. package/src/modules/access/user-access-removal.service.ts +7 -7
  513. package/src/modules/access-model/__tests__/access-grammar.test.ts +2 -2
  514. package/src/modules/access-model/access-errors.ts +4 -4
  515. package/src/modules/access-model/access-grammar.ts +4 -4
  516. package/src/modules/access-model/change-gate.ts +1 -1
  517. package/src/modules/access-model/roles-yaml-guard.ts +4 -4
  518. package/src/modules/agent-guide/__tests__/agent-guide.test.ts +98 -29
  519. package/src/modules/agent-guide/__tests__/agent-guide.tools.test.ts +39 -12
  520. package/src/modules/agent-guide/__tests__/guide-budget.test.ts +95 -0
  521. package/src/modules/agent-guide/__tests__/guide-eval.test.ts +182 -0
  522. package/src/modules/agent-guide/__tests__/guide-matches-code.test.ts +263 -0
  523. package/src/modules/agent-guide/__tests__/tool-surface.json +514 -0
  524. package/src/modules/agent-guide/__tests__/tool-surface.test.ts +75 -0
  525. package/src/modules/agent-guide/agent-guide.tools.ts +49 -31
  526. package/src/modules/agent-guide/agent-guide.ts +165 -32
  527. package/src/modules/agent-guide/guide-budget.ts +77 -0
  528. package/src/modules/agent-guide/index.ts +12 -0
  529. package/src/modules/agent-instructions/__tests__/agent-instructions.route.test.ts +4 -5
  530. package/src/modules/agent-instructions/__tests__/compose.test.ts +1 -1
  531. package/src/modules/agent-instructions/__tests__/shared-file-rules.test.ts +117 -11
  532. package/src/modules/agent-instructions/agent-instructions.routes.ts +12 -5
  533. package/src/modules/agent-instructions/compose.ts +28 -9
  534. package/src/modules/agent-instructions/shared-file-rules.ts +62 -18
  535. package/src/modules/agent-scope/__tests__/agent-surfaces.connect-as.test.ts +1 -1
  536. package/src/modules/audit/__tests__/agent-rest-audit.middleware.test.ts +113 -113
  537. package/src/modules/audit/__tests__/event-classifier.test.ts +121 -121
  538. package/src/modules/audit/event-classifier.ts +155 -155
  539. package/src/modules/auth/__tests__/account-deactivation.test.ts +1 -1
  540. package/src/modules/auth/__tests__/account-erasure.approval-gate.test.ts +4 -4
  541. package/src/modules/auth/__tests__/account-erasure.participants.test.ts +56 -0
  542. package/src/modules/auth/__tests__/account-switch-lock.pg.test.ts +2 -2
  543. package/src/modules/auth/__tests__/account-switch-lock.test.ts +2 -2
  544. package/src/modules/auth/__tests__/account.routes.test.ts +73 -11
  545. package/src/modules/auth/__tests__/auth.service.test.ts +1 -1
  546. package/src/modules/auth/account-erasure.service.ts +27 -9
  547. package/src/modules/auth/account-hooks.ts +34 -0
  548. package/src/modules/auth/account-switch-lock.ts +2 -2
  549. package/src/modules/auth/account.routes.ts +23 -5
  550. package/src/modules/auth/auth.service.ts +4 -4
  551. package/src/modules/auth/index.ts +1 -0
  552. package/src/modules/code-mode/code-mode.tool.ts +2 -2
  553. package/src/modules/connection-probe/__tests__/connection-probe.service.test.ts +5 -24
  554. package/src/modules/connection-probe/connection-probe.service.ts +1 -34
  555. package/src/modules/database/__tests__/advisory-lock.test.ts +169 -169
  556. package/src/modules/database/__tests__/migrations-unqualified.test.ts +32 -32
  557. package/src/modules/database/core-schema.ts +2 -2
  558. package/src/modules/diff/__tests__/diff.routes.read-gate.test.ts +2 -2
  559. package/src/modules/diff/__tests__/diff.routes.rejectPathsLocked.test.ts +12 -12
  560. package/src/modules/diff/diff.routes.ts +8 -8
  561. package/src/modules/embed/__tests__/embed.service.lock.test.ts +7 -7
  562. package/src/modules/embed/__tests__/embed.service.test.ts +42 -42
  563. package/src/modules/embed/__tests__/embed.tools.test.ts +1 -1
  564. package/src/modules/embed/embed.routes.ts +1 -1
  565. package/src/modules/embed/embed.service.ts +17 -17
  566. package/src/modules/kb-fs/__tests__/branch-name.test.ts +2 -2
  567. package/src/modules/kb-fs/__tests__/locking-filesystem.test.ts +260 -260
  568. package/src/modules/kb-fs/__tests__/move-with-edits.test.ts +34 -34
  569. package/src/modules/kb-fs/__tests__/repo-path.test.ts +8 -8
  570. package/src/modules/kb-fs/branch-name.ts +8 -8
  571. package/src/modules/kb-fs/file-change-notifier.ts +2 -2
  572. package/src/modules/kb-fs/locking-filesystem.ts +30 -30
  573. package/src/modules/kb-fs/repo-path.ts +5 -5
  574. package/src/modules/kb-fs/tmp-ref.ts +3 -3
  575. package/src/modules/kb-sync/__tests__/kb-sync.service.test.ts +36 -36
  576. package/src/modules/kb-sync/index.ts +1 -1
  577. package/src/modules/kb-sync/kb-sync.interface.ts +3 -3
  578. package/src/modules/kb-sync/kb-sync.service.ts +9 -9
  579. package/src/modules/marketplace/__tests__/github-facade.test.ts +1 -1
  580. package/src/modules/marketplace/__tests__/marketplace-git.test.ts +1 -1
  581. package/src/modules/mcp/__tests__/mcp-proxy-helpers.test.ts +4 -2
  582. package/src/modules/mcp/__tests__/mcp.e2e.test.ts +69 -8
  583. package/src/modules/mcp/__tests__/mcp.service.test.ts +91 -13
  584. package/src/modules/mcp/__tests__/read-only-hint.pg.test.ts +194 -0
  585. package/src/modules/mcp/mcp.service.ts +93 -62
  586. package/src/modules/onboarding/__tests__/starter-pack.service.test.ts +55 -55
  587. package/src/modules/onboarding/onboarding.contract.ts +1 -1
  588. package/src/modules/onboarding/onboarding.routes.ts +2 -2
  589. package/src/modules/onboarding/starter-pack.service.ts +6 -6
  590. package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +1 -1
  591. package/src/modules/plugins/__tests__/compile-marketplace.test.ts +1 -1
  592. package/src/modules/plugins/__tests__/join-request-jobs.service.test.ts +43 -43
  593. package/src/modules/plugins/__tests__/join-requests.service.test.ts +19 -19
  594. package/src/modules/plugins/__tests__/join-requests.settlement.test.ts +26 -26
  595. package/src/modules/plugins/__tests__/plugins.routes.test.ts +25 -25
  596. package/src/modules/plugins/join-request-jobs.service.ts +10 -10
  597. package/src/modules/plugins/join-requests.service.ts +4 -4
  598. package/src/modules/plugins/plugin-rename.service.ts +1 -1
  599. package/src/modules/plugins/plugins.routes.ts +9 -9
  600. package/src/modules/secrets-vault/__tests__/db-secrets-vault.managed.test.ts +773 -0
  601. package/src/modules/secrets-vault/__tests__/db-secrets-vault.oauth.test.ts +458 -4
  602. package/src/modules/secrets-vault/__tests__/managed-sign-in.route.test.ts +351 -0
  603. package/src/modules/secrets-vault/__tests__/oauth-live-declaration.route.test.ts +218 -0
  604. package/src/modules/secrets-vault/__tests__/oauth-return-to.route.test.ts +39 -6
  605. package/src/modules/secrets-vault/db-secrets-vault.service.ts +728 -118
  606. package/src/modules/secrets-vault/index.ts +8 -1
  607. package/src/modules/secrets-vault/managed-sign-in-erasure.ts +41 -0
  608. package/src/modules/secrets-vault/secrets-variable-loader.ts +134 -134
  609. package/src/modules/secrets-vault/secrets-vault.contract.ts +213 -11
  610. package/src/modules/secrets-vault/secrets-vault.routes.ts +244 -45
  611. package/src/modules/settings/__tests__/repository-source.test.ts +1 -1
  612. package/src/modules/settings/__tests__/setup.routes.layout-phase.test.ts +1 -1
  613. package/src/modules/settings/__tests__/setup.routes.managed-phase.test.ts +1 -1
  614. package/src/modules/settings/connection-check.ts +1 -1
  615. package/src/modules/settings/deployment-settings.service.ts +1 -1
  616. package/src/modules/settings/git-root-folders.ts +1 -1
  617. package/src/modules/settings/oidc-check.ts +5 -18
  618. package/src/modules/settings/setup.routes.ts +1 -1
  619. package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +3 -3
  620. package/src/modules/skills/__tests__/branch-skills.tools.test.ts +1 -1
  621. package/src/modules/skills/__tests__/pending-skills.service.test.ts +8 -8
  622. package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +18 -18
  623. package/src/modules/skills/__tests__/skills.service.test.ts +3 -3
  624. package/src/modules/skills/pending-skills.service.ts +3 -3
  625. package/src/modules/skills/skill-access-requests.routes.ts +7 -7
  626. package/src/modules/skills/skills.tools.ts +1 -1
  627. package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +22 -14
  628. package/src/modules/tool-helpers/__tests__/branch-declaration.test.ts +3 -3
  629. package/src/modules/tool-helpers/__tests__/can-write.tools.test.ts +3 -3
  630. package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +4 -4
  631. package/src/modules/tool-helpers/__tests__/route-tool-schemas.catalog.test.ts +38 -0
  632. package/src/modules/tool-helpers/__tests__/tools-surface.test.ts +3 -3
  633. package/src/modules/tool-helpers/__tests__/validate-token.test.ts +1 -1
  634. package/src/modules/tool-helpers/tool-context.ts +6 -6
  635. package/src/modules/tool-helpers/tool-def.ts +1 -1
  636. package/src/modules/tool-helpers/tool-handler.ts +2 -2
  637. package/src/modules/tool-helpers/tool.contract.ts +4 -4
  638. package/src/modules/tool-manuals/__tests__/pending-tools.service.test.ts +9 -9
  639. package/src/modules/tool-manuals/__tests__/tool-manuals.managed-sign-in.test.ts +89 -0
  640. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +197 -11
  641. package/src/modules/tool-manuals/__tests__/tool-manuals.restart.test.ts +1 -1
  642. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +132 -6
  643. package/src/modules/tool-manuals/mcp-json-discovery.ts +73 -34
  644. package/src/modules/tool-manuals/mcp-server-edit.service.ts +1 -1
  645. package/src/modules/tool-manuals/pending-tools.service.ts +3 -3
  646. package/src/modules/tool-manuals/tool-delete.service.ts +1 -1
  647. package/src/modules/tool-manuals/tool-manuals.contract.ts +63 -3
  648. package/src/modules/tool-manuals/tool-manuals.service.ts +191 -51
  649. package/src/modules/tool-manuals/tool-manuals.tools.ts +93 -28
  650. package/src/modules/tool-registry/__tests__/own-tool-schemas.test.ts +4 -4
  651. package/src/modules/tool-registry/__tests__/read-only-hints.test.ts +3 -3
  652. package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +12 -119
  653. package/src/modules/{workflow → version-control}/__tests__/apply-failure.test.ts +54 -54
  654. package/src/modules/{workflow → version-control}/__tests__/event-bus.test.ts +27 -27
  655. package/src/modules/{workflow → version-control}/__tests__/events-delivery.test.ts +37 -37
  656. package/src/modules/{workflow → version-control}/__tests__/file-lock.service.deletion-gate.test.ts +2 -2
  657. package/src/modules/{workflow → version-control}/__tests__/file-lock.service.path-identity.test.ts +8 -8
  658. package/src/modules/{workflow → version-control}/__tests__/merge-announces-tree.test.ts +11 -11
  659. package/src/modules/{workflow → version-control}/__tests__/pending-commits.worker.concurrency.test.ts +9 -9
  660. package/src/modules/{workflow → version-control}/__tests__/pending-commits.worker.test.ts +25 -25
  661. package/src/modules/{workflow → version-control}/__tests__/preserve-roles-yaml.test.ts +42 -42
  662. package/src/modules/version-control/__tests__/public-surface.test.ts +114 -0
  663. package/src/modules/{workflow/__tests__/workflow.routes.folder-proposals.test.ts → version-control/__tests__/version-control.routes.folder-proposals.test.ts} +18 -18
  664. package/src/modules/{workflow/__tests__/workflow.routes.fork-point-file.test.ts → version-control/__tests__/version-control.routes.fork-point-file.test.ts} +19 -19
  665. package/src/modules/{workflow/__tests__/workflow.routes.history-read-gate.test.ts → version-control/__tests__/version-control.routes.history-read-gate.test.ts} +13 -13
  666. package/src/modules/{workflow/__tests__/workflow.routes.lock-path.test.ts → version-control/__tests__/version-control.routes.lock-path.test.ts} +18 -18
  667. package/src/modules/{workflow/__tests__/workflow.routes.open-change-request.test.ts → version-control/__tests__/version-control.routes.open-change-request.test.ts} +7 -7
  668. package/src/modules/{workflow/__tests__/workflow.routes.push-refused.test.ts → version-control/__tests__/version-control.routes.push-refused.test.ts} +14 -14
  669. package/src/modules/{workflow/__tests__/workflow.service.branch-in-use.test.ts → version-control/__tests__/version-control.service.branch-in-use.test.ts} +6 -6
  670. package/src/modules/{workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts → version-control/__tests__/version-control.service.commitFileWhileLocked.test.ts} +14 -14
  671. package/src/modules/{workflow/__tests__/workflow.service.delete-branch.test.ts → version-control/__tests__/version-control.service.delete-branch.test.ts} +14 -14
  672. package/src/modules/{workflow/__tests__/workflow.service.deleted-branch-sweep.test.ts → version-control/__tests__/version-control.service.deleted-branch-sweep.test.ts} +4 -4
  673. package/src/modules/{workflow/__tests__/workflow.service.facade.test.ts → version-control/__tests__/version-control.service.facade.test.ts} +97 -99
  674. package/src/modules/{workflow/__tests__/workflow.service.folder-proposals.test.ts → version-control/__tests__/version-control.service.folder-proposals.test.ts} +7 -7
  675. package/src/modules/{workflow/__tests__/workflow.service.platform-restore.test.ts → version-control/__tests__/version-control.service.platform-restore.test.ts} +6 -6
  676. package/src/modules/{workflow/__tests__/workflow.service.read-gate.test.ts → version-control/__tests__/version-control.service.read-gate.test.ts} +9 -9
  677. package/src/modules/{workflow/__tests__/workflow.service.releaseLock.test.ts → version-control/__tests__/version-control.service.releaseLock.test.ts} +42 -42
  678. package/src/modules/{workflow/__tests__/workflow.service.repository-replaced.test.ts → version-control/__tests__/version-control.service.repository-replaced.test.ts} +4 -4
  679. package/src/modules/{workflow/__tests__/workflow.service.sync.test.ts → version-control/__tests__/version-control.service.sync.test.ts} +17 -17
  680. package/src/modules/{workflow/__tests__/workflow.service.update-change-request.pg.test.ts → version-control/__tests__/version-control.service.update-change-request.pg.test.ts} +6 -6
  681. package/src/modules/{workflow/__tests__/workflow.service.update-change-request.test.ts → version-control/__tests__/version-control.service.update-change-request.test.ts} +11 -11
  682. package/src/modules/{workflow/__tests__/workflow.service.update-from-target.test.ts → version-control/__tests__/version-control.service.update-from-target.test.ts} +22 -22
  683. package/src/modules/{workflow → version-control}/agent-tools/__tests__/change-request-read.tools.test.ts +3 -3
  684. package/src/modules/{workflow → version-control}/agent-tools/__tests__/update-change-request.parity.test.ts +16 -16
  685. package/src/modules/{workflow/agent-tools/__tests__/workflow.tools.test.ts → version-control/agent-tools/__tests__/version-control.tools.test.ts} +9 -9
  686. package/src/modules/{workflow → version-control}/agent-tools/change-request-read.tools.ts +2 -2
  687. package/src/modules/{workflow/agent-tools/workflow.tools.ts → version-control/agent-tools/version-control.tools.ts} +52 -48
  688. package/src/modules/{workflow → version-control}/change-request-hooks.ts +1 -1
  689. package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/approval-states.test.ts +5 -5
  690. package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/cancel-pr.test.ts +8 -8
  691. package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/carry-approvals-forward.test.ts +6 -6
  692. package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/erase-approver.test.ts +5 -5
  693. package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/merge-gate.test.ts +3 -3
  694. package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/merge-records-own-commit.test.ts +3 -3
  695. package/src/modules/{workflow/review-workflow/review-workflow.interface.ts → version-control/change-request-review/change-request-review.interface.ts} +1 -1
  696. package/src/modules/{workflow/review-workflow/review-workflow.service.ts → version-control/change-request-review/change-request-review.service.ts} +28 -28
  697. package/src/modules/{workflow → version-control}/event-bus.ts +14 -14
  698. package/src/modules/{workflow → version-control}/events-delivery.ts +11 -11
  699. package/src/modules/{workflow → version-control}/events.routes.ts +5 -5
  700. package/src/modules/{workflow → version-control}/file-lock.service.ts +6 -6
  701. package/src/modules/{workflow → version-control}/git/__tests__/git-test-helpers.ts +3 -3
  702. package/src/modules/{workflow → version-control}/git/__tests__/git.service.accessGating.test.ts +5 -5
  703. package/src/modules/{workflow → version-control}/git/__tests__/git.service.appliedChange.test.ts +4 -4
  704. package/src/modules/{workflow → version-control}/git/__tests__/git.service.changedFilesForPr.test.ts +16 -16
  705. package/src/modules/{workflow → version-control}/git/__tests__/git.service.changedPathsMemo.test.ts +2 -2
  706. package/src/modules/{workflow → version-control}/git/__tests__/git.service.commitChanges.test.ts +3 -3
  707. package/src/modules/{workflow → version-control}/git/__tests__/git.service.commitFile.strayPath.test.ts +10 -10
  708. package/src/modules/{workflow → version-control}/git/__tests__/git.service.commitFile.test.ts +3 -3
  709. package/src/modules/{workflow → version-control}/git/__tests__/git.service.createBranch.test.ts +3 -3
  710. package/src/modules/{workflow → version-control}/git/__tests__/git.service.deleteBranch.test.ts +7 -7
  711. package/src/modules/{workflow → version-control}/git/__tests__/git.service.diffFileAtCommit.test.ts +9 -9
  712. package/src/modules/{workflow → version-control}/git/__tests__/git.service.diffFileBetweenBranches.test.ts +23 -23
  713. package/src/modules/{workflow → version-control}/git/__tests__/git.service.fileBytesAtCommit.test.ts +7 -7
  714. package/src/modules/{workflow → version-control}/git/__tests__/git.service.fileContentsAtCommit.test.ts +3 -3
  715. package/src/modules/{workflow → version-control}/git/__tests__/git.service.forkPoint.test.ts +2 -2
  716. package/src/modules/{workflow → version-control}/git/__tests__/git.service.history-guards.test.ts +2 -2
  717. package/src/modules/{workflow → version-control}/git/__tests__/git.service.list-branches.test.ts +12 -12
  718. package/src/modules/{workflow → version-control}/git/__tests__/git.service.listTrackedFiles.test.ts +2 -2
  719. package/src/modules/{workflow → version-control}/git/__tests__/git.service.logForFile.test.ts +6 -6
  720. package/src/modules/{workflow → version-control}/git/__tests__/git.service.mergeChangeRequest.test.ts +20 -20
  721. package/src/modules/{workflow → version-control}/git/__tests__/git.service.mergeIntoBranch.test.ts +16 -16
  722. package/src/modules/{workflow → version-control}/git/__tests__/git.service.pendingChanges.test.ts +2 -2
  723. package/src/modules/{workflow → version-control}/git/__tests__/git.service.postMergePull.test.ts +5 -5
  724. package/src/modules/{workflow → version-control}/git/__tests__/git.service.prFetchFailure.test.ts +2 -2
  725. package/src/modules/{workflow → version-control}/git/__tests__/git.service.pull.test.ts +12 -12
  726. package/src/modules/{workflow → version-control}/git/__tests__/git.service.readFileAtRef.test.ts +3 -3
  727. package/src/modules/{workflow → version-control}/git/__tests__/git.service.revertPathsAndPush.test.ts +2 -2
  728. package/src/modules/{workflow → version-control}/git/__tests__/git.service.status.test.ts +4 -4
  729. package/src/modules/{workflow → version-control}/git/__tests__/git.service.syncFromRemote.test.ts +8 -8
  730. package/src/modules/{workflow → version-control}/git/__tests__/git.service.worktrees.test.ts +4 -4
  731. package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.list-fetch.test.ts +2 -2
  732. package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.test.ts +6 -6
  733. package/src/modules/{workflow → version-control}/git/git.service.ts +57 -57
  734. package/src/modules/{workflow → version-control}/git/node-git-runner.ts +1 -1
  735. package/src/modules/{workflow → version-control}/git/pull-request.service.ts +12 -12
  736. package/src/modules/{workflow → version-control}/index.ts +6 -5
  737. package/src/modules/{workflow → version-control}/pending-commits.service.ts +2 -2
  738. package/src/modules/{workflow → version-control}/pending-commits.worker.ts +8 -8
  739. package/src/modules/{workflow → version-control}/read-on-branch.ts +2 -2
  740. package/src/modules/{workflow/workflow-hooks.ts → version-control/version-control-hooks.ts} +3 -3
  741. package/src/modules/{workflow/workflow.routes.ts → version-control/version-control.routes.ts} +64 -63
  742. package/src/modules/{workflow/workflow.service.ts → version-control/version-control.service.ts} +92 -97
  743. package/src/modules/workspace/__tests__/agent-access.gate.test.ts +8 -8
  744. package/src/modules/workspace/__tests__/agent-downloads.test.ts +13 -16
  745. package/src/modules/workspace/__tests__/agent-uploads.test.ts +11 -12
  746. package/src/modules/workspace/__tests__/escape-sequences.routes.test.ts +11 -16
  747. package/src/modules/workspace/__tests__/file-stat-access.test.ts +3 -3
  748. package/src/modules/workspace/__tests__/git-internals.security.test.ts +27 -27
  749. package/src/modules/workspace/__tests__/kb-repository.test.ts +1 -1
  750. package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +3 -3
  751. package/src/modules/workspace/__tests__/start-session.default-branch.test.ts +152 -0
  752. package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +6 -6
  753. package/src/modules/workspace/__tests__/workspace-tmp.tools.test.ts +13 -14
  754. package/src/modules/workspace/__tests__/workspace.routes.at-ref.test.ts +6 -6
  755. package/src/modules/workspace/__tests__/workspace.routes.branch-errors.test.ts +4 -4
  756. package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +6 -6
  757. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +8 -8
  758. package/src/modules/workspace/__tests__/workspace.routes.download-implies-read.test.ts +4 -4
  759. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +6 -6
  760. package/src/modules/workspace/__tests__/workspace.routes.file-writes.test.ts +6 -6
  761. package/src/modules/workspace/__tests__/workspace.routes.folder-zip-access.test.ts +4 -4
  762. package/src/modules/workspace/__tests__/workspace.routes.folders.test.ts +6 -6
  763. package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +7 -7
  764. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +13 -13
  765. package/src/modules/workspace/__tests__/workspace.service.any-workspace-credentials.test.ts +1 -1
  766. package/src/modules/workspace/__tests__/workspace.service.replaced-repository.test.ts +1 -1
  767. package/src/modules/workspace/__tests__/workspace.service.worktrees.test.ts +1 -1
  768. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +12 -14
  769. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +5 -5
  770. package/src/modules/workspace/__tests__/workspace.tools.test.ts +182 -75
  771. package/src/modules/workspace/agent-access.gate.ts +6 -6
  772. package/src/modules/workspace/git-internals.middleware.ts +2 -2
  773. package/src/modules/workspace/kb-repository.ts +1 -1
  774. package/src/modules/workspace/startup/__tests__/kb-startup-runner.degraded.test.ts +1 -1
  775. package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +1 -1
  776. package/src/modules/workspace/startup/__tests__/kb-startup-runner.worktrees.test.ts +1 -1
  777. package/src/modules/workspace/startup/kb-git.ts +1 -1
  778. package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +94 -70
  779. package/src/modules/workspace/startup/steps/seed-tree.ts +4 -5
  780. package/src/modules/workspace/startup/steps/template-files.step.ts +4 -5
  781. package/src/modules/workspace/startup/steps/template-source.ts +21 -6
  782. package/src/modules/workspace/workspace-tmp.ts +4 -4
  783. package/src/modules/workspace/workspace.routes.ts +26 -26
  784. package/src/modules/workspace/workspace.service.ts +11 -11
  785. package/src/modules/workspace/workspace.tools.ts +90 -30
  786. package/src/shared/__tests__/canonical-file-identity.test.ts +5 -5
  787. package/src/shared/__tests__/http-errors.test.ts +4 -4
  788. package/src/shared/__tests__/read-capped.test.ts +68 -0
  789. package/src/shared/canonical-file-identity.ts +5 -5
  790. package/src/shared/domain-errors.ts +44 -44
  791. package/src/shared/git.contract.ts +1 -1
  792. package/src/shared/http-errors.ts +3 -3
  793. package/src/shared/kb-context.ts +130 -130
  794. package/src/shared/oauth-token-error.ts +46 -0
  795. package/src/shared/pending-proposals.ts +4 -4
  796. package/src/shared/read-capped.ts +40 -0
  797. package/src/tenancy/__tests__/tenant-host.test.ts +372 -372
  798. package/src/tenancy/__tests__/tenant-runtime.test.ts +221 -221
  799. package/src/tenancy/__tests__/tenant-secrets.test.ts +35 -35
  800. package/src/tenancy/index.ts +35 -35
  801. package/src/tenancy/static-tenant-source.ts +1 -1
  802. package/src/tenancy/tenant-host.ts +261 -261
  803. package/src/tenancy/tenant-runtime.ts +208 -208
  804. package/src/tenancy/tenant-source.contract.ts +59 -59
  805. package/agent-guide/finding-things.md +0 -7
  806. package/agent-guide/introduction.md +0 -27
  807. package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts.map +0 -1
  808. package/dist/modules/workflow/agent-tools/change-request-read-shape.js.map +0 -1
  809. package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts.map +0 -1
  810. package/dist/modules/workflow/agent-tools/change-request-read.tools.js.map +0 -1
  811. package/dist/modules/workflow/agent-tools/change-request-summary.d.ts.map +0 -1
  812. package/dist/modules/workflow/agent-tools/change-request-summary.js.map +0 -1
  813. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +0 -1
  814. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +0 -1
  815. package/dist/modules/workflow/change-request-hooks.d.ts.map +0 -1
  816. package/dist/modules/workflow/change-request-hooks.js.map +0 -1
  817. package/dist/modules/workflow/event-bus.d.ts.map +0 -1
  818. package/dist/modules/workflow/event-bus.js.map +0 -1
  819. package/dist/modules/workflow/events-delivery.d.ts.map +0 -1
  820. package/dist/modules/workflow/events-delivery.js.map +0 -1
  821. package/dist/modules/workflow/events.routes.d.ts.map +0 -1
  822. package/dist/modules/workflow/events.routes.js.map +0 -1
  823. package/dist/modules/workflow/file-lock.service.d.ts.map +0 -1
  824. package/dist/modules/workflow/file-lock.service.js.map +0 -1
  825. package/dist/modules/workflow/git/change-request-link.d.ts.map +0 -1
  826. package/dist/modules/workflow/git/change-request-link.js.map +0 -1
  827. package/dist/modules/workflow/git/git-version.d.ts.map +0 -1
  828. package/dist/modules/workflow/git/git-version.js.map +0 -1
  829. package/dist/modules/workflow/git/git.service.d.ts.map +0 -1
  830. package/dist/modules/workflow/git/git.service.js.map +0 -1
  831. package/dist/modules/workflow/git/merge-commit.d.ts.map +0 -1
  832. package/dist/modules/workflow/git/merge-commit.js.map +0 -1
  833. package/dist/modules/workflow/git/node-git-runner.d.ts.map +0 -1
  834. package/dist/modules/workflow/git/node-git-runner.js.map +0 -1
  835. package/dist/modules/workflow/git/pull-request.service.d.ts.map +0 -1
  836. package/dist/modules/workflow/git/pull-request.service.js.map +0 -1
  837. package/dist/modules/workflow/index.d.ts.map +0 -1
  838. package/dist/modules/workflow/index.js.map +0 -1
  839. package/dist/modules/workflow/pending-commits.service.d.ts.map +0 -1
  840. package/dist/modules/workflow/pending-commits.service.js.map +0 -1
  841. package/dist/modules/workflow/pending-commits.worker.d.ts.map +0 -1
  842. package/dist/modules/workflow/pending-commits.worker.js.map +0 -1
  843. package/dist/modules/workflow/read-on-branch.d.ts.map +0 -1
  844. package/dist/modules/workflow/read-on-branch.js.map +0 -1
  845. package/dist/modules/workflow/recovery-bot.d.ts.map +0 -1
  846. package/dist/modules/workflow/recovery-bot.js.map +0 -1
  847. package/dist/modules/workflow/review-workflow/approval-lock.d.ts.map +0 -1
  848. package/dist/modules/workflow/review-workflow/approval-lock.js.map +0 -1
  849. package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts.map +0 -1
  850. package/dist/modules/workflow/review-workflow/review-workflow.interface.js +0 -2
  851. package/dist/modules/workflow/review-workflow/review-workflow.interface.js.map +0 -1
  852. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +0 -1
  853. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +0 -1
  854. package/dist/modules/workflow/sanitize-error.d.ts.map +0 -1
  855. package/dist/modules/workflow/sanitize-error.js.map +0 -1
  856. package/dist/modules/workflow/workflow-hooks.d.ts.map +0 -1
  857. package/dist/modules/workflow/workflow-hooks.js.map +0 -1
  858. package/dist/modules/workflow/workflow.routes.d.ts.map +0 -1
  859. package/dist/modules/workflow/workflow.routes.js.map +0 -1
  860. package/dist/modules/workflow/workflow.service.d.ts.map +0 -1
  861. package/dist/modules/workflow/workflow.service.js.map +0 -1
  862. package/src/modules/mcp/__tests__/read-only-hint.e2e.test.ts +0 -213
  863. /package/dist/modules/{workflow → version-control}/agent-tools/change-request-read-shape.d.ts +0 -0
  864. /package/dist/modules/{workflow → version-control}/agent-tools/change-request-read-shape.js +0 -0
  865. /package/dist/modules/{workflow → version-control}/agent-tools/change-request-read.tools.d.ts +0 -0
  866. /package/dist/modules/{workflow → version-control}/agent-tools/change-request-summary.d.ts +0 -0
  867. /package/dist/modules/{workflow → version-control}/agent-tools/change-request-summary.js +0 -0
  868. /package/dist/modules/{workflow → version-control}/change-request-hooks.js +0 -0
  869. /package/dist/modules/{workflow/review-workflow → version-control/change-request-review}/approval-lock.d.ts +0 -0
  870. /package/dist/modules/{workflow/review-workflow → version-control/change-request-review}/approval-lock.js +0 -0
  871. /package/dist/modules/{workflow → version-control}/events-delivery.js +0 -0
  872. /package/dist/modules/{workflow → version-control}/events.routes.js +0 -0
  873. /package/dist/modules/{workflow → version-control}/git/change-request-link.d.ts +0 -0
  874. /package/dist/modules/{workflow → version-control}/git/change-request-link.js +0 -0
  875. /package/dist/modules/{workflow → version-control}/git/git-version.d.ts +0 -0
  876. /package/dist/modules/{workflow → version-control}/git/git-version.js +0 -0
  877. /package/dist/modules/{workflow → version-control}/git/merge-commit.d.ts +0 -0
  878. /package/dist/modules/{workflow → version-control}/git/merge-commit.js +0 -0
  879. /package/dist/modules/{workflow → version-control}/git/node-git-runner.d.ts +0 -0
  880. /package/dist/modules/{workflow → version-control}/recovery-bot.d.ts +0 -0
  881. /package/dist/modules/{workflow → version-control}/recovery-bot.js +0 -0
  882. /package/dist/modules/{workflow → version-control}/sanitize-error.d.ts +0 -0
  883. /package/dist/modules/{workflow → version-control}/sanitize-error.js +0 -0
  884. /package/src/modules/{workflow → version-control}/__tests__/change-request-hooks.test.ts +0 -0
  885. /package/src/modules/{workflow → version-control}/__tests__/fake-file-lock-db.ts +0 -0
  886. /package/src/modules/{workflow → version-control}/__tests__/pending-commits.canonical.test.ts +0 -0
  887. /package/src/modules/{workflow → version-control}/__tests__/pending-commits.enqueue-if-absent.test.ts +0 -0
  888. /package/src/modules/{workflow → version-control}/__tests__/pending-commits.repository-replaced.test.ts +0 -0
  889. /package/src/modules/{workflow → version-control}/__tests__/sanitize-error.test.ts +0 -0
  890. /package/src/modules/{workflow → version-control}/agent-tools/__tests__/change-request-read-shape.test.ts +0 -0
  891. /package/src/modules/{workflow → version-control}/agent-tools/change-request-read-shape.ts +0 -0
  892. /package/src/modules/{workflow → version-control}/agent-tools/change-request-summary.ts +0 -0
  893. /package/src/modules/{workflow/review-workflow → version-control/change-request-review}/approval-lock.ts +0 -0
  894. /package/src/modules/{workflow → version-control}/git/__tests__/branchAuthor.test.ts +0 -0
  895. /package/src/modules/{workflow → version-control}/git/__tests__/change-request-link.test.ts +0 -0
  896. /package/src/modules/{workflow → version-control}/git/__tests__/git-version.failure.test.ts +0 -0
  897. /package/src/modules/{workflow → version-control}/git/__tests__/git-version.test.ts +0 -0
  898. /package/src/modules/{workflow → version-control}/git/__tests__/node-git-runner.test.ts +0 -0
  899. /package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.getPrDetail.test.ts +0 -0
  900. /package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.placeholder.test.ts +0 -0
  901. /package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.viewer-can-cancel.test.ts +0 -0
  902. /package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.viewer-can-delete.test.ts +0 -0
  903. /package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.viewer-can-update.test.ts +0 -0
  904. /package/src/modules/{workflow → version-control}/git/change-request-link.ts +0 -0
  905. /package/src/modules/{workflow → version-control}/git/git-version.ts +0 -0
  906. /package/src/modules/{workflow → version-control}/git/merge-commit.ts +0 -0
  907. /package/src/modules/{workflow → version-control}/recovery-bot.ts +0 -0
  908. /package/src/modules/{workflow → version-control}/sanitize-error.ts +0 -0
@@ -7,18 +7,16 @@ import { tmpdir } from 'node:os';
7
7
  import { join } from 'node:path';
8
8
  import type { CallTemplate } from '@utcp/sdk';
9
9
  import { McpService } from '../mcp.service.js';
10
- import { SpillStore } from '../../workspace/spill-store.js';
11
- import { createManualRoutes } from '../../tool-registry/manual.routes.js';
12
- import { ToolRegistry } from '../../tool-registry/tool-registry.js';
13
- import { toolDef } from '../../tool-helpers/tool-def.js';
10
+ import { SpillStore } from '../../workspace/index.js';
11
+ import { createManualRoutes, ToolRegistry, GUIDE_FIRST_SENTENCE } from '../../tool-registry/index.js';
12
+ import { toolDef } from '../../tool-helpers/index.js';
13
+ import type { AgentEventInput, IAgentEventRecorder } from '../../audit/index.js';
14
14
  import { DEFAULT_KB_LAYOUT } from '@bevel-software/platform-shared';
15
15
  import { TOOL_PREFIX_LINE, platformInstructions } from '../../agent-instructions/index.js';
16
- import { GUIDE_FIRST_SENTENCE } from '../../tool-registry/guide-first.js';
17
16
  import { splitCallLine } from '@bevel-software/platform-mcp-core';
18
- import type { AgentEventInput, IAgentEventRecorder } from '../../audit/audit.contract.js';
19
17
 
20
18
  /** The platform-owned part of the handshake text: the header plus the shared file rules. */
21
- const PLATFORM = platformInstructions(DEFAULT_KB_LAYOUT);
19
+ const PLATFORM = platformInstructions(DEFAULT_KB_LAYOUT, '');
22
20
 
23
21
  /**
24
22
  * End-to-end proxy test: a real express app serving the registry-driven tool
@@ -56,6 +54,10 @@ async function setup(deps?: {
56
54
  auditRecorder?: IAgentEventRecorder;
57
55
  /** The agent connection an OAuth caller arrived through (with `tokenId: null`). */
58
56
  connectionId?: string | null;
57
+ /** The agent the credential connects as; absent = Everything. */
58
+ agentPath?: string | null;
59
+ /** Released skills listed beside `rfi` — listed only: `get_skill` answers not-found for them. */
60
+ listedOnly?: { name: string; description: string; path: string }[];
59
61
  }) {
60
62
  skillRequests = [];
61
63
  const registry = new ToolRegistry();
@@ -117,7 +119,7 @@ async function setup(deps?: {
117
119
  app.post('/api/agent/tools/list_skills', (req, res) => {
118
120
  const b = (req.body ?? {}) as Record<string, unknown>;
119
121
  skillRequests.push({ tool: 'list_skills', body: b });
120
- const released = [{ name: 'rfi', description: 'RFI answers', path: 'Plugins/Sales/rfi' }];
122
+ const released = [{ name: 'rfi', description: 'RFI answers', path: 'Plugins/Sales/rfi' }, ...(deps?.listedOnly ?? [])];
121
123
  res.json({
122
124
  skills:
123
125
  typeof b.branch === 'string'
@@ -194,6 +196,10 @@ async function setup(deps?: {
194
196
  httpServer = await new Promise<HttpServer>((resolve) => {
195
197
  const s = app.listen(0, () => resolve(s));
196
198
  });
199
+ // Every server a test opens is closed after it, not only the last: a test
200
+ // that sets up twice would otherwise leave the first one listening.
201
+ const opened = httpServer;
202
+ cleanups.push(() => new Promise<void>((r) => opened.close(() => r())));
197
203
  const port = (httpServer.address() as { port: number }).port;
198
204
  loopbackBase = `http://127.0.0.1:${port}`;
199
205
 
@@ -215,7 +221,7 @@ async function setup(deps?: {
215
221
  );
216
222
  lastService = mcp;
217
223
  const tokenId = deps?.tokenId === undefined ? 'tok-1' : deps.tokenId;
218
- return connectClient(mcp, tokenId, deps?.connectionId ?? null);
224
+ return connectClient(mcp, tokenId, deps?.connectionId ?? null, deps?.agentPath ?? null);
219
225
  }
220
226
 
221
227
  /** The service `setup` built last — for a test that needs a SECOND request against the same service. */
@@ -228,9 +234,14 @@ let lastService: McpService | undefined;
228
234
  * The initialize message is passed so the server carries instructions,
229
235
  * exactly as the route's initialize request would.
230
236
  */
231
- async function connectClient(mcp: McpService, tokenId: string | null, connectionId: string | null = null): Promise<Client> {
237
+ async function connectClient(
238
+ mcp: McpService,
239
+ tokenId: string | null,
240
+ connectionId: string | null = null,
241
+ agentPath: string | null = null,
242
+ ): Promise<Client> {
232
243
  const server = await mcp.createRequestServer(
233
- { userId: 'user-A', tokenId, connectionId, bearer: 'bevel_testkey' },
244
+ { userId: 'user-A', tokenId, connectionId, agentPath, bearer: 'bevel_testkey' },
234
245
  { jsonrpc: '2.0', id: 0, method: 'initialize', params: { protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: 'test-client', version: '0.0.0' } } },
235
246
  );
236
247
 
@@ -356,12 +367,14 @@ describe('McpService — per-user credential pre-check', () => {
356
367
  keys.map((key) => ({ key, adminConfigured: false, userConfigured, userAuthorized, grantedScopes })),
357
368
  });
358
369
  const manualsWithUserVar = {
370
+ sharedSignInKeysForManual: async () => [],
359
371
  userScopedKeysForManual: async (manual: string) =>
360
372
  manual === 'KNOWLEDGE_BASE'
361
373
  ? [{ key: 'KNOWLEDGE_BASE_API_KEY', name: 'API_KEY', label: 'Your API key', oauth: false }]
362
374
  : [],
363
375
  };
364
376
  const manualsWithOAuthVar = {
377
+ sharedSignInKeysForManual: async () => [],
365
378
  userScopedKeysForManual: async (manual: string) =>
366
379
  manual === 'KNOWLEDGE_BASE'
367
380
  ? [{ key: 'KNOWLEDGE_BASE_GOOGLE', name: 'GOOGLE', label: 'Google', oauth: true }]
@@ -369,6 +382,7 @@ describe('McpService — per-user credential pre-check', () => {
369
382
  };
370
383
  // An OAuth var that requires two scopes — for the scope-coverage cases.
371
384
  const manualsWithScopedOAuthVar = {
385
+ sharedSignInKeysForManual: async () => [],
372
386
  userScopedKeysForManual: async (manual: string) =>
373
387
  manual === 'KNOWLEDGE_BASE'
374
388
  ? [
@@ -383,9 +397,46 @@ describe('McpService — per-user credential pre-check', () => {
383
397
  : [],
384
398
  };
385
399
  const manualsNoUserVar = {
400
+ sharedSignInKeysForManual: async () => [],
386
401
  userScopedKeysForManual: async () =>
387
402
  [] as { key: string; name: string; label: string | null; oauth: boolean }[],
388
403
  };
404
+ // A WORKSPACE connection (a managed connector an owner connects once for
405
+ // everyone): no personal variable, one shared sign-in.
406
+ const manualsWithSharedSignIn = {
407
+ sharedSignInKeysForManual: async (manual: string) =>
408
+ manual === 'KNOWLEDGE_BASE'
409
+ ? [{ key: 'KNOWLEDGE_BASE_ACCESS_TOKEN', name: 'ACCESS_TOKEN', label: 'HubSpot sign-in', oauthScopes: ['crm.objects.contacts.read'] }]
410
+ : [],
411
+ userScopedKeysForManual: async () => [] as { key: string; name: string; label: string | null; oauth: boolean }[],
412
+ };
413
+ const sharedVault = (adminAuthorized: boolean, adminGrantedScopes?: string) => ({
414
+ statusFor: async (_userId: string, keys: string[]) =>
415
+ keys.map((key) => ({ key, adminConfigured: adminAuthorized, userConfigured: false, adminAuthorized, adminGrantedScopes })),
416
+ });
417
+
418
+ describe('a workspace connection nobody has made', () => {
419
+ it('refuses the call with words that say an owner connects it, without resetting the caller’s own grant', async () => {
420
+ const revokeOAuthAccess = vi.fn(async () => undefined);
421
+ const client = await setup({ secretsVault: sharedVault(false), toolManuals: manualsWithSharedSignIn, tokenId: null, revokeOAuthAccess });
422
+ const res = await client.callTool({ name: 'ask', arguments: { body: { prompt: 'hello' } } });
423
+ expect(res.isError).toBe(true);
424
+ const text = (res.content as Array<{ text: string }>)[0].text;
425
+ expect(text).toMatch(/HubSpot sign-in \(a tool owner connects this for the workspace\)/);
426
+ expect(text).toMatch(/\/connect/);
427
+ expect(revokeOAuthAccess).not.toHaveBeenCalled();
428
+ });
429
+
430
+ it('is hidden from a connection-key listing until an owner connects it with a covering token', async () => {
431
+ const names = async (c: Awaited<ReturnType<typeof setup>>) => (await c.listTools()).tools.map((t) => t.name).sort();
432
+ const unconnected = await setup({ secretsVault: sharedVault(false), toolManuals: manualsWithSharedSignIn });
433
+ expect(await names(unconnected)).toEqual(['call_tool_chain', 'list_tools', 'tools_info']);
434
+ const underScoped = await setup({ secretsVault: sharedVault(true, 'oauth'), toolManuals: manualsWithSharedSignIn });
435
+ expect(await names(underScoped)).toEqual(['call_tool_chain', 'list_tools', 'tools_info']);
436
+ const connected = await setup({ secretsVault: sharedVault(true, 'oauth crm.objects.contacts.read'), toolManuals: manualsWithSharedSignIn });
437
+ expect(await names(connected)).toEqual(['ask', 'boom', 'call_tool_chain', 'list_tools', 'refy', 'tools_info']);
438
+ });
439
+ });
389
440
 
390
441
  it('gates a tool whose personal credential is unset — returns the setup link, not the tool', async () => {
391
442
  const client = await setup({ secretsVault: vault(false), toolManuals: manualsWithUserVar });
@@ -657,7 +708,7 @@ describe('McpService — agent instructions', () => {
657
708
  // The listing filter registers only ready tools; the fake manual catalog
658
709
  // says every tool is ready, so the four survive it and carry the prefix.
659
710
  const vault = { statusFor: async (_u: string, keys: string[]) => keys.map((key) => ({ key, userConfigured: true })) };
660
- const manuals = { userScopedKeysForManual: async () => [{ key: 'KNOWLEDGE_BASE_X', name: 'X', oauth: false }] };
711
+ const manuals = { sharedSignInKeysForManual: async () => [], userScopedKeysForManual: async () => [{ key: 'KNOWLEDGE_BASE_X', name: 'X', oauth: false }] };
661
712
  const client = await setup({
662
713
  readAgentPreamble: async () => 'Acme.',
663
714
  extraTools: KB_TOOLS,
@@ -886,7 +937,7 @@ describe('McpService — the Audit log records what an agent calls', () => {
886
937
  it('serves prompts from the default branch only, never a draft', async () => {
887
938
  const client = await setup();
888
939
  const { prompts } = await client.listPrompts();
889
- expect(prompts.map((p) => p.name)).toEqual(['rfi']);
940
+ expect(prompts.map((p) => p.name)).toEqual(['onboard', 'rfi']);
890
941
 
891
942
  const got = await client.getPrompt({ name: 'rfi' });
892
943
  const text = got.messages[0].content.text as string;
@@ -899,10 +950,37 @@ describe('McpService — the Audit log records what an agent calls', () => {
899
950
  expect(skillRequests.every((r) => r.body.branch === undefined)).toBe(true);
900
951
  });
901
952
 
953
+ it('offers the platform onboard prompt, pointing at the guide section, while no skill takes its name', async () => {
954
+ const client = await setup();
955
+ const got = await client.getPrompt({ name: 'onboard' });
956
+ expect(got.messages[0].content.text).toContain('get_agent_guide({ body: { section: "onboarding" } })');
957
+ });
958
+
959
+ it("serves a workspace's own onboard skill in the platform prompt's place, and never the platform text when reading it fails", async () => {
960
+ const client = await setup({ listedOnly: [{ name: 'onboard', description: 'Our own onboarding', path: 'Plugins/People/onboard' }] });
961
+ const { prompts } = await client.listPrompts();
962
+ // The workspace's skill, in the catalog's own order; the platform's prompt is not added beside it.
963
+ expect(prompts.map((p) => [p.name, p.description])).toEqual([
964
+ ['rfi', 'RFI answers'],
965
+ ['onboard', 'Our own onboarding'],
966
+ ]);
967
+ // The skill is listed but its read answers not-found (the harness knows
968
+ // only `rfi`): the same failed read any prompt gets, never the platform's
969
+ // onboarding text under the workspace's name.
970
+ await expect(client.getPrompt({ name: 'onboard' })).rejects.toThrow(/Unknown skill "onboard"/);
971
+ });
972
+
973
+ it('serves a connection narrowed to an agent its skills and nothing beside them', async () => {
974
+ const client = await setup({ agentPath: 'Agents/support.agent' });
975
+ expect((await client.listPrompts()).prompts.map((p) => p.name)).toEqual(['rfi']);
976
+ await expect(client.getPrompt({ name: 'onboard' })).rejects.toThrow(/Unknown skill "onboard"/);
977
+ });
978
+
902
979
  it('records a call refused for a missing sign-in as denied, without running the tool', async () => {
903
980
  const recorder = spyRecorder();
904
981
  const vault = { statusFor: async (_u: string, keys: string[]) => keys.map((key) => ({ key, adminConfigured: false, userConfigured: false })) };
905
982
  const manuals = {
983
+ sharedSignInKeysForManual: async () => [],
906
984
  userScopedKeysForManual: async (manual: string) =>
907
985
  manual === 'KNOWLEDGE_BASE' ? [{ key: 'KNOWLEDGE_BASE_API_KEY', name: 'API_KEY', label: 'Your API key', oauth: false }] : [],
908
986
  };
@@ -0,0 +1,194 @@
1
+ import { createServer } from 'node:http';
2
+ import type { AddressInfo } from 'node:net';
3
+ import { cp, mkdtemp, rm, writeFile } from 'node:fs/promises';
4
+ import { execFile } from 'node:child_process';
5
+ import { promisify } from 'node:util';
6
+ import { randomBytes } from 'node:crypto';
7
+ import { tmpdir } from 'node:os';
8
+ import { join } from 'node:path';
9
+ import { afterAll, afterEach, describe, expect, it } from 'vitest';
10
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
11
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
12
+ import { createCoreServices, createCoreServer, stopCore, defaultKbTemplateDir, defaultStarterPacksDir, type TenantConfig } from '../../../index.js';
13
+ import { PG_ADMIN_URL, PG_TEST_TIMEOUT, scratchDatabaseUrl, dropScratchDatabases } from '../../../__tests__/pg-scratch.js';
14
+ import { startFakeDownstreamMcpServer, type FakeDownstreamMcpServer } from './fake-downstream-mcp-server.js';
15
+
16
+ /**
17
+ * A client of the public server composition, over real Streamable HTTP and a
18
+ * scratch Postgres. The catalog source is supplied through its public overlay
19
+ * hook; tool registration, manuals, hints, authentication and MCP routing are
20
+ * the production composition. Admin edits go through the public HTTP API too.
21
+ */
22
+ const stops: Array<() => Promise<void>> = [];
23
+ afterEach(async () => {
24
+ for (const stop of stops.splice(0).reverse()) await stop();
25
+ }, PG_TEST_TIMEOUT);
26
+ afterAll(dropScratchDatabases, PG_TEST_TIMEOUT);
27
+
28
+ async function startPlatform(opts: { downstream?: FakeDownstreamMcpServer; catalogRevision?: boolean } = {}) {
29
+ const root = await mkdtemp(join(tmpdir(), 'hosted-mcp-hints-'));
30
+ stops.push(() => rm(root, { recursive: true, force: true }));
31
+ const repository = join(root, 'repository');
32
+ await cp(defaultKbTemplateDir(), repository, { recursive: true });
33
+ await writeFile(join(repository, 'roles.yaml'), 'roles:\n Admin:\n - admin@example.com\n');
34
+ const git = (args: string[]) => promisify(execFile)('git', args, { cwd: repository });
35
+ await git(['init', '-q', '-b', 'main']);
36
+ await git(['add', '.']);
37
+ await git(['-c', 'user.name=Test', '-c', 'user.email=admin@example.com', 'commit', '-qm', 'Seed test knowledge base']);
38
+ // Bind before constructing the graph so its loopback URL has the real port.
39
+ const server = createServer();
40
+ await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve));
41
+ stops.push(async () => {
42
+ server.closeAllConnections();
43
+ await new Promise<void>((resolve, reject) => server.close((error) => error ? reject(error) : resolve()));
44
+ });
45
+ const port = (server.address() as AddressInfo).port;
46
+ const baseUrl = `http://127.0.0.1:${port}`;
47
+ const config: TenantConfig = {
48
+ port, databaseUrl: await scratchDatabaseUrl('hexis_mcp_hints'), dbSchema: 'public', nodeEnv: 'test',
49
+ tenantId: 'bevel', externalApiKeyPrefix: 'bevel_', internalTokenPrefix: 'bevel-internal_',
50
+ uploadTokenPrefix: 'bevel-upload_', mcpOAuthTokenPrefix: 'bevel-mcp_',
51
+ workspacesRoot: join(root, 'workspaces'), backupsRoot: join(root, 'backups'),
52
+ spillRoot: join(root, 'spills'), agentUploadsRoot: join(root, 'uploads'), docExtractCacheRoot: join(root, 'extracts'),
53
+ jwtSecret: 'hosted-hints-test-secret', adminEmail: 'admin@example.com', adminPassword: 'test-password',
54
+ oidcIssuerUrl: '', oidcClientId: '', oidcClientSecret: '', oidcScopes: 'openid', oidcProviderLabel: 'SSO',
55
+ kbRepoUrl: repository, kbDirName: 'knowledge-base', gitUsername: '', gitToken: '',
56
+ kbTemplateDir: defaultKbTemplateDir(), starterPacksDir: defaultStarterPacksDir(),
57
+ updateCheckEnabled: false, loginPasswordEnabled: true, allowedEmailDomains: [],
58
+ secretsEncKey: randomBytes(32).toString('base64'), internalTokenSecret: 'hosted-hints-internal-secret',
59
+ embedSharedSecret: '', trustProxy: '', gitTimeoutMs: 30_000,
60
+ publicBackendUrl: baseUrl, publicFrontendUrl: baseUrl, configuredPublicFrontendUrl: baseUrl,
61
+ settingsEnv: { KB_REPO_URL: repository, DEFAULT_BRANCH: 'main', PROTECTED_BRANCHES: 'main' },
62
+ };
63
+ const core = await createCoreServices(config, { mirrorSharedBindings: false });
64
+ stops.push(() => stopCore(core));
65
+ const app = await createCoreServer(core, {
66
+ preAuth(app) {
67
+ app.get('/api/agent/all-tools', core.manualAuthMiddleware, (_req, res) => {
68
+ res.json({ manuals: [
69
+ { name: 'KNOWLEDGE_BASE', call_template_type: 'http', http_method: 'GET',
70
+ url: '${API_URL}/api/agent/utcp', content_type: 'application/json',
71
+ headers: { Authorization: 'Bearer ${CONNECTION_KEY}' } },
72
+ ...(opts.downstream ? [{ name: 'notion', call_template_type: 'mcp',
73
+ config: { mcpServers: { srv: { transport: 'http', url: opts.downstream.url } } } }] : []),
74
+ ] });
75
+ });
76
+ app.get('/api/agent/catalog-revision', core.manualAuthMiddleware, (_req, res) => {
77
+ if (opts.catalogRevision) res.json({ revision: 'unchanged-catalog' });
78
+ else res.sendStatus(404);
79
+ });
80
+ },
81
+ }, { boot: false });
82
+ server.on('request', app);
83
+ const login = await fetch(`${baseUrl}/api/auth/login`, {
84
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
85
+ body: JSON.stringify({ email: config.adminEmail, password: config.adminPassword }),
86
+ });
87
+ expect(login.status).toBe(200);
88
+ const { token, user } = await login.json() as { token: string; user: { id: string } };
89
+ const { plaintext: key } = await core.externalApiKeyService.mint(user.id, 'metadata-test');
90
+ const setHint = async (name: string, readOnly: boolean | null) => {
91
+ const response = await fetch(`${baseUrl}/api/tool-hints/${name}`, {
92
+ method: 'PUT', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
93
+ body: JSON.stringify({ readOnly }),
94
+ });
95
+ expect(response.status).toBe(200);
96
+ };
97
+ return { baseUrl, key, setHint };
98
+ }
99
+
100
+ async function connect(baseUrl: string, key: string): Promise<Client> {
101
+ const transport = new StreamableHTTPClientTransport(new URL(`${baseUrl}/api/mcp`), {
102
+ requestInit: { headers: { Authorization: `Bearer ${key}` } },
103
+ });
104
+ const client = new Client({ name: 'hint-client', version: '0.0.0' }, { capabilities: {} });
105
+ await client.connect(transport);
106
+ stops.push(() => client.close());
107
+ return client;
108
+ }
109
+
110
+ const annotationsOf = async (client: Client) =>
111
+ Object.fromEntries((await client.listTools()).tools.map((t) => [t.name, t.annotations]));
112
+
113
+ describe.skipIf(!PG_ADMIN_URL)('the hosted MCP endpoint lists the read-only hint', () => {
114
+ it('on every platform tool and every meta-tool, and no other annotation', async () => {
115
+ const { baseUrl, key } = await startPlatform();
116
+ const tools = (await (await connect(baseUrl, key)).listTools()).tools;
117
+ for (const tool of tools) {
118
+ expect(tool.title).toEqual(expect.any(String));
119
+ expect(tool.title!.trim()).not.toBe('');
120
+ expect(tool.annotations).toEqual({ readOnlyHint: expect.any(Boolean) });
121
+ }
122
+ expect(Object.fromEntries(tools.map((t) => [t.name, t.title]))).toMatchObject({
123
+ list_tools: 'List tools',
124
+ tools_info: 'Tools info',
125
+ call_tool_chain: 'Call tool chain',
126
+ read_file: 'Read file',
127
+ write_file: 'Write file',
128
+ });
129
+ expect(Object.fromEntries(tools.map((t) => [t.name, t.annotations]))).toMatchObject({
130
+ list_tools: { readOnlyHint: true },
131
+ tools_info: { readOnlyHint: true },
132
+ call_tool_chain: { readOnlyHint: false },
133
+ read_file: { readOnlyHint: true },
134
+ write_file: { readOnlyHint: false },
135
+ });
136
+ });
137
+
138
+ it("lists an admin's change on the client's NEXT tools/list, with no reconnect, and a reset undoes it", async () => {
139
+ const { baseUrl, key, setHint } = await startPlatform();
140
+ const client = await connect(baseUrl, key);
141
+ expect((await annotationsOf(client)).read_file).toEqual({ readOnlyHint: true });
142
+
143
+ await setHint('read_file', false);
144
+ await setHint('write_file', true);
145
+ await setHint('call_tool_chain', true);
146
+ let listed = await annotationsOf(client);
147
+ expect(listed.read_file).toEqual({ readOnlyHint: false });
148
+ expect(listed.write_file).toEqual({ readOnlyHint: true });
149
+ expect(listed.call_tool_chain).toEqual({ readOnlyHint: true });
150
+
151
+ for (const name of ['read_file', 'write_file', 'call_tool_chain']) await setHint(name, null);
152
+ listed = await annotationsOf(client);
153
+ expect(listed.read_file).toEqual({ readOnlyHint: true });
154
+ expect(listed.write_file).toEqual({ readOnlyHint: false });
155
+ expect(listed.call_tool_chain).toEqual({ readOnlyHint: false });
156
+ });
157
+
158
+ it("lists an admin's change and its reset on the next tools/list when the tool surface is cached", async () => {
159
+ const { baseUrl, key, setHint } = await startPlatform({ catalogRevision: true });
160
+ const client = await connect(baseUrl, key);
161
+ expect((await annotationsOf(client)).read_file).toEqual({ readOnlyHint: true });
162
+
163
+ await setHint('read_file', false);
164
+ await setHint('write_file', true);
165
+ let listed = await annotationsOf(client);
166
+ expect(listed.read_file).toEqual({ readOnlyHint: false });
167
+ expect(listed.write_file).toEqual({ readOnlyHint: true });
168
+
169
+ for (const name of ['read_file', 'write_file']) await setHint(name, null);
170
+ listed = await annotationsOf(client);
171
+ expect(listed.read_file).toEqual({ readOnlyHint: true });
172
+ expect(listed.write_file).toEqual({ readOnlyHint: false });
173
+ });
174
+
175
+ it('does not keep an override in the cached surface: one set before the surface is built is undone by its reset', async () => {
176
+ const { baseUrl, key, setHint } = await startPlatform({ catalogRevision: true });
177
+ await setHint('read_file', false);
178
+ const client = await connect(baseUrl, key);
179
+ expect((await annotationsOf(client)).read_file).toEqual({ readOnlyHint: false });
180
+
181
+ await setHint('read_file', null);
182
+ expect((await annotationsOf(client)).read_file).toEqual({ readOnlyHint: true });
183
+ });
184
+
185
+ it('lists a tool from a plugin MCP server with conservative effects', async () => {
186
+ const downstream = await startFakeDownstreamMcpServer();
187
+ stops.push(() => downstream.stop());
188
+ const { baseUrl, key } = await startPlatform({ downstream });
189
+ const tools = (await (await connect(baseUrl, key)).listTools()).tools;
190
+ const proxied = tools.find((t) => t.name.endsWith('echo'));
191
+ expect(proxied).toBeDefined();
192
+ expect(proxied?.annotations).toEqual({ readOnlyHint: false });
193
+ });
194
+ });
@@ -42,6 +42,8 @@ import {
42
42
  retiredToolMessage,
43
43
  needsAuthorizationResult,
44
44
  skillPromptText,
45
+ ONBOARD_PROMPT,
46
+ promptsForSkills,
45
47
  toListedResource,
46
48
  toReadResourceResult,
47
49
  type McpAppManifest,
@@ -50,7 +52,7 @@ import {
50
52
  type LoadedSkill,
51
53
  } from '@bevel-software/platform-mcp-core';
52
54
  import type { KbLayout } from '@bevel-software/platform-shared';
53
- import { bevelSecretsLoaderConfig, type ForcedRefreshOutcome, type ISecretsVaultService, scopesCovered } from '../secrets-vault/index.js';
55
+ import { bevelSecretsLoaderConfig, type ForcedRefreshOutcome, type ISecretsVaultService, scopesCovered, userSecretGap } from '../secrets-vault/index.js';
54
56
  import { EXTERNAL_KB_MANUAL_NAME } from '../tool-manuals/index.js';
55
57
  import type { IToolManualService } from '../tool-manuals/index.js';
56
58
  import type { SpillStore } from '../workspace/index.js';
@@ -109,12 +111,19 @@ export interface McpProxyOptions {
109
111
  */
110
112
  readAgentPreamble?: AgentPreambleReader;
111
113
  /**
112
- * The layout in effect, read per request: the shared file rules name the
113
- * guide by the name a deployment saved for it, and the setup save applies
114
- * a layout without a restart. A GETTER, so nothing snapshots the
115
- * pre-setup default. Absent, the rules name `AGENTS.md`.
114
+ * The layout in effect, read per request: the shared file rules spell the
115
+ * root folders and platform files by the names a deployment saved, and the
116
+ * setup save applies a layout without a restart. A GETTER, so nothing
117
+ * snapshots the pre-setup default. Absent, the rules use the default
118
+ * layout. The guide is `AGENTS.md` either way.
116
119
  */
117
120
  kbLayout?: () => KbLayout;
121
+ /**
122
+ * The default branch in effect, read per request: the shared file rules
123
+ * name it as the branch people read. A GETTER for the same reason as the
124
+ * layout. Absent, the rules name no branch.
125
+ */
126
+ defaultBranch?: () => string;
118
127
  /** Bounds of the downstream (`mcp.json`) connection pool; defaults are 4h idle / 5000 entries. */
119
128
  downstreamPool?: Pick<DownstreamPoolOptions<unknown>, 'idleTtlMs' | 'maxEntries' | 'now'>;
120
129
  /**
@@ -378,7 +387,7 @@ export class McpService {
378
387
  private readonly manualFailures = new ManualFailureMemo();
379
388
  private readonly surfaceLog = new SurfaceLogThrottle();
380
389
  // One forced token refresh per (user, manual) per minute — see downstream-token-refresh.
381
- private readonly tokenRefreshes: DownstreamRefreshGuard<ForcedRefreshOutcome>;
390
+ private readonly tokenRefreshes: DownstreamRefreshGuard<ForcedRefreshOutcome | 'rejected-shared'>;
382
391
  /**
383
392
  * The tools each pooled manual last advertised, by manual definition. A
384
393
  * downstream can only be asked what its tools are over a connection, and a
@@ -859,17 +868,32 @@ export class McpService {
859
868
  // loopback with the caller's key — so the default-branch catalog, access
860
869
  // filtering, and progressive disclosure all live ONCE behind that REST
861
870
  // surface, never duplicated here. Neither handler needs the tool catalog.
871
+ // The one prompt that is not a skill is the platform's `onboard`, offered
872
+ // only on a connection not narrowed to an agent, and only while no skill
873
+ // takes its name (see `promptsForSkills`).
874
+ const offerOnboard = agentPath === null;
862
875
  server.setRequestHandler(ListPromptsRequestSchema, async () => {
863
876
  const skills = await this.fetchSkillList(loopbackBearer);
864
- const prompts: Prompt[] = skills.map((s) => ({
865
- name: s.name,
866
- description: s.description,
867
- arguments: [],
868
- }));
877
+ const prompts: Prompt[] = promptsForSkills(skills, offerOnboard);
869
878
  return { prompts };
870
879
  });
871
880
 
872
881
  server.setRequestHandler(GetPromptRequestSchema, async (request): Promise<GetPromptResult> => {
882
+ // The platform's own prompt is served exactly when `prompts/list`
883
+ // offered it: the connection is not narrowed and no released skill
884
+ // takes the name — judged on the skill LIST, the same answer the
885
+ // listing used, never on a read that failed. A workspace's own
886
+ // `onboard` skill is then read like any other prompt, and a read that
887
+ // fails is a failed read, not a reason to serve the platform's text.
888
+ if (offerOnboard && request.params.name === ONBOARD_PROMPT.name) {
889
+ const released = await this.fetchSkillList(loopbackBearer);
890
+ if (!released.some((s) => s.name === ONBOARD_PROMPT.name)) {
891
+ return {
892
+ description: ONBOARD_PROMPT.description,
893
+ messages: [{ role: 'user', content: { type: 'text', text: ONBOARD_PROMPT.text } }],
894
+ };
895
+ }
896
+ }
873
897
  const started = performance.now();
874
898
  const skill = await this.fetchSkill(loopbackBearer, request.params.name);
875
899
  // A prompt IS a skill read — the same event `get_skill` produces.
@@ -1059,13 +1083,14 @@ export class McpService {
1059
1083
  */
1060
1084
  private async composeAgentInstructions(): Promise<ComposedAgentInstructions> {
1061
1085
  const layout = this.opts.kbLayout?.();
1086
+ const defaultBranch = this.opts.defaultBranch?.();
1062
1087
  const read = this.opts.readAgentPreamble;
1063
- if (!read) return composeAgentInstructions(null, layout);
1088
+ if (!read) return composeAgentInstructions(null, layout, defaultBranch);
1064
1089
  try {
1065
- return composeAgentInstructions(await read(), layout);
1090
+ return composeAgentInstructions(await read(), layout, defaultBranch);
1066
1091
  } catch (err) {
1067
1092
  log.warn('could not read mcp-description.md; this request gets the platform text alone:', { err });
1068
- return composeAgentInstructions(null, layout);
1093
+ return composeAgentInstructions(null, layout, defaultBranch);
1069
1094
  }
1070
1095
  }
1071
1096
 
@@ -1559,7 +1584,7 @@ export class McpService {
1559
1584
  this.downstream.evictWhere((k) => k === poolKey);
1560
1585
  return { retry: true };
1561
1586
  }
1562
- if (outcome === 'rejected') {
1587
+ if (outcome === 'rejected' || outcome === 'rejected-shared') {
1563
1588
  // The connection was dialed with a grant that no longer exists; the
1564
1589
  // vault's mutation signal drops it too, this keeps the next request
1565
1590
  // honest whether or not that is wired.
@@ -1568,8 +1593,11 @@ export class McpService {
1568
1593
  retry: false,
1569
1594
  credentialTransient: false,
1570
1595
  error: new Error(
1571
- `Your sign-in for "${manualName}" was rejected and has been disconnected. ` +
1572
- `Re-authorize it on ${this.opts.publicFrontendUrl}/connect, then run the tool again.`,
1596
+ outcome === 'rejected-shared'
1597
+ ? `The workspace connection for "${manualName}" was rejected by the provider and has been disconnected. ` +
1598
+ `A tool owner has to reconnect it on ${this.opts.publicFrontendUrl}/connect; then run the tool again.`
1599
+ : `Your sign-in for "${manualName}" was rejected and has been disconnected. ` +
1600
+ `Re-authorize it on ${this.opts.publicFrontendUrl}/connect, then run the tool again.`,
1573
1601
  ),
1574
1602
  };
1575
1603
  }
@@ -1596,12 +1624,21 @@ export class McpService {
1596
1624
  private async refreshDownstreamToken(
1597
1625
  userId: string,
1598
1626
  manualName: string,
1599
- ): Promise<ForcedRefreshOutcome | 'guarded' | undefined> {
1627
+ ): Promise<ForcedRefreshOutcome | 'rejected-shared' | 'guarded' | undefined> {
1600
1628
  const vault = this.secretsVault;
1601
1629
  if (!vault || !this.toolManuals || !manualName) return undefined;
1602
1630
  let keys: string[];
1631
+ let sharedKeys = new Set<string>();
1603
1632
  try {
1604
- keys = (await this.toolManuals.userScopedKeysForManual(manualName)).filter((v) => v.oauth).map((v) => v.key);
1633
+ // Every sign-in the manual declares: the caller's own, and a workspace
1634
+ // connection every caller resolves (the vault's forceRefresh reads the
1635
+ // shared row for an admin-scoped key, as resolve does).
1636
+ const [own, shared] = await Promise.all([
1637
+ this.toolManuals.userScopedKeysForManual(manualName),
1638
+ this.toolManuals.sharedSignInKeysForManual(manualName),
1639
+ ]);
1640
+ keys = [...own.filter((v) => v.oauth).map((v) => v.key), ...shared.map((v) => v.key)];
1641
+ sharedKeys = new Set(shared.map((v) => v.key));
1605
1642
  } catch (err) {
1606
1643
  // The error's own message is caller-controlled as well (it quotes the
1607
1644
  // manual, and may quote a provider's reply), and a raw Error handed to
@@ -1616,12 +1653,20 @@ export class McpService {
1616
1653
  if (keys.length === 0) return undefined;
1617
1654
  const attempt = this.tokenRefreshes.run(`${userId}${POOL_KEY_SEPARATOR}${manualName}`, async () => {
1618
1655
  const outcomes: ForcedRefreshOutcome[] = [];
1656
+ // A dead WORKSPACE connection is told apart from a dead personal one:
1657
+ // the caller cannot repair it, a writer of the tool can, and the words
1658
+ // the caller gets have to say so.
1659
+ let rejectedShared = false;
1619
1660
  for (const key of keys) {
1620
1661
  // A vault fault is not a verdict on the grant: keep the token, try later.
1621
- outcomes.push(await vault.forceRefresh(userId, key).catch((): ForcedRefreshOutcome => 'transient'));
1662
+ const result = await vault.forceRefresh(userId, key).catch((): ForcedRefreshOutcome => 'transient');
1663
+ if (result === 'rejected' && sharedKeys.has(key)) rejectedShared = true;
1664
+ outcomes.push(result);
1622
1665
  }
1623
- const outcome: ForcedRefreshOutcome = outcomes.includes('rejected')
1624
- ? 'rejected'
1666
+ const outcome: ForcedRefreshOutcome | 'rejected-shared' = outcomes.includes('rejected')
1667
+ ? rejectedShared
1668
+ ? 'rejected-shared'
1669
+ : 'rejected'
1625
1670
  : outcomes.includes('transient')
1626
1671
  ? 'transient'
1627
1672
  : outcomes.includes('refreshed')
@@ -1681,51 +1726,37 @@ export class McpService {
1681
1726
  manualName: string,
1682
1727
  ): Promise<{ name: string; label?: string | null; brokenSignIn: boolean }[]> {
1683
1728
  if (!this.secretsVault || !this.toolManuals || !manualName) return [];
1684
- const userVars = await this.toolManuals.userScopedKeysForManual(manualName);
1685
- if (userVars.length === 0) return [];
1686
- const status = await this.secretsVault.statusFor(
1687
- userId,
1688
- userVars.map((v) => v.key),
1689
- );
1729
+ const [userVars, sharedSignIns] = await Promise.all([
1730
+ this.toolManuals.userScopedKeysForManual(manualName),
1731
+ this.toolManuals.sharedSignInKeysForManual(manualName),
1732
+ ]);
1733
+ if (userVars.length === 0 && sharedSignIns.length === 0) return [];
1734
+ const status = await this.secretsVault.statusFor(userId, [
1735
+ ...userVars.map((v) => v.key),
1736
+ ...sharedSignIns.map((v) => v.key),
1737
+ ]);
1690
1738
  const statusMap = new Map(status.map((s) => [s.key, s]));
1691
1739
  const missing: { name: string; label?: string | null; brokenSignIn: boolean }[] = [];
1692
- for (const v of userVars) {
1740
+ // A WORKSPACE sign-in (a managed connector enabled as one shared
1741
+ // connection) is nobody's personal credential, but a tool whose one
1742
+ // connection has not been made — or no longer covers what the tool
1743
+ // declares — fails just as opaquely at the provider. Reported like a
1744
+ // personal one, with words that say whose job it is; never a "broken
1745
+ // sign-in" of the caller's, since there is nothing of theirs to reset.
1746
+ for (const v of sharedSignIns) {
1693
1747
  const st = statusMap.get(v.key);
1694
- // A sign-in the caller already HAS a row for but that isn't (or is no
1695
- // longer) usable: dead/wiped grant, abandoned consent, missing scopes.
1696
- const brokenSignIn = Boolean(v.oauth && st?.userConfigured);
1697
- if (!st?.userConfigured) {
1698
- missing.push({ name: v.name, label: v.label, brokenSignIn }); // no row at all → needs a value / sign-in
1699
- continue;
1700
- }
1701
- // A row of the OTHER kind is not this credential: a `.tool` edited from
1702
- // an OAuth sign-in to a plain key (or back) leaves the old row behind,
1703
- // and serving a token where a key is declared — or a key where a
1704
- // sign-in is — fails opaquely at the provider. Not a broken sign-in
1705
- // either: nothing to reset, the user has to set the credential up as
1706
- // the manual now declares it.
1707
- const declaredKind = v.oauth ? 'oauth' : 'static';
1708
- if (st.userKind && st.userKind !== declaredKind) {
1709
- missing.push({ name: v.name, label: v.label, brokenSignIn: false });
1710
- continue;
1711
- }
1712
- // An OAuth-backed var whose row exists but has no token yet is NOT ready —
1713
- // the user has registered but not completed sign-in. Fail closed: anything
1714
- // other than a confirmed `true` (including a non-oauth row → undefined)
1715
- // counts as not-yet-authorized.
1716
- if (v.oauth && st.userAuthorized !== true) {
1717
- missing.push({ name: v.name, label: v.label, brokenSignIn });
1718
- continue;
1719
- }
1720
- // An OAuth-backed var the user signed in for, but whose token was granted
1721
- // fewer scopes than the tool now declares, is ALSO not ready — the call would
1722
- // otherwise fail opaquely at the provider. Compare the live required scopes
1723
- // against the token's recorded granted scopes; an under-scoped (or unknown)
1724
- // token needs re-authorization.
1725
- if (v.oauth && !scopesCovered(v.oauthScopes, st.grantedScopes)) {
1726
- missing.push({ name: v.name, label: v.label, brokenSignIn });
1748
+ const connected = st?.adminAuthorized === true && scopesCovered(v.oauthScopes, st.adminGrantedScopes);
1749
+ if (!connected) {
1750
+ missing.push({ name: v.name, label: `${v.label ?? v.name} (a tool owner connects this for the workspace)`, brokenSignIn: false });
1727
1751
  }
1728
1752
  }
1753
+ for (const v of userVars) {
1754
+ // The one readiness rule `list_tool_setup` reports from (`userSecretGap`).
1755
+ // A sign-in the caller already HAS a row for but that isn't (or is no
1756
+ // longer) usable is a broken sign-in: abandoned consent, missing scopes.
1757
+ const gap = userSecretGap(v, statusMap.get(v.key));
1758
+ if (gap) missing.push({ name: v.name, label: v.label, brokenSignIn: gap === 'unauthorized' || gap === 'under-scoped' });
1759
+ }
1729
1760
  return missing;
1730
1761
  }
1731
1762