@bevel-software/platform-core-backend 0.25.2 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (733) hide show
  1. package/agent-guide/access-control.md +251 -0
  2. package/agent-guide/conventions.md +35 -0
  3. package/agent-guide/directory-structure.md +145 -0
  4. package/agent-guide/finding-things.md +7 -0
  5. package/agent-guide/html-views.md +83 -0
  6. package/agent-guide/introduction.md +27 -0
  7. package/agent-guide/new-knowledge-base.md +24 -0
  8. package/agent-guide/skills.md +47 -0
  9. package/agent-guide/tool-manuals.md +227 -0
  10. package/agent-guide/where-a-new-file-goes.md +36 -0
  11. package/dist/assets.d.ts +26 -0
  12. package/dist/assets.d.ts.map +1 -1
  13. package/dist/assets.js +35 -2
  14. package/dist/assets.js.map +1 -1
  15. package/dist/core/catalog-revision.d.ts +19 -1
  16. package/dist/core/catalog-revision.d.ts.map +1 -1
  17. package/dist/core/catalog-revision.js +14 -3
  18. package/dist/core/catalog-revision.js.map +1 -1
  19. package/dist/core/core-ports.d.ts +11 -0
  20. package/dist/core/core-ports.d.ts.map +1 -1
  21. package/dist/core/core-ports.js.map +1 -1
  22. package/dist/core/create-core-server.d.ts +5 -0
  23. package/dist/core/create-core-server.d.ts.map +1 -1
  24. package/dist/core/create-core-server.js +65 -3
  25. package/dist/core/create-core-server.js.map +1 -1
  26. package/dist/core/create-core-services.d.ts +35 -0
  27. package/dist/core/create-core-services.d.ts.map +1 -1
  28. package/dist/core/create-core-services.js +114 -12
  29. package/dist/core/create-core-services.js.map +1 -1
  30. package/dist/core/lifecycle.d.ts +16 -1
  31. package/dist/core/lifecycle.d.ts.map +1 -1
  32. package/dist/core/lifecycle.js +18 -1
  33. package/dist/core/lifecycle.js.map +1 -1
  34. package/dist/core-config.d.ts +21 -0
  35. package/dist/core-config.d.ts.map +1 -1
  36. package/dist/core-config.js +22 -1
  37. package/dist/core-config.js.map +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +2 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/modules/access/access-control.interface.d.ts +17 -0
  43. package/dist/modules/access/access-control.interface.d.ts.map +1 -1
  44. package/dist/modules/access/access-control.service.d.ts +2 -0
  45. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  46. package/dist/modules/access/access-control.service.js +27 -0
  47. package/dist/modules/access/access-control.service.js.map +1 -1
  48. package/dist/modules/access/directory-sync-bot.js +1 -1
  49. package/dist/modules/access/directory-sync-bot.js.map +1 -1
  50. package/dist/modules/agent-guide/agent-guide.d.ts +145 -0
  51. package/dist/modules/agent-guide/agent-guide.d.ts.map +1 -0
  52. package/dist/modules/agent-guide/agent-guide.js +199 -0
  53. package/dist/modules/agent-guide/agent-guide.js.map +1 -0
  54. package/dist/modules/agent-guide/agent-guide.tools.d.ts +24 -0
  55. package/dist/modules/agent-guide/agent-guide.tools.d.ts.map +1 -0
  56. package/dist/modules/agent-guide/agent-guide.tools.js +100 -0
  57. package/dist/modules/agent-guide/agent-guide.tools.js.map +1 -0
  58. package/dist/modules/agent-guide/index.d.ts +4 -0
  59. package/dist/modules/agent-guide/index.d.ts.map +1 -0
  60. package/dist/modules/agent-guide/index.js +4 -0
  61. package/dist/modules/agent-guide/index.js.map +1 -0
  62. package/dist/modules/agent-instructions/agent-instructions.routes.d.ts +3 -2
  63. package/dist/modules/agent-instructions/agent-instructions.routes.d.ts.map +1 -1
  64. package/dist/modules/agent-instructions/agent-instructions.routes.js +3 -2
  65. package/dist/modules/agent-instructions/agent-instructions.routes.js.map +1 -1
  66. package/dist/modules/agent-instructions/compose.d.ts +14 -6
  67. package/dist/modules/agent-instructions/compose.d.ts.map +1 -1
  68. package/dist/modules/agent-instructions/compose.js +28 -8
  69. package/dist/modules/agent-instructions/compose.js.map +1 -1
  70. package/dist/modules/agent-instructions/index.d.ts +1 -1
  71. package/dist/modules/agent-instructions/index.d.ts.map +1 -1
  72. package/dist/modules/agent-instructions/index.js +1 -1
  73. package/dist/modules/agent-instructions/index.js.map +1 -1
  74. package/dist/modules/agent-instructions/shared-file-rules.d.ts +10 -50
  75. package/dist/modules/agent-instructions/shared-file-rules.d.ts.map +1 -1
  76. package/dist/modules/agent-instructions/shared-file-rules.js +51 -104
  77. package/dist/modules/agent-instructions/shared-file-rules.js.map +1 -1
  78. package/dist/modules/audit/agent-audit.service.d.ts +21 -2
  79. package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
  80. package/dist/modules/audit/agent-audit.service.js +43 -2
  81. package/dist/modules/audit/agent-audit.service.js.map +1 -1
  82. package/dist/modules/audit/agent-connection.routes.d.ts +34 -0
  83. package/dist/modules/audit/agent-connection.routes.d.ts.map +1 -0
  84. package/dist/modules/audit/agent-connection.routes.js +38 -0
  85. package/dist/modules/audit/agent-connection.routes.js.map +1 -0
  86. package/dist/modules/audit/audit.contract.d.ts +24 -0
  87. package/dist/modules/audit/audit.contract.d.ts.map +1 -1
  88. package/dist/modules/audit/audit.contract.js.map +1 -1
  89. package/dist/modules/audit/index.d.ts +1 -0
  90. package/dist/modules/audit/index.d.ts.map +1 -1
  91. package/dist/modules/audit/index.js +1 -0
  92. package/dist/modules/audit/index.js.map +1 -1
  93. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  94. package/dist/modules/auth/account.routes.js +10 -3
  95. package/dist/modules/auth/account.routes.js.map +1 -1
  96. package/dist/modules/auth/auth.middleware.d.ts +7 -0
  97. package/dist/modules/auth/auth.middleware.d.ts.map +1 -1
  98. package/dist/modules/auth/auth.middleware.js +1 -1
  99. package/dist/modules/auth/auth.middleware.js.map +1 -1
  100. package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -1
  101. package/dist/modules/code-mode/code-mode.tool.js +11 -3
  102. package/dist/modules/code-mode/code-mode.tool.js.map +1 -1
  103. package/dist/modules/database/core-schema.d.ts +96 -0
  104. package/dist/modules/database/core-schema.d.ts.map +1 -1
  105. package/dist/modules/database/core-schema.js +32 -3
  106. package/dist/modules/database/core-schema.js.map +1 -1
  107. package/dist/modules/embed/account-link.service.d.ts +42 -0
  108. package/dist/modules/embed/account-link.service.d.ts.map +1 -0
  109. package/dist/modules/embed/account-link.service.js +50 -0
  110. package/dist/modules/embed/account-link.service.js.map +1 -0
  111. package/dist/modules/embed/embed-link.d.ts +58 -0
  112. package/dist/modules/embed/embed-link.d.ts.map +1 -0
  113. package/dist/modules/embed/embed-link.js +160 -0
  114. package/dist/modules/embed/embed-link.js.map +1 -0
  115. package/dist/modules/embed/embed.errors.d.ts +30 -0
  116. package/dist/modules/embed/embed.errors.d.ts.map +1 -0
  117. package/dist/modules/embed/embed.errors.js +42 -0
  118. package/dist/modules/embed/embed.errors.js.map +1 -0
  119. package/dist/modules/embed/embed.interface.d.ts +204 -0
  120. package/dist/modules/embed/embed.interface.d.ts.map +1 -0
  121. package/dist/modules/embed/embed.interface.js +2 -0
  122. package/dist/modules/embed/embed.interface.js.map +1 -0
  123. package/dist/modules/embed/embed.routes.d.ts +59 -0
  124. package/dist/modules/embed/embed.routes.d.ts.map +1 -0
  125. package/dist/modules/embed/embed.routes.js +343 -0
  126. package/dist/modules/embed/embed.routes.js.map +1 -0
  127. package/dist/modules/embed/embed.service.d.ts +169 -0
  128. package/dist/modules/embed/embed.service.d.ts.map +1 -0
  129. package/dist/modules/embed/embed.service.js +627 -0
  130. package/dist/modules/embed/embed.service.js.map +1 -0
  131. package/dist/modules/embed/embed.tools.d.ts +51 -0
  132. package/dist/modules/embed/embed.tools.d.ts.map +1 -0
  133. package/dist/modules/embed/embed.tools.js +170 -0
  134. package/dist/modules/embed/embed.tools.js.map +1 -0
  135. package/dist/modules/embed/mcp-app.d.ts +64 -0
  136. package/dist/modules/embed/mcp-app.d.ts.map +1 -0
  137. package/dist/modules/embed/mcp-app.js +147 -0
  138. package/dist/modules/embed/mcp-app.js.map +1 -0
  139. package/dist/modules/embed/mcp-app.routes.d.ts +21 -0
  140. package/dist/modules/embed/mcp-app.routes.d.ts.map +1 -0
  141. package/dist/modules/embed/mcp-app.routes.js +36 -0
  142. package/dist/modules/embed/mcp-app.routes.js.map +1 -0
  143. package/dist/modules/github-app/github-app.connection.d.ts +15 -0
  144. package/dist/modules/github-app/github-app.connection.d.ts.map +1 -1
  145. package/dist/modules/github-app/github-app.connection.js +34 -3
  146. package/dist/modules/github-app/github-app.connection.js.map +1 -1
  147. package/dist/modules/kb-fs/locking-filesystem.d.ts +65 -0
  148. package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
  149. package/dist/modules/kb-fs/locking-filesystem.js +300 -0
  150. package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
  151. package/dist/modules/kb-sync/kb-sync.interface.d.ts +5 -0
  152. package/dist/modules/kb-sync/kb-sync.interface.d.ts.map +1 -1
  153. package/dist/modules/kb-sync/kb-sync.service.d.ts.map +1 -1
  154. package/dist/modules/kb-sync/kb-sync.service.js +6 -0
  155. package/dist/modules/kb-sync/kb-sync.service.js.map +1 -1
  156. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
  157. package/dist/modules/mcp/mcp-auth.middleware.js +2 -1
  158. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
  159. package/dist/modules/mcp/mcp.service.d.ts +57 -3
  160. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  161. package/dist/modules/mcp/mcp.service.js +177 -24
  162. package/dist/modules/mcp/mcp.service.js.map +1 -1
  163. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +24 -0
  164. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  165. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +32 -4
  166. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  167. package/dist/modules/mcp/tool-schema-guard.d.ts +105 -0
  168. package/dist/modules/mcp/tool-schema-guard.d.ts.map +1 -0
  169. package/dist/modules/mcp/tool-schema-guard.js +171 -0
  170. package/dist/modules/mcp/tool-schema-guard.js.map +1 -0
  171. package/dist/modules/onboarding/onboarding.contract.d.ts +80 -0
  172. package/dist/modules/onboarding/onboarding.contract.d.ts.map +1 -0
  173. package/dist/modules/onboarding/onboarding.contract.js +7 -0
  174. package/dist/modules/onboarding/onboarding.contract.js.map +1 -0
  175. package/dist/modules/onboarding/onboarding.routes.d.ts +18 -0
  176. package/dist/modules/onboarding/onboarding.routes.d.ts.map +1 -0
  177. package/dist/modules/onboarding/onboarding.routes.js +81 -0
  178. package/dist/modules/onboarding/onboarding.routes.js.map +1 -0
  179. package/dist/modules/onboarding/starter-pack.service.d.ts +213 -0
  180. package/dist/modules/onboarding/starter-pack.service.d.ts.map +1 -0
  181. package/dist/modules/onboarding/starter-pack.service.js +492 -0
  182. package/dist/modules/onboarding/starter-pack.service.js.map +1 -0
  183. package/dist/modules/onboarding/starter-packs.d.ts +78 -0
  184. package/dist/modules/onboarding/starter-packs.d.ts.map +1 -0
  185. package/dist/modules/onboarding/starter-packs.js +156 -0
  186. package/dist/modules/onboarding/starter-packs.js.map +1 -0
  187. package/dist/modules/plugins/index.d.ts +1 -1
  188. package/dist/modules/plugins/index.d.ts.map +1 -1
  189. package/dist/modules/plugins/index.js +1 -1
  190. package/dist/modules/plugins/index.js.map +1 -1
  191. package/dist/modules/plugins/plugin-provision.service.d.ts +19 -0
  192. package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
  193. package/dist/modules/plugins/plugin-provision.service.js +18 -1
  194. package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
  195. package/dist/modules/plugins/plugins.routes.d.ts +0 -36
  196. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  197. package/dist/modules/plugins/plugins.routes.js +31 -0
  198. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  199. package/dist/modules/plugins/plugins.tools.d.ts +36 -2
  200. package/dist/modules/plugins/plugins.tools.d.ts.map +1 -1
  201. package/dist/modules/plugins/plugins.tools.js +71 -14
  202. package/dist/modules/plugins/plugins.tools.js.map +1 -1
  203. package/dist/modules/settings/deployment-settings.service.d.ts +34 -7
  204. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  205. package/dist/modules/settings/deployment-settings.service.js +148 -54
  206. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  207. package/dist/modules/settings/repository-source.d.ts +1 -0
  208. package/dist/modules/settings/repository-source.d.ts.map +1 -1
  209. package/dist/modules/settings/repository-source.js +3 -3
  210. package/dist/modules/settings/repository-source.js.map +1 -1
  211. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  212. package/dist/modules/settings/setup.routes.js +3 -6
  213. package/dist/modules/settings/setup.routes.js.map +1 -1
  214. package/dist/modules/skills/skills.tools.d.ts.map +1 -1
  215. package/dist/modules/skills/skills.tools.js +103 -43
  216. package/dist/modules/skills/skills.tools.js.map +1 -1
  217. package/dist/modules/tool-auth/connection-key-rejection.d.ts +10 -1
  218. package/dist/modules/tool-auth/connection-key-rejection.d.ts.map +1 -1
  219. package/dist/modules/tool-auth/connection-key-rejection.js +11 -3
  220. package/dist/modules/tool-auth/connection-key-rejection.js.map +1 -1
  221. package/dist/modules/tool-auth/external-api-key.interface.d.ts +8 -0
  222. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
  223. package/dist/modules/tool-auth/external-api-key.service.d.ts +24 -2
  224. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  225. package/dist/modules/tool-auth/external-api-key.service.js +59 -2
  226. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  227. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
  228. package/dist/modules/tool-auth/tool-auth.middleware.js +9 -4
  229. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
  230. package/dist/modules/tool-helpers/index.d.ts +28 -1
  231. package/dist/modules/tool-helpers/index.d.ts.map +1 -1
  232. package/dist/modules/tool-helpers/index.js +28 -1
  233. package/dist/modules/tool-helpers/index.js.map +1 -1
  234. package/dist/modules/tool-helpers/route-argument-check.d.ts +10 -0
  235. package/dist/modules/tool-helpers/route-argument-check.d.ts.map +1 -0
  236. package/dist/modules/tool-helpers/route-argument-check.js +132 -0
  237. package/dist/modules/tool-helpers/route-argument-check.js.map +1 -0
  238. package/dist/modules/tool-helpers/route-tool-schemas.d.ts +89 -0
  239. package/dist/modules/tool-helpers/route-tool-schemas.d.ts.map +1 -0
  240. package/dist/modules/tool-helpers/route-tool-schemas.js +113 -0
  241. package/dist/modules/tool-helpers/route-tool-schemas.js.map +1 -0
  242. package/dist/modules/tool-helpers/tool-def.d.ts +71 -0
  243. package/dist/modules/tool-helpers/tool-def.d.ts.map +1 -1
  244. package/dist/modules/tool-helpers/tool-def.js +70 -6
  245. package/dist/modules/tool-helpers/tool-def.js.map +1 -1
  246. package/dist/modules/tool-helpers/tool-handler.d.ts +46 -6
  247. package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
  248. package/dist/modules/tool-helpers/tool-handler.js +157 -8
  249. package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
  250. package/dist/modules/tool-helpers/tool.contract.d.ts +9 -0
  251. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
  252. package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
  253. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +23 -4
  254. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
  255. package/dist/modules/tool-manuals/tool-manuals.contract.js.map +1 -1
  256. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +4 -0
  257. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  258. package/dist/modules/tool-manuals/tool-manuals.service.js +14 -0
  259. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  260. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +7 -0
  261. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  262. package/dist/modules/tool-manuals/tool-manuals.tools.js +77 -38
  263. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  264. package/dist/modules/tool-registry/description-length.d.ts +20 -16
  265. package/dist/modules/tool-registry/description-length.d.ts.map +1 -1
  266. package/dist/modules/tool-registry/description-length.js +50 -30
  267. package/dist/modules/tool-registry/description-length.js.map +1 -1
  268. package/dist/modules/tool-registry/guide-first.d.ts +27 -0
  269. package/dist/modules/tool-registry/guide-first.d.ts.map +1 -0
  270. package/dist/modules/tool-registry/guide-first.js +40 -0
  271. package/dist/modules/tool-registry/guide-first.js.map +1 -0
  272. package/dist/modules/tool-registry/tool-registry.d.ts +6 -0
  273. package/dist/modules/tool-registry/tool-registry.d.ts.map +1 -1
  274. package/dist/modules/tool-registry/tool-registry.js +9 -2
  275. package/dist/modules/tool-registry/tool-registry.js.map +1 -1
  276. package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts +449 -0
  277. package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts.map +1 -0
  278. package/dist/modules/workflow/agent-tools/change-request-read-shape.js +481 -0
  279. package/dist/modules/workflow/agent-tools/change-request-read-shape.js.map +1 -0
  280. package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts +126 -0
  281. package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts.map +1 -0
  282. package/dist/modules/workflow/agent-tools/change-request-read.tools.js +611 -0
  283. package/dist/modules/workflow/agent-tools/change-request-read.tools.js.map +1 -0
  284. package/dist/modules/workflow/agent-tools/change-request-summary.d.ts +12 -1
  285. package/dist/modules/workflow/agent-tools/change-request-summary.d.ts.map +1 -1
  286. package/dist/modules/workflow/agent-tools/change-request-summary.js +5 -1
  287. package/dist/modules/workflow/agent-tools/change-request-summary.js.map +1 -1
  288. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +8 -1
  289. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  290. package/dist/modules/workflow/agent-tools/workflow.tools.js +133 -37
  291. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  292. package/dist/modules/workflow/file-lock.service.d.ts +29 -5
  293. package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
  294. package/dist/modules/workflow/file-lock.service.js +62 -5
  295. package/dist/modules/workflow/file-lock.service.js.map +1 -1
  296. package/dist/modules/workflow/git/git.service.d.ts +282 -14
  297. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  298. package/dist/modules/workflow/git/git.service.js +627 -126
  299. package/dist/modules/workflow/git/git.service.js.map +1 -1
  300. package/dist/modules/workflow/git/merge-commit.d.ts +73 -0
  301. package/dist/modules/workflow/git/merge-commit.d.ts.map +1 -0
  302. package/dist/modules/workflow/git/merge-commit.js +89 -0
  303. package/dist/modules/workflow/git/merge-commit.js.map +1 -0
  304. package/dist/modules/workflow/git/node-git-runner.d.ts +15 -0
  305. package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
  306. package/dist/modules/workflow/git/node-git-runner.js +78 -6
  307. package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
  308. package/dist/modules/workflow/git/pull-request.service.d.ts +94 -1
  309. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
  310. package/dist/modules/workflow/git/pull-request.service.js +332 -37
  311. package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
  312. package/dist/modules/workflow/pending-commits.service.d.ts +15 -0
  313. package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
  314. package/dist/modules/workflow/pending-commits.service.js +25 -1
  315. package/dist/modules/workflow/pending-commits.service.js.map +1 -1
  316. package/dist/modules/workflow/pending-commits.worker.d.ts +6 -1
  317. package/dist/modules/workflow/pending-commits.worker.d.ts.map +1 -1
  318. package/dist/modules/workflow/pending-commits.worker.js +23 -6
  319. package/dist/modules/workflow/pending-commits.worker.js.map +1 -1
  320. package/dist/modules/workflow/recovery-bot.js +1 -1
  321. package/dist/modules/workflow/recovery-bot.js.map +1 -1
  322. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts +35 -0
  323. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
  324. package/dist/modules/workflow/review-workflow/review-workflow.service.js +180 -13
  325. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
  326. package/dist/modules/workflow/sanitize-error.d.ts +16 -0
  327. package/dist/modules/workflow/sanitize-error.d.ts.map +1 -1
  328. package/dist/modules/workflow/sanitize-error.js +45 -0
  329. package/dist/modules/workflow/sanitize-error.js.map +1 -1
  330. package/dist/modules/workflow/workflow.routes.d.ts +6 -2
  331. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
  332. package/dist/modules/workflow/workflow.routes.js +7 -2
  333. package/dist/modules/workflow/workflow.routes.js.map +1 -1
  334. package/dist/modules/workflow/workflow.service.d.ts +187 -15
  335. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  336. package/dist/modules/workflow/workflow.service.js +808 -106
  337. package/dist/modules/workflow/workflow.service.js.map +1 -1
  338. package/dist/modules/workspace/agent-download.builder.d.ts +105 -0
  339. package/dist/modules/workspace/agent-download.builder.d.ts.map +1 -0
  340. package/dist/modules/workspace/agent-download.builder.js +238 -0
  341. package/dist/modules/workspace/agent-download.builder.js.map +1 -0
  342. package/dist/modules/workspace/agent-download.routes.d.ts +77 -0
  343. package/dist/modules/workspace/agent-download.routes.d.ts.map +1 -0
  344. package/dist/modules/workspace/agent-download.routes.js +156 -0
  345. package/dist/modules/workspace/agent-download.routes.js.map +1 -0
  346. package/dist/modules/workspace/agent-download.store.d.ts +225 -0
  347. package/dist/modules/workspace/agent-download.store.d.ts.map +1 -0
  348. package/dist/modules/workspace/agent-download.store.js +423 -0
  349. package/dist/modules/workspace/agent-download.store.js.map +1 -0
  350. package/dist/modules/workspace/agent-upload.store.d.ts +10 -1
  351. package/dist/modules/workspace/agent-upload.store.d.ts.map +1 -1
  352. package/dist/modules/workspace/agent-upload.store.js +16 -6
  353. package/dist/modules/workspace/agent-upload.store.js.map +1 -1
  354. package/dist/modules/workspace/file-readers/raw-mime.d.ts +6 -0
  355. package/dist/modules/workspace/file-readers/raw-mime.d.ts.map +1 -0
  356. package/dist/modules/workspace/file-readers/raw-mime.js +38 -0
  357. package/dist/modules/workspace/file-readers/raw-mime.js.map +1 -0
  358. package/dist/modules/workspace/file-readers/text-reader.d.ts +5 -5
  359. package/dist/modules/workspace/file-readers/text-reader.d.ts.map +1 -1
  360. package/dist/modules/workspace/file-readers/text-reader.js +5 -8
  361. package/dist/modules/workspace/file-readers/text-reader.js.map +1 -1
  362. package/dist/modules/workspace/first-run.d.ts +111 -0
  363. package/dist/modules/workspace/first-run.d.ts.map +1 -0
  364. package/dist/modules/workspace/first-run.js +181 -0
  365. package/dist/modules/workspace/first-run.js.map +1 -0
  366. package/dist/modules/workspace/move-links.d.ts +92 -0
  367. package/dist/modules/workspace/move-links.d.ts.map +1 -0
  368. package/dist/modules/workspace/move-links.js +173 -0
  369. package/dist/modules/workspace/move-links.js.map +1 -0
  370. package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
  371. package/dist/modules/workspace/startup/steps/seed-tree.js +24 -39
  372. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  373. package/dist/modules/workspace/startup/steps/template-files.step.d.ts +58 -52
  374. package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
  375. package/dist/modules/workspace/startup/steps/template-files.step.js +209 -223
  376. package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
  377. package/dist/modules/workspace/startup/steps/template-source.d.ts +5 -3
  378. package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -1
  379. package/dist/modules/workspace/startup/steps/template-source.js +5 -3
  380. package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
  381. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  382. package/dist/modules/workspace/workspace.routes.js +63 -22
  383. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  384. package/dist/modules/workspace/workspace.service.d.ts +75 -2
  385. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  386. package/dist/modules/workspace/workspace.service.js +197 -24
  387. package/dist/modules/workspace/workspace.service.js.map +1 -1
  388. package/dist/modules/workspace/workspace.tools.d.ts +68 -1
  389. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  390. package/dist/modules/workspace/workspace.tools.js +642 -71
  391. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  392. package/dist/modules/write-access/write-access.d.ts.map +1 -1
  393. package/dist/modules/write-access/write-access.js +9 -0
  394. package/dist/modules/write-access/write-access.js.map +1 -1
  395. package/dist/shared/domain-errors.d.ts +84 -1
  396. package/dist/shared/domain-errors.d.ts.map +1 -1
  397. package/dist/shared/domain-errors.js +100 -12
  398. package/dist/shared/domain-errors.js.map +1 -1
  399. package/dist/shared/git.contract.d.ts +10 -1
  400. package/dist/shared/git.contract.d.ts.map +1 -1
  401. package/dist/shared/git.contract.js.map +1 -1
  402. package/dist/shared/hidden-tools.d.ts +44 -0
  403. package/dist/shared/hidden-tools.d.ts.map +1 -0
  404. package/dist/shared/hidden-tools.js +13 -0
  405. package/dist/shared/hidden-tools.js.map +1 -0
  406. package/dist/shared/utf8-text.d.ts +15 -0
  407. package/dist/shared/utf8-text.d.ts.map +1 -0
  408. package/dist/shared/utf8-text.js +20 -0
  409. package/dist/shared/utf8-text.js.map +1 -0
  410. package/dist/tenancy/static-tenant-source.d.ts +2 -1
  411. package/dist/tenancy/static-tenant-source.d.ts.map +1 -1
  412. package/dist/tenancy/static-tenant-source.js +9 -2
  413. package/dist/tenancy/static-tenant-source.js.map +1 -1
  414. package/kb-template/.bevelignore +0 -5
  415. package/mcp-app/page.html +349 -0
  416. package/migrations/0017_atlassian_account_links.sql +37 -0
  417. package/migrations/meta/0017_snapshot.json +2396 -0
  418. package/migrations/meta/_journal.json +8 -1
  419. package/package.json +6 -3
  420. package/src/__tests__/kb-layout-config.test.ts +10 -100
  421. package/src/__tests__/packaged-assets-ship.test.ts +66 -0
  422. package/src/assets.ts +38 -2
  423. package/src/core/__tests__/catalog-revision.test.ts +40 -0
  424. package/src/core/__tests__/gated-boot.test.ts +1 -0
  425. package/src/core/__tests__/lifecycle.test.ts +14 -0
  426. package/src/core/catalog-revision.ts +15 -2
  427. package/src/core/core-ports.ts +11 -0
  428. package/src/core/create-core-server.ts +78 -3
  429. package/src/core/create-core-services.ts +168 -10
  430. package/src/core/lifecycle.ts +28 -2
  431. package/src/core-config.ts +24 -1
  432. package/src/index.ts +2 -2
  433. package/src/modules/access/__tests__/access-control.atref-batch.test.ts +58 -0
  434. package/src/modules/access/__tests__/access-control.platform-restore.test.ts +8 -7
  435. package/src/modules/access/__tests__/access-control.service.test.ts +19 -0
  436. package/src/modules/access/__tests__/access-personal-plugin.test.ts +1 -18
  437. package/src/modules/access/access-control.interface.ts +28 -0
  438. package/src/modules/access/access-control.service.ts +37 -0
  439. package/src/modules/access/directory-sync-bot.ts +1 -1
  440. package/src/modules/agent-guide/__tests__/agent-guide.test.ts +386 -0
  441. package/src/modules/agent-guide/__tests__/agent-guide.tools.test.ts +207 -0
  442. package/src/modules/agent-guide/agent-guide.tools.ts +122 -0
  443. package/src/modules/agent-guide/agent-guide.ts +300 -0
  444. package/src/modules/agent-guide/index.ts +22 -0
  445. package/src/modules/agent-instructions/__tests__/shared-file-rules.test.ts +39 -118
  446. package/src/modules/agent-instructions/agent-instructions.routes.ts +3 -2
  447. package/src/modules/agent-instructions/compose.ts +26 -8
  448. package/src/modules/agent-instructions/index.ts +0 -3
  449. package/src/modules/agent-instructions/shared-file-rules.ts +50 -112
  450. package/src/modules/audit/__tests__/agent-audit.service.test.ts +64 -4
  451. package/src/modules/audit/__tests__/agent-connection.routes.test.ts +102 -0
  452. package/src/modules/audit/agent-audit.service.ts +58 -3
  453. package/src/modules/audit/agent-connection.routes.ts +56 -0
  454. package/src/modules/audit/audit.contract.ts +26 -0
  455. package/src/modules/audit/index.ts +1 -0
  456. package/src/modules/auth/__tests__/account.routes.test.ts +5 -3
  457. package/src/modules/auth/account.routes.ts +10 -3
  458. package/src/modules/auth/auth.middleware.ts +1 -1
  459. package/src/modules/code-mode/__tests__/code-mode.tool.test.ts +18 -2
  460. package/src/modules/code-mode/code-mode.tool.ts +13 -2
  461. package/src/modules/database/core-schema.ts +33 -3
  462. package/src/modules/embed/__tests__/account-links.migration.test.ts +98 -0
  463. package/src/modules/embed/__tests__/embed-link.test.ts +122 -0
  464. package/src/modules/embed/__tests__/embed.routes.test.ts +362 -0
  465. package/src/modules/embed/__tests__/embed.service.lock.test.ts +193 -0
  466. package/src/modules/embed/__tests__/embed.service.test.ts +805 -0
  467. package/src/modules/embed/__tests__/embed.tools.test.ts +304 -0
  468. package/src/modules/embed/__tests__/mcp-app.test.ts +207 -0
  469. package/src/modules/embed/account-link.service.ts +76 -0
  470. package/src/modules/embed/embed-link.ts +180 -0
  471. package/src/modules/embed/embed.errors.ts +43 -0
  472. package/src/modules/embed/embed.interface.ts +203 -0
  473. package/src/modules/embed/embed.routes.ts +363 -0
  474. package/src/modules/embed/embed.service.ts +705 -0
  475. package/src/modules/embed/embed.tools.ts +206 -0
  476. package/src/modules/embed/mcp-app.routes.ts +41 -0
  477. package/src/modules/embed/mcp-app.ts +173 -0
  478. package/src/modules/github-app/__tests__/github-app.test.ts +76 -0
  479. package/src/modules/github-app/github-app.connection.ts +38 -4
  480. package/src/modules/kb-fs/__tests__/move-with-edits.test.ts +304 -0
  481. package/src/modules/kb-fs/locking-filesystem.ts +287 -0
  482. package/src/modules/kb-sync/__tests__/kb-sync.service.test.ts +35 -0
  483. package/src/modules/kb-sync/kb-sync.interface.ts +2 -0
  484. package/src/modules/kb-sync/kb-sync.service.ts +6 -0
  485. package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +68 -11
  486. package/src/modules/mcp/__tests__/fake-downstream-mcp-server.ts +14 -3
  487. package/src/modules/mcp/__tests__/mcp-proxy-helpers.test.ts +37 -2
  488. package/src/modules/mcp/__tests__/mcp.app.e2e.test.ts +200 -0
  489. package/src/modules/mcp/__tests__/mcp.e2e.test.ts +252 -0
  490. package/src/modules/mcp/__tests__/mcp.service.test.ts +42 -24
  491. package/src/modules/mcp/__tests__/tool-call-interface.e2e.test.ts +499 -0
  492. package/src/modules/mcp/__tests__/tool-schema-guard.test.ts +266 -0
  493. package/src/modules/mcp/mcp-auth.middleware.ts +2 -1
  494. package/src/modules/mcp/mcp.service.ts +218 -31
  495. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +42 -4
  496. package/src/modules/mcp/tool-schema-guard.ts +196 -0
  497. package/src/modules/onboarding/__tests__/onboarding.routes.test.ts +163 -0
  498. package/src/modules/onboarding/__tests__/starter-pack.service.test.ts +635 -0
  499. package/src/modules/onboarding/__tests__/starter-packs.test.ts +169 -0
  500. package/src/modules/onboarding/onboarding.contract.ts +85 -0
  501. package/src/modules/onboarding/onboarding.routes.ts +85 -0
  502. package/src/modules/onboarding/starter-pack.service.ts +580 -0
  503. package/src/modules/onboarding/starter-packs.ts +182 -0
  504. package/src/modules/plugins/__tests__/plugins.tools.test.ts +177 -4
  505. package/src/modules/plugins/index.ts +1 -0
  506. package/src/modules/plugins/plugin-provision.service.ts +22 -1
  507. package/src/modules/plugins/plugins.routes.ts +29 -0
  508. package/src/modules/plugins/plugins.tools.ts +75 -15
  509. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +176 -56
  510. package/src/modules/settings/__tests__/repository-source.test.ts +9 -0
  511. package/src/modules/settings/deployment-settings.service.ts +144 -55
  512. package/src/modules/settings/repository-source.ts +4 -4
  513. package/src/modules/settings/setup.routes.ts +3 -6
  514. package/src/modules/skills/__tests__/skills.tools.description.test.ts +95 -0
  515. package/src/modules/skills/skills.tools.ts +112 -46
  516. package/src/modules/tool-auth/__tests__/connection-key-rejection.test.ts +32 -0
  517. package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +65 -0
  518. package/src/modules/tool-auth/connection-key-rejection.ts +13 -3
  519. package/src/modules/tool-auth/external-api-key.interface.ts +9 -0
  520. package/src/modules/tool-auth/external-api-key.service.ts +61 -4
  521. package/src/modules/tool-auth/tool-auth.middleware.ts +13 -4
  522. package/src/modules/tool-helpers/__tests__/branch-declaration.test.ts +502 -0
  523. package/src/modules/tool-helpers/__tests__/route-argument-check.test.ts +337 -0
  524. package/src/modules/tool-helpers/index.ts +34 -1
  525. package/src/modules/tool-helpers/route-argument-check.ts +149 -0
  526. package/src/modules/tool-helpers/route-tool-schemas.ts +171 -0
  527. package/src/modules/tool-helpers/tool-def.ts +132 -7
  528. package/src/modules/tool-helpers/tool-handler.ts +196 -8
  529. package/src/modules/tool-helpers/tool.contract.ts +9 -0
  530. package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +57 -0
  531. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +73 -4
  532. package/src/modules/tool-manuals/tool-manuals.contract.ts +24 -4
  533. package/src/modules/tool-manuals/tool-manuals.service.ts +17 -0
  534. package/src/modules/tool-manuals/tool-manuals.tools.ts +86 -38
  535. package/src/modules/tool-registry/__tests__/own-tool-schemas.test.ts +173 -0
  536. package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +81 -66
  537. package/src/modules/tool-registry/description-length.ts +57 -32
  538. package/src/modules/tool-registry/guide-first.ts +41 -0
  539. package/src/modules/tool-registry/tool-registry.ts +9 -2
  540. package/src/modules/workflow/__tests__/apply-failure.test.ts +6 -1
  541. package/src/modules/workflow/__tests__/file-lock.service.deletion-gate.test.ts +104 -0
  542. package/src/modules/workflow/__tests__/pending-commits.repository-replaced.test.ts +66 -0
  543. package/src/modules/workflow/__tests__/pending-commits.worker.test.ts +31 -2
  544. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +110 -6
  545. package/src/modules/workflow/__tests__/sanitize-error.test.ts +89 -1
  546. package/src/modules/workflow/__tests__/workflow.routes.push-refused.test.ts +202 -0
  547. package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +6 -6
  548. package/src/modules/workflow/__tests__/workflow.service.delete-branch.test.ts +1026 -0
  549. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +468 -10
  550. package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +4 -0
  551. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +5 -4
  552. package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +54 -2
  553. package/src/modules/workflow/agent-tools/__tests__/change-request-read-shape.test.ts +705 -0
  554. package/src/modules/workflow/agent-tools/__tests__/change-request-read.tools.test.ts +1554 -0
  555. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +150 -4
  556. package/src/modules/workflow/agent-tools/change-request-read-shape.ts +712 -0
  557. package/src/modules/workflow/agent-tools/change-request-read.tools.ts +759 -0
  558. package/src/modules/workflow/agent-tools/change-request-summary.ts +5 -1
  559. package/src/modules/workflow/agent-tools/workflow.tools.ts +137 -35
  560. package/src/modules/workflow/file-lock.service.ts +67 -5
  561. package/src/modules/workflow/git/__tests__/git.service.appliedChange.test.ts +285 -0
  562. package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +124 -0
  563. package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +164 -0
  564. package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +334 -0
  565. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +48 -1
  566. package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +231 -2
  567. package/src/modules/workflow/git/__tests__/pull-request.service.list-fetch.test.ts +72 -2
  568. package/src/modules/workflow/git/__tests__/pull-request.service.placeholder.test.ts +24 -2
  569. package/src/modules/workflow/git/__tests__/pull-request.service.test.ts +620 -1
  570. package/src/modules/workflow/git/git.service.ts +714 -133
  571. package/src/modules/workflow/git/merge-commit.ts +88 -0
  572. package/src/modules/workflow/git/node-git-runner.ts +82 -7
  573. package/src/modules/workflow/git/pull-request.service.ts +380 -54
  574. package/src/modules/workflow/pending-commits.service.ts +29 -1
  575. package/src/modules/workflow/pending-commits.worker.ts +24 -6
  576. package/src/modules/workflow/recovery-bot.ts +1 -1
  577. package/src/modules/workflow/review-workflow/__tests__/approval-states.test.ts +7 -1
  578. package/src/modules/workflow/review-workflow/__tests__/merge-records-own-commit.test.ts +407 -0
  579. package/src/modules/workflow/review-workflow/review-workflow.service.ts +191 -12
  580. package/src/modules/workflow/sanitize-error.ts +50 -0
  581. package/src/modules/workflow/workflow.routes.ts +7 -2
  582. package/src/modules/workflow/workflow.service.ts +886 -112
  583. package/src/modules/workspace/__tests__/agent-downloads.test.ts +823 -0
  584. package/src/modules/workspace/__tests__/escape-sequences.routes.test.ts +4 -3
  585. package/src/modules/workspace/__tests__/first-run.test.ts +234 -0
  586. package/src/modules/workspace/__tests__/git-internals.security.test.ts +5 -2
  587. package/src/modules/workspace/__tests__/md-links.test.ts +353 -0
  588. package/src/modules/workspace/__tests__/move-links.test.ts +261 -0
  589. package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +219 -0
  590. package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -0
  591. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +102 -0
  592. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +52 -5
  593. package/src/modules/workspace/__tests__/workspace.routes.folder-zip-access.test.ts +190 -0
  594. package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +21 -10
  595. package/src/modules/workspace/__tests__/workspace.service.forget-clone-races.test.ts +8 -4
  596. package/src/modules/workspace/__tests__/workspace.service.test.ts +50 -8
  597. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +33 -55
  598. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +44 -1
  599. package/src/modules/workspace/__tests__/workspace.tools.test.ts +664 -34
  600. package/src/modules/workspace/agent-download.builder.ts +308 -0
  601. package/src/modules/workspace/agent-download.routes.ts +183 -0
  602. package/src/modules/workspace/agent-download.store.ts +533 -0
  603. package/src/modules/workspace/agent-upload.store.ts +23 -7
  604. package/src/modules/workspace/file-readers/raw-mime.ts +40 -0
  605. package/src/modules/workspace/file-readers/text-reader.ts +5 -8
  606. package/src/modules/workspace/first-run.ts +222 -0
  607. package/src/modules/workspace/move-links.ts +237 -0
  608. package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +191 -489
  609. package/src/modules/workspace/startup/steps/seed-tree.ts +23 -38
  610. package/src/modules/workspace/startup/steps/template-files.step.ts +217 -249
  611. package/src/modules/workspace/startup/steps/template-source.ts +5 -3
  612. package/src/modules/workspace/workspace.routes.ts +64 -22
  613. package/src/modules/workspace/workspace.service.ts +202 -25
  614. package/src/modules/workspace/workspace.tools.ts +707 -68
  615. package/src/modules/write-access/__tests__/write-access.test.ts +13 -0
  616. package/src/modules/write-access/write-access.ts +9 -0
  617. package/src/shared/domain-errors.ts +123 -11
  618. package/src/shared/git.contract.ts +8 -1
  619. package/src/shared/hidden-tools.ts +45 -0
  620. package/src/shared/utf8-text.ts +21 -0
  621. package/src/tenancy/__tests__/static-tenant-source.test.ts +1 -0
  622. package/src/tenancy/static-tenant-source.ts +10 -2
  623. package/starter-packs/README.md +103 -0
  624. package/starter-packs/engineering/KnowledgeBase/About us.md +9 -0
  625. package/starter-packs/engineering/KnowledgeBase/Architecture.md +9 -0
  626. package/starter-packs/engineering/KnowledgeBase/Glossary.md +9 -0
  627. package/starter-packs/engineering/KnowledgeBase/How we ship.md +9 -0
  628. package/starter-packs/engineering/Plugins/engineering-starter/LICENSE +21 -0
  629. package/starter-packs/engineering/Plugins/engineering-starter/SOURCE.md +20 -0
  630. package/starter-packs/engineering/Plugins/engineering-starter/access.md +19 -0
  631. package/starter-packs/engineering/Plugins/engineering-starter/plugin.json +10 -0
  632. package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/SKILL.md +171 -0
  633. package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/sections/phase-2a-startup-diagnostic.md +157 -0
  634. package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/sections/phase-2b-builder-brainstorm.md +39 -0
  635. package/starter-packs/engineering/Plugins/engineering-starter/skills/plan-ceo-review/SKILL.md +144 -0
  636. package/starter-packs/engineering/Plugins/engineering-starter/skills/plan-eng-review/SKILL.md +144 -0
  637. package/starter-packs/engineering/Plugins/engineering-starter/skills/review/SKILL.md +80 -0
  638. package/starter-packs/engineering/Plugins/engineering-starter/skills/review/checklist.md +184 -0
  639. package/starter-packs/engineering/pack.yaml +11 -0
  640. package/starter-packs/general/KnowledgeBase/About us.md +9 -0
  641. package/starter-packs/general/KnowledgeBase/Glossary.md +9 -0
  642. package/starter-packs/general/KnowledgeBase/How we work.md +9 -0
  643. package/starter-packs/general/Plugins/general-starter/LICENSE +202 -0
  644. package/starter-packs/general/Plugins/general-starter/SOURCE.md +10 -0
  645. package/starter-packs/general/Plugins/general-starter/access.md +19 -0
  646. package/starter-packs/general/Plugins/general-starter/plugin.json +10 -0
  647. package/starter-packs/general/Plugins/general-starter/skills/memory-management/SKILL.md +332 -0
  648. package/starter-packs/general/Plugins/general-starter/skills/productivity-start/SKILL.md +163 -0
  649. package/starter-packs/general/Plugins/general-starter/skills/productivity-update/SKILL.md +167 -0
  650. package/starter-packs/general/Plugins/general-starter/skills/task-management/SKILL.md +83 -0
  651. package/starter-packs/general/pack.yaml +10 -0
  652. package/starter-packs/operations/KnowledgeBase/Glossary.md +9 -0
  653. package/starter-packs/operations/KnowledgeBase/How we work.md +9 -0
  654. package/starter-packs/operations/KnowledgeBase/Processes.md +9 -0
  655. package/starter-packs/operations/KnowledgeBase/Tools we use.md +9 -0
  656. package/starter-packs/operations/KnowledgeBase/Vendors.md +9 -0
  657. package/starter-packs/operations/Plugins/operations-starter/LICENSE +202 -0
  658. package/starter-packs/operations/Plugins/operations-starter/SOURCE.md +10 -0
  659. package/starter-packs/operations/Plugins/operations-starter/access.md +19 -0
  660. package/starter-packs/operations/Plugins/operations-starter/plugin.json +10 -0
  661. package/starter-packs/operations/Plugins/operations-starter/skills/capacity-plan/SKILL.md +111 -0
  662. package/starter-packs/operations/Plugins/operations-starter/skills/change-request/SKILL.md +119 -0
  663. package/starter-packs/operations/Plugins/operations-starter/skills/compliance-tracking/SKILL.md +44 -0
  664. package/starter-packs/operations/Plugins/operations-starter/skills/process-doc/SKILL.md +80 -0
  665. package/starter-packs/operations/Plugins/operations-starter/skills/process-optimization/SKILL.md +39 -0
  666. package/starter-packs/operations/Plugins/operations-starter/skills/risk-assessment/SKILL.md +40 -0
  667. package/starter-packs/operations/Plugins/operations-starter/skills/runbook/SKILL.md +85 -0
  668. package/starter-packs/operations/Plugins/operations-starter/skills/status-report/SKILL.md +75 -0
  669. package/starter-packs/operations/Plugins/operations-starter/skills/vendor-review/SKILL.md +102 -0
  670. package/starter-packs/operations/pack.yaml +12 -0
  671. package/starter-packs/sales/KnowledgeBase/About us.md +9 -0
  672. package/starter-packs/sales/KnowledgeBase/Customers.md +9 -0
  673. package/starter-packs/sales/KnowledgeBase/Glossary.md +9 -0
  674. package/starter-packs/sales/KnowledgeBase/How we sell.md +9 -0
  675. package/starter-packs/sales/KnowledgeBase/Objections.md +9 -0
  676. package/starter-packs/sales/KnowledgeBase/Pricing.md +9 -0
  677. package/starter-packs/sales/Plugins/sales-starter/LICENSE +202 -0
  678. package/starter-packs/sales/Plugins/sales-starter/SOURCE.md +10 -0
  679. package/starter-packs/sales/Plugins/sales-starter/access.md +19 -0
  680. package/starter-packs/sales/Plugins/sales-starter/plugin.json +10 -0
  681. package/starter-packs/sales/Plugins/sales-starter/skills/account-context/SKILL.md +94 -0
  682. package/starter-packs/sales/Plugins/sales-starter/skills/account-plan/SKILL.md +95 -0
  683. package/starter-packs/sales/Plugins/sales-starter/skills/account-research/SKILL.md +99 -0
  684. package/starter-packs/sales/Plugins/sales-starter/skills/account-tiering/SKILL.md +101 -0
  685. package/starter-packs/sales/Plugins/sales-starter/skills/call-prep/SKILL.md +111 -0
  686. package/starter-packs/sales/Plugins/sales-starter/skills/call-summary/SKILL.md +111 -0
  687. package/starter-packs/sales/Plugins/sales-starter/skills/close-plan/SKILL.md +106 -0
  688. package/starter-packs/sales/Plugins/sales-starter/skills/competitive-intelligence/SKILL.md +102 -0
  689. package/starter-packs/sales/Plugins/sales-starter/skills/create-an-asset/SKILL.md +105 -0
  690. package/starter-packs/sales/Plugins/sales-starter/skills/crm-hygiene-check/SKILL.md +103 -0
  691. package/starter-packs/sales/Plugins/sales-starter/skills/customer-health/SKILL.md +108 -0
  692. package/starter-packs/sales/Plugins/sales-starter/skills/customer-voice/SKILL.md +94 -0
  693. package/starter-packs/sales/Plugins/sales-starter/skills/daily-briefing/SKILL.md +61 -0
  694. package/starter-packs/sales/Plugins/sales-starter/skills/deal-advance-gap/SKILL.md +102 -0
  695. package/starter-packs/sales/Plugins/sales-starter/skills/deal-review/SKILL.md +105 -0
  696. package/starter-packs/sales/Plugins/sales-starter/skills/deal-signals/SKILL.md +96 -0
  697. package/starter-packs/sales/Plugins/sales-starter/skills/deal-slip-scenario/SKILL.md +104 -0
  698. package/starter-packs/sales/Plugins/sales-starter/skills/draft-outreach/SKILL.md +116 -0
  699. package/starter-packs/sales/Plugins/sales-starter/skills/end-of-day/SKILL.md +114 -0
  700. package/starter-packs/sales/Plugins/sales-starter/skills/expansion-whitespace/SKILL.md +97 -0
  701. package/starter-packs/sales/Plugins/sales-starter/skills/forecast/SKILL.md +100 -0
  702. package/starter-packs/sales/Plugins/sales-starter/skills/handle-objection/SKILL.md +93 -0
  703. package/starter-packs/sales/Plugins/sales-starter/skills/inbox-sweep/SKILL.md +114 -0
  704. package/starter-packs/sales/Plugins/sales-starter/skills/lead-triage/SKILL.md +106 -0
  705. package/starter-packs/sales/Plugins/sales-starter/skills/log-activity/SKILL.md +111 -0
  706. package/starter-packs/sales/Plugins/sales-starter/skills/pipeline-review/SKILL.md +97 -0
  707. package/starter-packs/sales/Plugins/sales-starter/skills/renewal-radar/SKILL.md +95 -0
  708. package/starter-packs/sales/Plugins/sales-starter/skills/rep-context/SKILL.md +90 -0
  709. package/starter-packs/sales/Plugins/sales-starter/skills/route-lead/SKILL.md +111 -0
  710. package/starter-packs/sales/Plugins/sales-starter/skills/sales-setup/SKILL.md +200 -0
  711. package/starter-packs/sales/Plugins/sales-starter/skills/schedule-meeting/SKILL.md +99 -0
  712. package/starter-packs/sales/Plugins/sales-starter/skills/stakeholder-map/SKILL.md +107 -0
  713. package/starter-packs/sales/Plugins/sales-starter/skills/team-pipeline/SKILL.md +105 -0
  714. package/starter-packs/sales/Plugins/sales-starter/skills/update-opportunity/SKILL.md +112 -0
  715. package/starter-packs/sales/Plugins/sales-starter/skills/weekly-wrap/SKILL.md +90 -0
  716. package/starter-packs/sales/Plugins/sales-starter/skills/win-loss-review/SKILL.md +88 -0
  717. package/starter-packs/sales/pack.yaml +13 -0
  718. package/starter-packs/support/KnowledgeBase/Escalations.md +9 -0
  719. package/starter-packs/support/KnowledgeBase/Glossary.md +9 -0
  720. package/starter-packs/support/KnowledgeBase/Known issues.md +9 -0
  721. package/starter-packs/support/KnowledgeBase/Products.md +9 -0
  722. package/starter-packs/support/KnowledgeBase/Tone of voice.md +9 -0
  723. package/starter-packs/support/Plugins/support-starter/LICENSE +202 -0
  724. package/starter-packs/support/Plugins/support-starter/SOURCE.md +10 -0
  725. package/starter-packs/support/Plugins/support-starter/access.md +19 -0
  726. package/starter-packs/support/Plugins/support-starter/plugin.json +10 -0
  727. package/starter-packs/support/Plugins/support-starter/skills/customer-escalation/SKILL.md +246 -0
  728. package/starter-packs/support/Plugins/support-starter/skills/customer-research/SKILL.md +250 -0
  729. package/starter-packs/support/Plugins/support-starter/skills/draft-response/SKILL.md +416 -0
  730. package/starter-packs/support/Plugins/support-starter/skills/kb-article/SKILL.md +350 -0
  731. package/starter-packs/support/Plugins/support-starter/skills/ticket-triage/SKILL.md +273 -0
  732. package/starter-packs/support/pack.yaml +12 -0
  733. package/kb-template/AGENTS.md +0 -730
@@ -22,10 +22,32 @@ function updated(branch: string): BranchSyncOutcome {
22
22
  }
23
23
 
24
24
  describe('KbSyncService', () => {
25
+ it('answers the sync without waiting for the tidy-up after it', async () => {
26
+ let finish = (): void => undefined;
27
+ const workflow: SyncWorkflowPort = {
28
+ syncWorkspaceFromRemote: vi.fn(async (id: string) => updated(decodeURIComponent(id))),
29
+ closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
30
+ // A tidy-up that never ends unless told to — and one that fails.
31
+ tidyAfterSweep: vi
32
+ .fn()
33
+ .mockImplementationOnce(
34
+ () => new Promise((resolve) => (finish = () => resolve({ closedEmpty: 0, removedLeftovers: 0 }))),
35
+ )
36
+ .mockRejectedValueOnce(new Error('boom')),
37
+ retireRemoteGoneClone: vi.fn(async () => true),
38
+ };
39
+ const svc = new KbSyncService(workflow, workspaces(['main']));
40
+ await expect(svc.sync({ branches: 'all' })).resolves.toMatchObject({ status: 'synced' });
41
+ expect(workflow.tidyAfterSweep).toHaveBeenCalledTimes(1);
42
+ await expect(svc.sync({ branches: 'all' })).resolves.toMatchObject({ status: 'synced' });
43
+ finish();
44
+ });
45
+
25
46
  it('syncs every known clone for an "all" request and reports unknown branches as not cloned', async () => {
26
47
  const workflow: SyncWorkflowPort = {
27
48
  syncWorkspaceFromRemote: vi.fn(async (id: string) => updated(decodeURIComponent(id))),
28
49
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 1),
50
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
29
51
  retireRemoteGoneClone: vi.fn(async () => true),
30
52
  };
31
53
  const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x']));
@@ -34,6 +56,8 @@ describe('KbSyncService', () => {
34
56
  expect(all.status).toBe('synced');
35
57
  expect(all.results.map((r) => r.branch)).toEqual(['main', 'ali/x']);
36
58
  expect(all.changeRequests.closedDeletedBranch).toBe(1);
59
+ // Every sweep for deleted branches is followed by the leftover cleanup.
60
+ expect(workflow.tidyAfterSweep).toHaveBeenCalledTimes(1);
37
61
  expect(workflow.syncWorkspaceFromRemote).toHaveBeenCalledWith('ali%2Fx');
38
62
 
39
63
  const some = await svc.sync({ branches: ['ali/x', 'juan/other'] });
@@ -48,6 +72,7 @@ describe('KbSyncService', () => {
48
72
  : updated(decodeURIComponent(id)),
49
73
  ),
50
74
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
75
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
51
76
  retireRemoteGoneClone: vi.fn(async () => true),
52
77
  };
53
78
  const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x']));
@@ -62,6 +87,7 @@ describe('KbSyncService', () => {
62
87
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => {
63
88
  throw new Error('origin down');
64
89
  }),
90
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
65
91
  retireRemoteGoneClone: vi.fn(async () => true),
66
92
  };
67
93
  const svc = new KbSyncService(workflow, workspaces(['main']));
@@ -91,6 +117,7 @@ describe('KbSyncService', () => {
91
117
  return updated(branch);
92
118
  }),
93
119
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
120
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
94
121
  retireRemoteGoneClone: vi.fn(async () => true),
95
122
  };
96
123
  const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x', 'juan/y']));
@@ -121,6 +148,7 @@ describe('KbSyncService', () => {
121
148
  return updated(decodeURIComponent(id));
122
149
  }),
123
150
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
151
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
124
152
  retireRemoteGoneClone: vi.fn(async () => true),
125
153
  };
126
154
  const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x', 'juan/y']));
@@ -141,6 +169,7 @@ describe('KbSyncService.lastSync', () => {
141
169
  const workflow: SyncWorkflowPort = {
142
170
  syncWorkspaceFromRemote: vi.fn(async (id: string) => updated(decodeURIComponent(id))),
143
171
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
172
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
144
173
  retireRemoteGoneClone: vi.fn(async () => true),
145
174
  };
146
175
  let clock = 1_000;
@@ -168,6 +197,7 @@ describe('KbSyncService.lastSync', () => {
168
197
  return updated(decodeURIComponent(id));
169
198
  }),
170
199
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
200
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
171
201
  retireRemoteGoneClone: vi.fn(async () => true),
172
202
  };
173
203
  const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x']));
@@ -188,6 +218,7 @@ describe('KbSyncService — a throwing branch step', () => {
188
218
  return updated(decodeURIComponent(id));
189
219
  }),
190
220
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 1),
221
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
191
222
  retireRemoteGoneClone: vi.fn(async () => true),
192
223
  };
193
224
  const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x']));
@@ -208,6 +239,7 @@ describe('KbSyncService — clones the host no longer has, and clones that canno
208
239
  id === 'ali%2Fx' ? { branch: 'ali/x', outcome: 'remote-gone' } : updated(decodeURIComponent(id)),
209
240
  ),
210
241
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 1),
242
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
211
243
  retireRemoteGoneClone: vi.fn(async () => true),
212
244
  };
213
245
  const svc = new KbSyncService(workflow, workspaces(['ali/x', 'main']));
@@ -222,6 +254,7 @@ describe('KbSyncService — clones the host no longer has, and clones that canno
222
254
  const workflow: SyncWorkflowPort = {
223
255
  syncWorkspaceFromRemote: vi.fn(async (id: string) => updated(decodeURIComponent(id))),
224
256
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
257
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
225
258
  retireRemoteGoneClone: vi.fn(async () => true),
226
259
  };
227
260
  const port: SyncWorkspacePort = {
@@ -251,6 +284,7 @@ describe('KbSyncService — a coalesced caller is judged by its own branches', (
251
284
  return updated(decodeURIComponent(id));
252
285
  }),
253
286
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
287
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
254
288
  retireRemoteGoneClone: vi.fn(async () => true),
255
289
  };
256
290
  const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x', 'juan/y']));
@@ -278,6 +312,7 @@ describe('KbSyncService — a waiter keeps the branches it asked for', () => {
278
312
  return updated(decodeURIComponent(id));
279
313
  }),
280
314
  closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
315
+ tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
281
316
  retireRemoteGoneClone: vi.fn(async () => true),
282
317
  };
283
318
  const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x', 'juan/y']));
@@ -61,6 +61,8 @@ export interface SyncWorkflowPort {
61
61
  retireRemoteGoneClone(workspaceId: string): Promise<boolean>;
62
62
  /** The existing sweep; returns how many requests it closed. */
63
63
  closeChangeRequestsWithDeletedBranches(): Promise<number>;
64
+ /** The tidy-up after the sweep — empty open requests closed, leftover branches removed; never throws. */
65
+ tidyAfterSweep(): Promise<{ closedEmpty: number; removedLeftovers: number }>;
64
66
  }
65
67
 
66
68
  /**
@@ -187,6 +187,12 @@ export class KbSyncService implements IKbSyncService {
187
187
  } catch (err) {
188
188
  log.warn('deleted-branch sweep failed:', { err });
189
189
  }
190
+ // Then the tidy-up boot runs too: empty open requests closed, leftover
191
+ // branches of merged requests removed. Detached: it can take a while on a
192
+ // large repository, and the sync (often a webhook with a short timeout)
193
+ // must not wait on it. It never throws; the catch is for a mock or a
194
+ // future change that does.
195
+ void this.workflow.tidyAfterSweep().catch((err: unknown) => log.warn('post-sync tidy-up failed:', { err }));
190
196
 
191
197
  const result: SyncResult = {
192
198
  status: KbSyncService.statusOf(results),
@@ -70,15 +70,19 @@ function render(fragment: SQL): { sql: string; params: unknown[] } {
70
70
  return { sql: q.sql, params: q.params };
71
71
  }
72
72
 
73
- function makeProvider(queue: any[] = []) {
74
- const { db, captured } = makeFakeDb(queue);
75
- const provider = new BevelOAuthProvider({
73
+ function providerDeps(db: Database) {
74
+ return {
76
75
  db,
77
76
  crypto: null,
78
77
  stateSecret: STATE_SECRET,
79
78
  publicFrontendUrl: FRONTEND,
80
79
  tokenPrefix: PREFIX,
81
- });
80
+ };
81
+ }
82
+
83
+ function makeProvider(queue: unknown[] = []) {
84
+ const { db, captured } = makeFakeDb(queue);
85
+ const provider = new BevelOAuthProvider(providerDeps(db));
82
86
  return { provider, captured, db };
83
87
  }
84
88
 
@@ -292,9 +296,10 @@ describe('BevelOAuthProvider', () => {
292
296
  const { provider, captured, db } = makeProvider([
293
297
  [oldRow] /* revoke.returning */,
294
298
  [{ id: 'conn-1' }] /* the token's connection, still live */,
295
- undefined /* the (throttled) use stamp */,
299
+ [] /* the (throttled) use stamp's first-use claim: stamped before */,
296
300
  undefined, undefined, /* prunes */
297
301
  undefined /* token insert */,
302
+ undefined /* the ordinary use stamp */,
298
303
  ]);
299
304
  const tokens = await provider.exchangeRefreshToken(CLIENT, 'bevel-mcp_r_old', ['mcp']);
300
305
  expect(tokens.scope).toBe('mcp');
@@ -307,8 +312,10 @@ describe('BevelOAuthProvider', () => {
307
312
  expect((db as any).select).toHaveBeenCalledTimes(1);
308
313
  expect(render(captured.where[1])).toMatchObject({ params: ['conn-1'] });
309
314
  expect(render(captured.where[1]).sql).toMatch(/"agent_connections"."revoked_at" is null/);
310
- // …and the use is stamped separately, off the refresh's own path.
311
- expect(captured.updateTargets).toEqual([oauthTokens, agentConnections]);
315
+ // …and the use is stamped separately, off the refresh's own path: the
316
+ // first-use claim, then (stamped before) the ordinary stamp.
317
+ await new Promise((r) => setTimeout(r, 0));
318
+ expect(captured.updateTargets).toEqual([oauthTokens, agentConnections, agentConnections]);
312
319
  expect(Object.keys(captured.set[1])).toEqual(['lastUsedAt']);
313
320
 
314
321
  // Widening is refused.
@@ -363,6 +370,7 @@ describe('BevelOAuthProvider', () => {
363
370
  const { provider, captured } = makeProvider([
364
371
  [row] /* select */,
365
372
  undefined /* token lastUsedAt touch */,
373
+ [] /* the connection's first-use claim: stamped before */,
366
374
  undefined /* connection lastUsedAt touch */,
367
375
  [row] /* a second verify a moment later */,
368
376
  undefined /* its token touch — and NO second connection touch */,
@@ -381,16 +389,65 @@ describe('BevelOAuthProvider', () => {
381
389
  // Both "last used" marks are touched: the token's row, and THIS token's
382
390
  // agent connection.
383
391
  await new Promise((r) => setTimeout(r, 0));
384
- expect(captured.updateTargets).toEqual([oauthTokens, agentConnections]);
385
- expect(captured.set.map((s) => Object.keys(s))).toEqual([['lastUsedAt'], ['lastUsedAt']]);
392
+ // The connection's stamp is two statements: the first-use claim (its
393
+ // id, and never stamped), then — stamped before — the ordinary stamp.
394
+ expect(captured.updateTargets).toEqual([oauthTokens, agentConnections, agentConnections]);
395
+ expect(captured.set.map((s) => Object.keys(s))).toEqual([['lastUsedAt'], ['lastUsedAt'], ['lastUsedAt']]);
386
396
  expect(render(captured.where[1])).toMatchObject({ params: ['tok-row-1'] });
387
397
  expect(render(captured.where[2])).toMatchObject({ params: ['conn-1'] });
388
- expect(render(captured.where[2]).sql).toMatch(/"agent_connections"."id" = \$1/);
398
+ expect(render(captured.where[2]).sql).toMatch(/"agent_connections"."id" = \$1 and "agent_connections"."last_used_at" is null/);
399
+ expect(render(captured.where[3])).toMatchObject({ params: ['conn-1'] });
400
+ expect(render(captured.where[3]).sql).toMatch(/"agent_connections"."id" = \$1/);
389
401
  // The connection's stamp is throttled: a verify a moment later touches
390
402
  // the token row again but not the connection — a minute has not passed.
391
403
  await provider.verifyAccessToken('bevel-mcp_live');
392
404
  await new Promise((r) => setTimeout(r, 0));
393
- expect(captured.updateTargets).toEqual([oauthTokens, agentConnections, oauthTokens]);
405
+ expect(captured.updateTargets).toEqual([oauthTokens, agentConnections, agentConnections, oauthTokens]);
406
+ });
407
+
408
+ /**
409
+ * The FIRST stamp of a connection is the agent arriving — what the
410
+ * onboarding waits for — so the owner is told, once: the claim that took
411
+ * the row from never-used to now is the one that announces, and it is
412
+ * the only statement that run makes. A connection stamped before loses
413
+ * the claim, is stamped the ordinary way, and nobody is told.
414
+ */
415
+ it('announces an agent connection to its owner on its first use, and never again', async () => {
416
+ const row = {
417
+ id: 'tok-row-1', clientId: 'client-1', connectionId: 'conn-1', scope: 'mcp', resource: null,
418
+ expiresAt: new Date(Date.now() + 60_000), userId: 'user-1', userEmail: 'alice@example.com',
419
+ };
420
+ const events = { emit: vi.fn() };
421
+ const fresh = makeProvider([
422
+ [row],
423
+ undefined /* token touch */,
424
+ [{ userId: 'user-1', client: 'Claude' }] /* the claim: this request took the first stamp */,
425
+ ]);
426
+ const freshProvider = new BevelOAuthProvider({ ...providerDeps(fresh.db), events });
427
+ await freshProvider.verifyAccessToken('bevel-mcp_live');
428
+ await new Promise((r) => setTimeout(r, 0));
429
+ expect(events.emit).toHaveBeenCalledTimes(1);
430
+ expect(events.emit).toHaveBeenCalledWith({
431
+ kind: 'agent-connected',
432
+ forUserId: 'user-1',
433
+ client: 'Claude',
434
+ agentKind: 'agent',
435
+ at: expect.stringMatching(/^\d{4}-\d{2}-\d{2}T/),
436
+ });
437
+ // The claim WAS the stamp: no second write for the winner.
438
+ expect(fresh.captured.updateTargets).toEqual([oauthTokens, agentConnections]);
439
+
440
+ const used = makeProvider([
441
+ [row],
442
+ undefined,
443
+ [] /* the claim lost: stamped before (or by a racing request) */,
444
+ undefined /* the ordinary stamp */,
445
+ ]);
446
+ const usedEvents = { emit: vi.fn() };
447
+ await new BevelOAuthProvider({ ...providerDeps(used.db), events: usedEvents }).verifyAccessToken('bevel-mcp_live');
448
+ await new Promise((r) => setTimeout(r, 0));
449
+ expect(usedEvents.emit).not.toHaveBeenCalled();
450
+ expect(used.captured.updateTargets).toEqual([oauthTokens, agentConnections, agentConnections]);
394
451
  });
395
452
 
396
453
  it('revokeToken (RFC 7009) ends the agent connection once no live token remains on it, as the owner\'s doing', async () => {
@@ -8,6 +8,7 @@ import {
8
8
  ListToolsRequestSchema,
9
9
  isInitializeRequest,
10
10
  type CallToolResult,
11
+ type ListToolsResult,
11
12
  } from '@modelcontextprotocol/sdk/types.js';
12
13
 
13
14
  /**
@@ -44,6 +45,13 @@ export interface FakeDownstreamOptions {
44
45
  * revoked or expired token with.
45
46
  */
46
47
  acceptsToken?: (token: string) => boolean;
48
+ /**
49
+ * What `tools/list` answers, in place of the single `echo` tool. A FUNCTION,
50
+ * read per request, so a test can have the server correct a schema between
51
+ * two discoveries the way a vendor's fix reaches us — through the next load,
52
+ * with nothing restarted here.
53
+ */
54
+ tools?: () => Array<{ name: string; description?: string; inputSchema: unknown }>;
47
55
  }
48
56
 
49
57
  export async function startFakeDownstreamMcpServer(opts: FakeDownstreamOptions = {}): Promise<FakeDownstreamMcpServer> {
@@ -55,13 +63,16 @@ export async function startFakeDownstreamMcpServer(opts: FakeDownstreamOptions =
55
63
  function buildServer(): Server {
56
64
  const server = new Server({ name: 'downstream', version: '0.0.0' }, { capabilities: { tools: {} } });
57
65
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
58
- tools: [
66
+ // Cast because a test may deliberately advertise a schema that is NOT
67
+ // valid JSON Schema, which is precisely what the SDK's type forbids and
68
+ // what a real server is free to send.
69
+ tools: (opts.tools?.() ?? [
59
70
  {
60
71
  name: 'echo',
61
72
  description: 'Return the text it was given.',
62
- inputSchema: { type: 'object' as const, properties: { text: { type: 'string' } } },
73
+ inputSchema: { type: 'object', properties: { text: { type: 'string' } } },
63
74
  },
64
- ],
75
+ ]) as unknown as ListToolsResult['tools'],
65
76
  }));
66
77
  server.setRequestHandler(CallToolRequestSchema, async (request): Promise<CallToolResult> => {
67
78
  executions += 1;
@@ -68,15 +68,50 @@ describe('toListedTool', () => {
68
68
  ...over,
69
69
  });
70
70
 
71
- it('passes a conforming tool through', () => {
71
+ it('passes a conforming tool through, its call example first', () => {
72
72
  const listed = toListedTool(proxied({ mcpName: 'gmail_send_email' }));
73
73
  expect(listed).toEqual({
74
74
  name: 'gmail_send_email',
75
- description: 'a tool',
75
+ description: 'Call: m.t({})\n\na tool',
76
76
  inputSchema: { type: 'object', properties: {} },
77
77
  });
78
78
  });
79
79
 
80
+ it('generates the example from the tool\'s own schema, in the shape it really takes', () => {
81
+ const platform = toListedTool(
82
+ proxied({
83
+ utcpName: 'KNOWLEDGE_BASE.read_file',
84
+ mcpName: 'read_file',
85
+ inputSchema: {
86
+ type: 'object',
87
+ properties: {
88
+ body: {
89
+ type: 'object',
90
+ properties: { branch: { type: 'string' }, path: { type: 'string' }, limit: { type: 'integer' } },
91
+ required: ['branch', 'path'],
92
+ },
93
+ },
94
+ required: ['body'],
95
+ } as never,
96
+ }),
97
+ )!;
98
+ expect(platform.description.split('\n')[0]).toBe(
99
+ 'Call: KNOWLEDGE_BASE.read_file({ body: { branch: "...", path: "..." } })',
100
+ );
101
+ const flat = toListedTool(
102
+ proxied({
103
+ utcpName: 'NS.search',
104
+ mcpName: 'NS_search',
105
+ inputSchema: {
106
+ type: 'object',
107
+ properties: { query: { type: 'string' }, limit: { type: 'integer' } },
108
+ required: ['query'],
109
+ } as never,
110
+ }),
111
+ )!;
112
+ expect(flat.description.split('\n')[0]).toBe('Call: NS.search({ query: "..." })');
113
+ });
114
+
80
115
  it('drops a tool whose name is too long or has illegal chars (so it cannot blank the whole list)', () => {
81
116
  expect(toListedTool(proxied({ mcpName: 'has spaces' }))).toBeNull();
82
117
  expect(toListedTool(proxied({ mcpName: 'a'.repeat(129) }))).toBeNull();
@@ -0,0 +1,200 @@
1
+ import type { Server as HttpServer } from 'node:http';
2
+ import type { AddressInfo } from 'node:net';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import express, { type RequestHandler } from 'express';
6
+ import { afterEach, describe, expect, it } from 'vitest';
7
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
8
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
9
+ import { MCP_APP_MIME_TYPE, MCP_APP_UI_META_KEY } from '@bevel-software/platform-mcp-core';
10
+ import { createMcpRoutes } from '../mcp.routes.js';
11
+ import { McpService } from '../mcp.service.js';
12
+ import { SpillStore } from '../../workspace/spill-store.js';
13
+ import { createManualRoutes } from '../../tool-registry/manual.routes.js';
14
+ import { ToolRegistry } from '../../tool-registry/tool-registry.js';
15
+ import { toolDef } from '../../tool-helpers/tool-def.js';
16
+ import { McpAppService, OPEN_PAGE_VIEW_URI_PREFIX } from '../../embed/mcp-app.js';
17
+ import { OPEN_PAGE_TOOL } from '../../embed/embed.tools.js';
18
+
19
+ /**
20
+ * The MCP App, over the REAL Streamable-HTTP transport with the official SDK
21
+ * client — the criterion as a host actually observes it: `tools/list` carries
22
+ * the view on `open_page`, `resources/list` offers it under the MCP App media
23
+ * type, and `resources/read` hands back the view with the framing metadata.
24
+ */
25
+
26
+ const KEY = 'bevel_key_user_a';
27
+ const PUBLIC = 'https://hexis.example';
28
+
29
+ const bearerOf = (req: express.Request) => (req.headers.authorization ?? '').replace(/^Bearer\s+/i, '');
30
+ const fakeAuth: RequestHandler = (req, res, next) => {
31
+ if (bearerOf(req) !== KEY) {
32
+ res.status(401).json({ error: 'unauthorized' });
33
+ return;
34
+ }
35
+ req.userId = 'user-A';
36
+ req.externalApiKeyId = 'tok-A';
37
+ next();
38
+ };
39
+
40
+ let httpServer: HttpServer | null = null;
41
+ let client: Client | null = null;
42
+
43
+ afterEach(async () => {
44
+ await client?.close().catch(() => undefined);
45
+ client = null;
46
+ if (httpServer) {
47
+ httpServer.closeAllConnections();
48
+ await new Promise<void>((r) => httpServer!.close(() => r()));
49
+ }
50
+ httpServer = null;
51
+ });
52
+
53
+ /** The platform: the real proxy, the real routes, and `open_page` in the catalog. */
54
+ async function connect(opts: { serveApps?: boolean } = {}) {
55
+ const app = express();
56
+ app.use(express.json());
57
+
58
+ const registry = new ToolRegistry();
59
+ for (const name of [OPEN_PAGE_TOOL, 'read_file']) {
60
+ registry.registerExternalTool(
61
+ toolDef({
62
+ name,
63
+ description: `the ${name} tool`,
64
+ path: `/api/agent/tools/${name}`,
65
+ inputs: { type: 'object', properties: { path: { type: 'string' } }, required: ['path'], additionalProperties: false },
66
+ }),
67
+ );
68
+ }
69
+ const toolRoutes = express.Router();
70
+ toolRoutes.use(createManualRoutes(registry, fakeAuth, async () => 'a@x.io'));
71
+ toolRoutes.post('/agent/tools/:name', (req, res) =>
72
+ res.json(
73
+ req.params.name === OPEN_PAGE_TOOL
74
+ ? { path: 'Data/Thing.md', content: '# Thing', embedUrl: `${PUBLIC}/embed?token=t`, appUrl: PUBLIC, branch: 'main' }
75
+ : { ok: true },
76
+ ),
77
+ );
78
+
79
+ httpServer = app.listen(0);
80
+ await new Promise<void>((r) => httpServer!.once('listening', () => r()));
81
+ const port = (httpServer.address() as AddressInfo).port;
82
+ const baseUrl = `http://127.0.0.1:${port}`;
83
+
84
+ const service = new McpService(
85
+ {
86
+ loopbackBaseUrl: baseUrl,
87
+ manualName: 'KNOWLEDGE_BASE',
88
+ spillStore: new SpillStore(join(tmpdir(), 'bevel-test-spills')),
89
+ publicFrontendUrl: PUBLIC,
90
+ },
91
+ undefined,
92
+ undefined,
93
+ undefined,
94
+ undefined,
95
+ undefined,
96
+ // A deployment with no apps is the degraded shape: no capability, no view.
97
+ opts.serveApps === false ? undefined : new McpAppService({ publicFrontendUrl: PUBLIC }),
98
+ );
99
+ const stub = {} as never;
100
+ app.use('/api', createMcpRoutes(service, stub, fakeAuth, fakeAuth, stub, stub, stub, ''));
101
+ app.use('/api', toolRoutes);
102
+
103
+ client = new Client({ name: 'test-host', version: '1.0.0' });
104
+ await client.connect(
105
+ new StreamableHTTPClientTransport(new URL(`${baseUrl}/api/mcp`), {
106
+ requestInit: { headers: { Authorization: `Bearer ${KEY}` } },
107
+ }),
108
+ );
109
+ return client;
110
+ }
111
+
112
+ /** The URI the packaged view is served under — named by its content, so read off the service. */
113
+ async function viewUri(): Promise<string> {
114
+ return (await new McpAppService({ publicFrontendUrl: PUBLIC }).manifest()).resources[0].uri;
115
+ }
116
+
117
+ describe('the hosted MCP endpoint serves the open_page view', () => {
118
+ it('lists open_page carrying UI metadata that names a ui:// resource', async () => {
119
+ const host = await connect();
120
+ const { tools } = await host.listTools();
121
+ const openPage = tools.find((t) => t.name === OPEN_PAGE_TOOL);
122
+ expect(openPage).toBeDefined();
123
+ expect(openPage!._meta).toEqual({ [MCP_APP_UI_META_KEY]: { resourceUri: await viewUri() } });
124
+ expect((await viewUri()).startsWith(OPEN_PAGE_VIEW_URI_PREFIX)).toBe(true);
125
+ // And only that tool: `read_file` is deliberately untouched.
126
+ expect(tools.find((t) => t.name === 'read_file')!._meta).toBeUndefined();
127
+ }, 30_000);
128
+
129
+ it('lists the view with the MCP App media type', async () => {
130
+ const host = await connect();
131
+ const { resources } = await host.listResources();
132
+ const uri = await viewUri();
133
+ const view = resources.find((r) => r.uri === uri);
134
+ expect(view).toBeDefined();
135
+ expect(view!.mimeType).toBe(MCP_APP_MIME_TYPE);
136
+ expect(view!._meta).toMatchObject({
137
+ [MCP_APP_UI_META_KEY]: { csp: { connectDomains: [PUBLIC], resourceDomains: [PUBLIC] } },
138
+ });
139
+ }, 30_000);
140
+
141
+ it('reads the view, reaching exactly the deployment own origin and asking for no sandbox domain', async () => {
142
+ const host = await connect();
143
+ const read = await host.readResource({ uri: await viewUri() });
144
+ expect(read.contents).toHaveLength(1);
145
+ const [content] = read.contents as Array<{ mimeType: string; text: string; _meta: Record<string, unknown> }>;
146
+ expect(content.mimeType).toBe(MCP_APP_MIME_TYPE);
147
+ expect(content.text).toContain('ui/initialize');
148
+ expect(content._meta[MCP_APP_UI_META_KEY]).toMatchObject({
149
+ csp: { connectDomains: [PUBLIC], resourceDomains: [PUBLIC] },
150
+ prefersBorder: false,
151
+ });
152
+ // No frames: a chat host's sandbox blocks them, so the view does not ask.
153
+ expect((content._meta[MCP_APP_UI_META_KEY] as { csp: Record<string, unknown> }).csp).not.toHaveProperty(
154
+ 'frameDomains',
155
+ );
156
+ // The host's default sandbox: the field's format is each host's own, and
157
+ // a value a host rejects is a view that never renders.
158
+ expect(content._meta[MCP_APP_UI_META_KEY]).not.toHaveProperty('domain');
159
+ }, 30_000);
160
+
161
+ it('refuses a resource it does not serve, naming the ones it does', async () => {
162
+ const host = await connect();
163
+ await expect(host.readResource({ uri: 'ui://hexis/not-a-view.html' })).rejects.toThrow(
164
+ /No resource at ui:\/\/hexis\/not-a-view\.html/,
165
+ );
166
+ }, 30_000);
167
+
168
+ /**
169
+ * A deployment that serves no view must not declare the capability: a
170
+ * client would list resources and be told the method does not exist, which
171
+ * reads as a broken endpoint rather than as "this one has no apps".
172
+ */
173
+ it('declares no resources capability when the deployment serves no app', async () => {
174
+ const host = await connect({ serveApps: false });
175
+ expect(host.getServerCapabilities()?.resources).toBeUndefined();
176
+ const { tools } = await host.listTools();
177
+ // Every tool is still listed, and still carries no view.
178
+ expect(tools.find((t) => t.name === OPEN_PAGE_TOOL)).toBeDefined();
179
+ expect(tools.find((t) => t.name === OPEN_PAGE_TOOL)!._meta).toBeUndefined();
180
+ }, 30_000);
181
+
182
+ /**
183
+ * The view frames `structuredContent.embedUrl` — it has nowhere else to
184
+ * read it — so a tool with a view must answer structured content as well
185
+ * as the text the model reads. A tool without one answers text alone.
186
+ */
187
+ it('answers open_page with structured content the view can read, and read_file without', async () => {
188
+ const host = await connect();
189
+ const opened = await host.callTool({ name: OPEN_PAGE_TOOL, arguments: { path: 'Data/Thing.md' } });
190
+ expect(opened.structuredContent).toMatchObject({ embedUrl: `${PUBLIC}/embed?token=t`, branch: 'main' });
191
+ expect((opened.content as Array<{ type: string; text: string }>)[0].text).toContain('embedUrl');
192
+ const read = await host.callTool({ name: 'read_file', arguments: { path: 'Data/Thing.md' } });
193
+ expect(read.structuredContent).toBeUndefined();
194
+ }, 30_000);
195
+
196
+ it('declares the resources capability when it does', async () => {
197
+ const host = await connect();
198
+ expect(host.getServerCapabilities()?.resources).toBeDefined();
199
+ }, 30_000);
200
+ });