@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
@@ -14,13 +14,17 @@ import type { IExternalApiKeyService } from '../../tool-auth/external-api-key.in
14
14
  * update / delete` pops the next queued result. `transaction` runs its
15
15
  * callback against the same fake, so queued results are consumed in order.
16
16
  * Every `where` predicate and `update` target is captured, so a test can pin
17
- * WHICH rows a statement addressed (see {@link render}), not just that it ran.
17
+ * WHICH rows a statement addressed (see {@link render}), not just that it ran;
18
+ * `orderBy` and `limit` too, since the fake applies neither and a test can
19
+ * only pin WHICH row of several a read keeps by the clauses it sent.
18
20
  */
19
21
  function makeFakeDb(queue: unknown[]) {
20
- const captured: { values: any[]; set: any[]; where: SQL[]; updateTargets: unknown[] } = {
22
+ const captured: { values: any[]; set: any[]; where: SQL[]; orderBy: SQL[][]; limit: number[]; updateTargets: unknown[] } = {
21
23
  values: [],
22
24
  set: [],
23
25
  where: [],
26
+ orderBy: [],
27
+ limit: [],
24
28
  updateTargets: [],
25
29
  };
26
30
  const counts = { insert: 0, select: 0, update: 0, delete: 0 };
@@ -36,10 +40,10 @@ function makeFakeDb(queue: unknown[]) {
36
40
  chain.values = passthrough((a) => captured.values.push(a[0]));
37
41
  chain.set = passthrough((a) => captured.set.push(a[0]));
38
42
  chain.where = passthrough((a) => captured.where.push(a[0]));
39
- chain.limit = passthrough();
43
+ chain.limit = passthrough((a) => captured.limit.push(a[0]));
40
44
  chain.innerJoin = passthrough();
41
45
  chain.from = passthrough();
42
- chain.orderBy = passthrough();
46
+ chain.orderBy = passthrough((a) => captured.orderBy.push(a));
43
47
  chain.groupBy = passthrough();
44
48
  chain.returning = passthrough();
45
49
  chain.then = (onF: any, onR: any) => Promise.resolve(result).then(onF, onR);
@@ -355,6 +359,62 @@ describe('AgentAuditService.revokeConnection', () => {
355
359
  });
356
360
  });
357
361
 
362
+ /**
363
+ * The onboarding's "is your agent connected yet?". The page polls it, so the
364
+ * contract worth pinning is what it reads (one person's LIVE, USED rows of
365
+ * each kind — never the event log) and how the two kinds are combined.
366
+ */
367
+ describe('AgentAuditService.lastAgentUse', () => {
368
+ it('answers null when neither an agent connection nor a key has been used', async () => {
369
+ const { service, counts } = makeService([[] /* connections */, [] /* keys */]);
370
+ await expect(service.lastAgentUse(ALICE.id)).resolves.toBeNull();
371
+ expect(counts.select).toBe(2);
372
+ });
373
+
374
+ it("reads only the caller's live, used rows of each kind", async () => {
375
+ const { service, captured } = makeService([[], []]);
376
+ await service.lastAgentUse(ALICE.id);
377
+ const [connections, keys] = captured.where.map(render);
378
+ expect(connections!.sql).toContain('"agent_connections"."user_id" = $1');
379
+ expect(connections!.sql).toContain('"agent_connections"."revoked_at" is null');
380
+ expect(connections!.sql).toContain('"agent_connections"."last_used_at" is not null');
381
+ expect(connections!.params).toEqual([ALICE.id]);
382
+ expect(keys!.sql).toContain('"api_tokens"."user_id" = $1');
383
+ expect(keys!.sql).toContain('"api_tokens"."revoked_at" is null');
384
+ expect(keys!.sql).toContain('"api_tokens"."last_used_at" is not null');
385
+ expect(keys!.params).toEqual([ALICE.id]);
386
+ });
387
+
388
+ it('keeps the most recently used row of each kind, of however many a person has', async () => {
389
+ // The fake neither sorts nor limits, so what is pinned is what each read
390
+ // asks the database for: newest use first, one row.
391
+ const { service, captured } = makeService([[], []]);
392
+ await service.lastAgentUse(ALICE.id);
393
+ expect(captured.orderBy.map((clauses) => clauses.map((c) => render(c).sql))).toEqual([
394
+ ['"agent_connections"."last_used_at" desc'],
395
+ ['"api_tokens"."last_used_at" desc'],
396
+ ]);
397
+ expect(captured.limit).toEqual([1, 1]);
398
+ });
399
+
400
+ it("names an agent connection by its client, and an unnamed one as such", async () => {
401
+ const at = new Date(NOW - 60_000);
402
+ const named = makeService([[{ client: 'Claude', at }], []]);
403
+ await expect(named.service.lastAgentUse(ALICE.id)).resolves.toEqual({ at, client: 'Claude', kind: 'agent' });
404
+ const unnamed = makeService([[{ client: null, at }], []]);
405
+ await expect(unnamed.service.lastAgentUse(ALICE.id)).resolves.toEqual({ at, client: 'Unnamed agent', kind: 'agent' });
406
+ });
407
+
408
+ it('answers with the newer of the two when both kinds have been used', async () => {
409
+ const older = new Date(NOW - DAY);
410
+ const newer = new Date(NOW - 60_000);
411
+ const keyNewer = makeService([[{ client: 'Claude', at: older }], [{ client: 'Laptop', at: newer }]]);
412
+ await expect(keyNewer.service.lastAgentUse(ALICE.id)).resolves.toEqual({ at: newer, client: 'Laptop', kind: 'key' });
413
+ const agentNewer = makeService([[{ client: 'Claude', at: newer }], [{ client: 'Laptop', at: older }]]);
414
+ await expect(agentNewer.service.lastAgentUse(ALICE.id)).resolves.toEqual({ at: newer, client: 'Claude', kind: 'agent' });
415
+ });
416
+ });
417
+
358
418
  describe('retentionDaysFrom', () => {
359
419
  it('reads a positive whole number of days, and blank, zero or negative as forever', () => {
360
420
  expect(retentionDaysFrom('30')).toBe(30);
@@ -0,0 +1,102 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2
+ import express from 'express';
3
+ import type { Server } from 'node:http';
4
+ import { createAgentConnectionRoutes } from '../agent-connection.routes.js';
5
+ import type { AgentUse, IAgentConnectionStatus } from '../audit.contract.js';
6
+
7
+ /**
8
+ * GET /onboarding/agent-connection — what the connect-your-agent page polls.
9
+ * The contract worth pinning:
10
+ *
11
+ * - it answers for the AUTHENTICATED user (req.userId) and nobody else;
12
+ * nothing in the request — query or otherwise — can name another account;
13
+ * - "not yet" and "connected" are the two shapes, the second with when, as
14
+ * what, and whether that name is an agent's or a connection key's label;
15
+ * - the answer is never cached, since the next poll expects it to change;
16
+ * - a failure is a generic 500, never the driver's message.
17
+ */
18
+
19
+ const ALICE = 'u-alice';
20
+ const BOB = 'u-bob';
21
+ const CARA = 'u-cara';
22
+
23
+ const USES: Record<string, AgentUse> = {
24
+ [BOB]: { at: new Date(Date.UTC(2026, 9, 7, 12, 0, 0)), client: 'Claude', kind: 'agent' },
25
+ [CARA]: { at: new Date(Date.UTC(2026, 9, 7, 13, 0, 0)), client: 'Laptop', kind: 'key' },
26
+ };
27
+
28
+ const status = {
29
+ lastAgentUse: vi.fn(async (userId: string) => USES[userId] ?? null),
30
+ } satisfies IAgentConnectionStatus;
31
+
32
+ let server: Server | undefined;
33
+ afterEach(() => {
34
+ server?.close();
35
+ server = undefined;
36
+ vi.clearAllMocks();
37
+ vi.restoreAllMocks();
38
+ });
39
+
40
+ /** Mount the route with a stand-in auth middleware stamping `as` as the caller. */
41
+ async function listen(as: string): Promise<string> {
42
+ const app = express();
43
+ app.use((req, _res, next) => {
44
+ req.userId = as;
45
+ next();
46
+ });
47
+ app.use('/api', createAgentConnectionRoutes(status));
48
+ await new Promise<void>((resolve) => {
49
+ server = app.listen(0, resolve);
50
+ });
51
+ const address = server!.address();
52
+ if (typeof address === 'string' || !address) throw new Error('no port');
53
+ return `http://127.0.0.1:${address.port}`;
54
+ }
55
+
56
+ describe('GET /onboarding/agent-connection', () => {
57
+ it('says "not yet" for a caller whose agents have not been used', async () => {
58
+ const base = await listen(ALICE);
59
+ const res = await fetch(`${base}/api/onboarding/agent-connection`);
60
+ expect(res.status).toBe(200);
61
+ expect(await res.json()).toEqual({ connected: false });
62
+ expect(status.lastAgentUse).toHaveBeenCalledWith(ALICE);
63
+ });
64
+
65
+ it('says connected, with when and as what, once one has', async () => {
66
+ const base = await listen(BOB);
67
+ const res = await fetch(`${base}/api/onboarding/agent-connection`);
68
+ expect(await res.json()).toEqual({ connected: true, at: '2026-10-07T12:00:00.000Z', client: 'Claude', kind: 'agent' });
69
+ });
70
+
71
+ it("keeps a connection key's kind: its label says nothing about which app holds it", async () => {
72
+ const base = await listen(CARA);
73
+ const res = await fetch(`${base}/api/onboarding/agent-connection`);
74
+ expect(await res.json()).toEqual({ connected: true, at: '2026-10-07T13:00:00.000Z', client: 'Laptop', kind: 'key' });
75
+ });
76
+
77
+ it("answers for the caller alone — a named account in the query is not asked about", async () => {
78
+ const base = await listen(ALICE);
79
+ const res = await fetch(`${base}/api/onboarding/agent-connection?userId=${BOB}&user=${BOB}`);
80
+ expect(await res.json()).toEqual({ connected: false });
81
+ expect(status.lastAgentUse).toHaveBeenCalledTimes(1);
82
+ expect(status.lastAgentUse).toHaveBeenCalledWith(ALICE);
83
+ });
84
+
85
+ it('is never cached: the next poll expects a different answer', async () => {
86
+ const base = await listen(ALICE);
87
+ const res = await fetch(`${base}/api/onboarding/agent-connection`);
88
+ expect(res.headers.get('cache-control')).toBe('no-store');
89
+ });
90
+
91
+ it('reports a failed read as a generic 500, keeping the detail server-side', async () => {
92
+ const detail = 'connection to 10.0.0.4:5432 refused';
93
+ status.lastAgentUse.mockRejectedValueOnce(new Error(detail));
94
+ vi.spyOn(console, 'error').mockImplementation(() => {});
95
+ const base = await listen(ALICE);
96
+ const res = await fetch(`${base}/api/onboarding/agent-connection`);
97
+ expect(res.status).toBe(500);
98
+ const body = (await res.json()) as { error: string };
99
+ expect(body.error).toBe('Could not check your agent');
100
+ expect(body.error).not.toContain(detail);
101
+ });
102
+ });
@@ -1,7 +1,7 @@
1
- import { and, count, desc, eq, isNull, lt, or, type SQL } from 'drizzle-orm';
1
+ import { and, count, desc, eq, isNotNull, isNull, lt, or, type SQL } from 'drizzle-orm';
2
2
  import { logger } from '../../shared/logging.js';
3
3
  import type { Database } from '../database/connection.js';
4
- import { agentConnections, agentEvents, oauthTokens, users } from '../database/schema.js';
4
+ import { agentConnections, agentEvents, externalApiKeys, oauthTokens, users } from '../database/schema.js';
5
5
  import type { IExternalApiKeyService } from '../tool-auth/external-api-key.interface.js';
6
6
  import {
7
7
  AuditPrincipalNotFoundError,
@@ -11,10 +11,12 @@ import {
11
11
  type AgentEventInput,
12
12
  type AgentEventPage,
13
13
  type AgentEventView,
14
+ type AgentUse,
14
15
  type AuditPrincipal,
15
16
  type AuditPrincipalRef,
16
17
  type AuditScope,
17
18
  type IAgentAuditService,
19
+ type IAgentConnectionStatus,
18
20
  type IAgentEventRecorder,
19
21
  } from './audit.contract.js';
20
22
 
@@ -39,7 +41,7 @@ const PRUNE_INTERVAL_MS = 60 * 60_000;
39
41
  * Connection keys are read through the key service rather than joined here,
40
42
  * so their summary shape (kind, revoked-by, …) has exactly one definition.
41
43
  */
42
- export class AgentAuditService implements IAgentAuditService, IAgentEventRecorder {
44
+ export class AgentAuditService implements IAgentAuditService, IAgentEventRecorder, IAgentConnectionStatus {
43
45
  private lastPruneAt = 0;
44
46
 
45
47
  constructor(
@@ -242,6 +244,59 @@ export class AgentAuditService implements IAgentAuditService, IAgentEventRecorde
242
244
  };
243
245
  }
244
246
 
247
+ /**
248
+ * Whether one person's agent has reached the platform yet — what the
249
+ * onboarding asks once on arrival (the `agent-connected` event the stamp
250
+ * paths emit tells it the moment it changes). Two single-row reads on the
251
+ * per-user indexes, never a scan of the event log.
252
+ *
253
+ * Read from the `last_used_at` stamps, not from `agent_events`: an agent
254
+ * stamps its connection (or key) on its FIRST authenticated request — the
255
+ * `initialize` / `tools/list` every client sends straight after connecting
256
+ * — while an event is written only once it calls a tool, which may be
257
+ * never. The stamps are also outside the retention sweep, so "connected"
258
+ * cannot quietly turn back into "waiting" when old events are pruned.
259
+ *
260
+ * Live rows only: an agent its owner disconnected, or an admin revoked, is
261
+ * not a connected agent, whatever it did before. The key's columns are read
262
+ * here rather than through the key service because the service has no
263
+ * single-row read and this question needs only two columns of one row.
264
+ */
265
+ async lastAgentUse(userId: string): Promise<AgentUse | null> {
266
+ const [[agent], [key]] = await Promise.all([
267
+ this.db
268
+ .select({ client: agentConnections.clientName, at: agentConnections.lastUsedAt })
269
+ .from(agentConnections)
270
+ .where(
271
+ and(
272
+ eq(agentConnections.userId, userId),
273
+ isNull(agentConnections.revokedAt),
274
+ isNotNull(agentConnections.lastUsedAt),
275
+ ),
276
+ )
277
+ .orderBy(desc(agentConnections.lastUsedAt))
278
+ .limit(1),
279
+ this.db
280
+ .select({ client: externalApiKeys.label, at: externalApiKeys.lastUsedAt })
281
+ .from(externalApiKeys)
282
+ .where(
283
+ and(
284
+ eq(externalApiKeys.userId, userId),
285
+ isNull(externalApiKeys.revokedAt),
286
+ isNotNull(externalApiKeys.lastUsedAt),
287
+ ),
288
+ )
289
+ .orderBy(desc(externalApiKeys.lastUsedAt))
290
+ .limit(1),
291
+ ]);
292
+ const uses = [
293
+ agent?.at ? { at: agent.at, client: agent.client ?? 'Unnamed agent', kind: 'agent' as const } : null,
294
+ key?.at ? { at: key.at, client: key.client, kind: 'key' as const } : null,
295
+ ].filter((u): u is AgentUse => u !== null);
296
+ if (uses.length === 0) return null;
297
+ return uses.reduce((newest, u) => (u.at.getTime() > newest.at.getTime() ? u : newest));
298
+ }
299
+
245
300
  async revokeConnection(id: string, by: 'owner' | 'admin', ownerUserId?: string): Promise<void> {
246
301
  const scope = ownerUserId
247
302
  ? and(eq(agentConnections.id, id), eq(agentConnections.userId, ownerUserId))!
@@ -0,0 +1,56 @@
1
+ import express from 'express';
2
+ import { logger } from '../../shared/logging.js';
3
+ import type { IAgentConnectionStatus } from './audit.contract.js';
4
+ import '../auth/auth.middleware.js'; // Express Request augmentation (req.userId)
5
+
6
+ const log = logger('audit');
7
+
8
+ /** What the onboarding reads: connected or not, and — once connected — when, as what, and through which kind of credential. */
9
+ export interface AgentConnectionResponse {
10
+ connected: boolean;
11
+ /** The agent's most recent call, ISO 8601. */
12
+ at?: string;
13
+ /** The agent's registered client name, or the connection key's label. */
14
+ client?: string;
15
+ /**
16
+ * Which of the two `client` is: `agent` for an OAuth connection's
17
+ * registered name, `key` for a connection key's free-text label. Only an
18
+ * `agent` name says which app connected.
19
+ */
20
+ kind?: 'agent' | 'key';
21
+ }
22
+
23
+ /**
24
+ * GET /api/onboarding/agent-connection — "has an agent of mine reached the
25
+ * platform yet?", JWT-only (mounted behind the session middleware).
26
+ *
27
+ * The connect-your-agent page and the Get set up list ask it once on
28
+ * arrival, and again when the person comes back to the tab; the moment it
29
+ * changes is told by the `agent-connected` event the use-stamp paths emit
30
+ * over the event stream, so nothing asks on a timer. It answers for the
31
+ * CALLER alone: the user is the token's, and nothing in the request can name
32
+ * anyone else — there is no parameter to try.
33
+ *
34
+ * `no-store` because the answer is expected to change between two asks; a
35
+ * cached "not yet" would keep a page waiting on an agent that has already
36
+ * arrived.
37
+ */
38
+ export function createAgentConnectionRoutes(status: IAgentConnectionStatus): express.Router {
39
+ const router = express.Router();
40
+
41
+ router.get('/onboarding/agent-connection', async (req, res) => {
42
+ res.set('Cache-Control', 'no-store');
43
+ try {
44
+ const use = await status.lastAgentUse(req.userId!);
45
+ const body: AgentConnectionResponse = use
46
+ ? { connected: true, at: use.at.toISOString(), client: use.client, kind: use.kind }
47
+ : { connected: false };
48
+ res.json(body);
49
+ } catch (err) {
50
+ log.error('agent connection status failed:', { err });
51
+ res.status(500).json({ error: 'Could not check your agent' });
52
+ }
53
+ });
54
+
55
+ return router;
56
+ }
@@ -121,6 +121,32 @@ export interface IAgentAuditService {
121
121
  revokeConnection(id: string, by: 'owner' | 'admin', ownerUserId?: string): Promise<void>;
122
122
  }
123
123
 
124
+ /**
125
+ * The most recent use of any of one person's live agents: when, what it
126
+ * calls itself (the agent's registered client name, or the key's label), and
127
+ * which of the two that name is.
128
+ */
129
+ export interface AgentUse {
130
+ at: Date;
131
+ client: string;
132
+ /**
133
+ * `agent`: an OAuth connection, and `client` is the name the agent
134
+ * registered. `key`: a connection key, and `client` is whatever label its
135
+ * owner typed — it says nothing about which app holds the key.
136
+ */
137
+ kind: 'agent' | 'key';
138
+ }
139
+
140
+ /**
141
+ * The onboarding's "is your agent connected yet?" — answered for ONE person,
142
+ * from the use stamps the auth paths already write, so it costs two indexed
143
+ * single-row reads and records nothing new.
144
+ */
145
+ export interface IAgentConnectionStatus {
146
+ /** The newest use among the person's live agent connections and connection keys; null when none has been used. */
147
+ lastAgentUse(userId: string): Promise<AgentUse | null>;
148
+ }
149
+
124
150
  export class AuditPrincipalNotFoundError extends Error {
125
151
  constructor() {
126
152
  super('No such agent or key');
@@ -2,6 +2,7 @@ export * from './audit.contract.js';
2
2
  export { AgentAuditService, MAX_EVENT_PAGE, retentionDaysFrom } from './agent-audit.service.js';
3
3
  export { createAgentRestAuditMiddleware } from './agent-rest-audit.middleware.js';
4
4
  export { createAuditRoutes } from './audit.routes.js';
5
+ export { createAgentConnectionRoutes, type AgentConnectionResponse } from './agent-connection.routes.js';
5
6
  export { RequestAudit } from './request-audit.js';
6
7
  export {
7
8
  classifyToolCall,
@@ -67,6 +67,8 @@ describe('account routes — admin gate', () => {
67
67
  body: JSON.stringify({ email: 'x@example.com', password: 'long-enough-pw' }),
68
68
  });
69
69
  expect(create.status).toBe(403);
70
+ // Not an admission refusal: nothing here may read as "no seat left".
71
+ expect(await create.json()).toEqual({ error: 'Admins only' });
70
72
  expect(authService.createAccount).not.toHaveBeenCalled();
71
73
  });
72
74
 
@@ -151,7 +153,7 @@ describe('account routes — admin gate', () => {
151
153
  expect(accountErasure.eraseUser).toHaveBeenLastCalledWith('u2');
152
154
  });
153
155
 
154
- it('an account the admission port refuses → 403 carrying the port\'s own words', async () => {
156
+ it('an account the admission port refuses → 403 carrying the port\'s own words, marked as an admission refusal', async () => {
155
157
  const base = await listen(makeApp({ admin: true }));
156
158
  vi.mocked(authService.createAccount).mockRejectedValueOnce(
157
159
  new AccountAdmissionRefusedError('No seat left on this plan'),
@@ -162,7 +164,7 @@ describe('account routes — admin gate', () => {
162
164
  body: JSON.stringify({ email: 'b@example.com', password: 'long-enough-pw' }),
163
165
  });
164
166
  expect(refused.status).toBe(403);
165
- expect(((await refused.json()) as { error: string }).error).toBe('No seat left on this plan');
167
+ expect(await refused.json()).toEqual({ error: 'No seat left on this plan', kind: 'admission' });
166
168
  });
167
169
 
168
170
  it('erasure failure → 500 with a generic body (no internal error text)', async () => {
@@ -370,7 +372,7 @@ describe('account routes — switching an account off and on', () => {
370
372
  const base = await listen(makeApp({ admin: true }));
371
373
  const res = await post(base, 'u2/reactivate');
372
374
  expect(res.status).toBe(403);
373
- expect(((await res.json()) as { error: string }).error).toBe('All 3 seats are taken');
375
+ expect(await res.json()).toEqual({ error: 'All 3 seats are taken', kind: 'admission' });
374
376
  });
375
377
 
376
378
  it('answers a refused deactivation (the deployment admin, say) with 400 and the reason', async () => {
@@ -73,7 +73,13 @@ export function createAccountRoutes(
73
73
  const msg = error instanceof Error ? error.message : 'Unknown error';
74
74
  // The deployment has no place for the account (a seat limit, say): the
75
75
  // port's own words, as a refusal rather than a malformed request.
76
- res.status(error instanceof AccountAdmissionRefusedError ? 403 : 400).json({ error: msg });
76
+ // `kind` tells it apart from `requireAdmin`'s 403, which a caller must
77
+ // not read as "no seat left".
78
+ if (error instanceof AccountAdmissionRefusedError) {
79
+ res.status(403).json({ error: msg, kind: 'admission' });
80
+ return;
81
+ }
82
+ res.status(400).json({ error: msg });
77
83
  }
78
84
  });
79
85
 
@@ -107,7 +113,8 @@ export function createAccountRoutes(
107
113
 
108
114
  // POST /api/admin/accounts/:userId/reactivate — switch it back on, if the
109
115
  // deployment has room: the admission port is asked, as for a new account
110
- // (a host that sells seats answers from its plan; 403 with its words).
116
+ // (a host that sells seats answers from its plan; 403 with its words and
117
+ // `kind: 'admission'`).
111
118
  router.post('/admin/accounts/:userId/reactivate', requireAdmin, async (req, res) => {
112
119
  const userId = String(req.params.userId);
113
120
  try {
@@ -119,7 +126,7 @@ export function createAccountRoutes(
119
126
  res.status(204).end();
120
127
  } catch (error) {
121
128
  if (error instanceof AccountAdmissionRefusedError) {
122
- res.status(403).json({ error: error.message });
129
+ res.status(403).json({ error: error.message, kind: 'admission' });
123
130
  return;
124
131
  }
125
132
  log.error('switching an account on failed:', { err: error });
@@ -30,7 +30,7 @@ export const AUTH_COOKIE_NAME = 'bevel_token';
30
30
  * beats the dep surface of a middleware. Returns `null` if the cookie
31
31
  * is absent or empty.
32
32
  */
33
- function readAuthCookie(req: Request): string | null {
33
+ export function readAuthCookie(req: Request): string | null {
34
34
  const header = req.headers.cookie;
35
35
  if (!header) return null;
36
36
  for (const segment of header.split(';')) {
@@ -27,6 +27,16 @@ vi.mock('../code-mode-names.js', async (importOriginal) => {
27
27
  }
28
28
  if (name === 'down.run') throw new Error('repository unavailable: ECONNREFUSED');
29
29
  if (name === 'solo.run') return { tool: { name: 'solo.run' }, utcpName: 'solo.run' };
30
+ if (name === 'kb.read_file') {
31
+ return {
32
+ tool: {
33
+ name: 'kb.read_file',
34
+ description: 'Read a file.',
35
+ inputs: { type: 'object', properties: { query: { type: 'string' } }, required: ['query'] },
36
+ },
37
+ utcpName: 'kb.read_file',
38
+ };
39
+ }
30
40
  return null;
31
41
  }),
32
42
  };
@@ -35,7 +45,8 @@ vi.mock('../code-mode-names.js', async (importOriginal) => {
35
45
  const { createToolsInfoTool } = await import('../code-mode.tool.js');
36
46
 
37
47
  const client = {
38
- toolToTypeScriptInterface: (tool: { name: string }) => `interface ${tool.name}`,
48
+ toolToTypeScriptInterface: (tool: { name: string; description?: string }) =>
49
+ tool.description ? `/** ${tool.description} */ interface ${tool.name}` : `interface ${tool.name}`,
39
50
  } as unknown as CodeModeUtcpClient;
40
51
 
41
52
  type ToolsInfoResult = { interfaces: string; not_found: string[]; errors?: string[] };
@@ -58,11 +69,16 @@ describe('tools_info', () => {
58
69
 
59
70
  it('omits the errors field entirely when every name resolves or misses cleanly', async () => {
60
71
  const result = await run(['solo.run', 'nope']);
61
- expect(result.interfaces).toBe('interface solo.run');
72
+ expect(result.interfaces).toBe('/** Call: solo.run({}) */ interface solo.run');
62
73
  expect(result.not_found).toEqual(['nope']);
63
74
  expect(result.errors).toBeUndefined();
64
75
  });
65
76
 
77
+ it('shows each tool with its Call: line, as the chain description promises', async () => {
78
+ const result = await run(['kb.read_file']);
79
+ expect(result.interfaces).toBe('/** Call: kb.read_file({ query: "..." })\n\nRead a file. */ interface kb.read_file');
80
+ });
81
+
66
82
  it('contains ONLY ambiguity — an outage rethrows instead of posing as partial success', async () => {
67
83
  await expect(run(['solo.run', 'down.run'])).rejects.toThrow(/repository unavailable/);
68
84
  });
@@ -11,6 +11,7 @@ import {
11
11
  chainExample,
12
12
  type ChainExampleTool,
13
13
  runToolChain,
14
+ withCallExample,
14
15
  } from '@bevel-software/platform-mcp-core';
15
16
  import type { SpillStore } from '../workspace/spill-store.js';
16
17
  import { utcpNameToTsInterfaceName, findToolByName, AmbiguousToolNameError } from './code-mode-names.js';
@@ -46,7 +47,8 @@ export function createCallToolChainTool(
46
47
  id: 'call_tool_chain',
47
48
  description: [
48
49
  CodeModeUtcpClient.AGENT_PROMPT_TEMPLATE,
49
- `Execute JavaScript code with direct access to all registered UTCP tools as hierarchical functions — call them as \`${ns}.<tool>({ body: { ...args } })\`, synchronous, no await.${worked} Every argument a tool declares REQUIRED must be present — for the knowledge-base tools that includes \`branch\`. The runtime is plain JavaScript — no type annotations or other TypeScript-only syntax — plus \`atob\`, \`btoa\`, \`TextEncoder\` and \`TextDecoder\` for base64 and UTF-8 bytes, as in a browser; there is no \`Buffer\`, no \`fetch\` and no \`require\`. Return the final value with \`return\`. Use \`list_tools\` and \`tools_info\` first to discover available tools and their interfaces.`,
50
+ `Execute JavaScript code with direct access to all registered UTCP tools as hierarchical functions, synchronous, no await.${worked} The runtime is plain JavaScript — no type annotations or other TypeScript-only syntax — plus \`atob\`, \`btoa\`, \`TextEncoder\` and \`TextDecoder\` for base64 and UTF-8 bytes, as in a browser; there is no \`Buffer\`, no \`fetch\` and no \`require\`. Return the final value with \`return\`. Use \`list_tools\` and \`tools_info\` first to discover available tools and their interfaces.`,
51
+ `There is NO single calling shape: some tools take their arguments under a \`body\` object, others take them flat. Call each tool as the \`Call:\` line at the top of its own description shows — it is generated from that tool's input schema, and every tool in \`${ns}\` has one. Every argument a tool declares REQUIRED must be present; for the knowledge-base tools that includes \`branch\`. Arguments that do not match the schema are refused before anything is sent or run, and the refusal carries the tool's interface.`,
50
52
  'Error handling inside the chain: a failing tool call THROWS, and the thrown error\'s `.message` holds the server\'s actual reason (e.g. a 403 with the explanation, not just a status code). If you catch it, surface `err.message` (and `err.status` / `err.data` when present) — NEVER `return { error: err }` or otherwise return the raw Error object, because an Error serializes to `{}` (its `message` is non-enumerable) and the reason is lost. If you don\'t need to handle it, just let it throw — the runtime already reports `err.message` back to you.',
51
53
  `Failures are answered, never dropped: a chain that throws comes back with \`success: false\` and the reason, and one that outlives \`timeout\` (default ${CHAIN_TIMEOUT_DEFAULT_MS} ms, maximum ${CHAIN_TIMEOUT_MAX_MS} ms) comes back saying it timed out — raise \`timeout\` or split the work and run it again. Either way your next tool call works as usual.`,
52
54
  'Large return values: if the returned value exceeds `max_output_size`, the full JSON is auto-spilled to a shared spill store (outside any workspace, never committed) and the response contains only a `__tool_chain_spill__/…` ref + a truncated marker. You can read the spill back with the regular `read_file` tool — pass that ref as `path` (its `branch` is ignored) plus `offset` / `limit` to slice it, never read a multi-MB file in full. Order of preference: (1) re-run `call_tool_chain` with a follow-up code chain that filters/maps the data inline and returns just what you need; (2) narrow the API call — shorter `fields`, tighter date window, lower `limit`; (3) last resort — `read_file` against the spill ref with `offset` / `limit`. The spill is read-only context only; do NOT use it as a way to persist KB content — for KB writes use the regular `write_file` / `edit_file` tools, which go through the lock/commit pipeline.',
@@ -176,7 +178,16 @@ export function createToolsInfoTool(client: CodeModeUtcpClient) {
176
178
  try {
177
179
  const found = await findToolByName(client, name);
178
180
  if (found) {
179
- interfaces.push(client.toolToTypeScriptInterface(found.tool));
181
+ // With its `Call:` line, as on the MCP surface (`meta-tools.ts`):
182
+ // the chain's description tells the agent to call each tool as
183
+ // that line shows, and this is where it reads the tool. The
184
+ // repository's tool is not ours to edit, so a copy carries it.
185
+ interfaces.push(
186
+ client.toolToTypeScriptInterface({
187
+ ...found.tool,
188
+ description: withCallExample(found.tool.description, found.utcpName, found.tool.inputs),
189
+ }),
190
+ );
180
191
  } else {
181
192
  notFound.push(name);
182
193
  }
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * CORE platform tables — the git-backed workspace/workflow, auth, access,
3
3
  * change requests, locks, the pending-commits queue, connection keys, MCP
4
- * OAuth, and the Secrets Vault. A core-only deployment migrates and runs on
5
- * exactly these tables.
4
+ * OAuth, the Secrets Vault, and the embed's Atlassian account links. A
5
+ * core-only deployment migrates and runs on exactly these tables.
6
6
  *
7
7
  * Enterprise-only tables (chat, routines, watchlist, connectors, LLM config,
8
- * SharePoint/Atlassian links, feedback, upload, kb-revalidation) live in
8
+ * SharePoint links, feedback, upload, kb-revalidation) live in
9
9
  * `enterprise-schema.ts`, which imports the FK targets (`users`,
10
10
  * `externalApiKeys`) from here. `schema.ts` re-exports both, so existing
11
11
  * imports keep working unchanged.
@@ -829,3 +829,33 @@ export const pluginJoinRequests = pgTable('plugin_join_requests', {
829
829
  sql`${t.status} IN ('pending', 'opened', 'failed')`,
830
830
  ),
831
831
  }));
832
+
833
+ /**
834
+ * Links an account from an outside system — today an Atlassian (Forge)
835
+ * account id — to a Hexis user, so an embed minted for that account resolves
836
+ * to a person whose read and write access the view obeys.
837
+ *
838
+ * KEPT UNDER ITS ENTERPRISE NAME, deliberately. The table was created by the
839
+ * Bevel Platform's own migration history before the embed moved into Hexis;
840
+ * an upgraded database already holds every link its Jira users made, and
841
+ * nobody is going to re-link. So the core migration creates it only if it is
842
+ * absent and adopts what is there otherwise (see
843
+ * `0017_atlassian_account_links.sql`), and the generic name this table
844
+ * deserves is not worth a data migration for a column nobody reads by name.
845
+ *
846
+ * Not sealed: an Atlassian account id is an opaque identifier from another
847
+ * system, which is the same reason the rest of those are left in the clear.
848
+ *
849
+ * PK is the account id — one Hexis user per Atlassian account — while one
850
+ * user may hold several account ids across sites, which is what `by_user`
851
+ * serves. Links die with the user (`onDelete: 'cascade'`): an erasure request
852
+ * must never be blocked by a leftover embed link.
853
+ */
854
+ export const atlassianAccountLinks = pgTable('atlassian_account_links', {
855
+ atlassianAccountId: text('atlassian_account_id').primaryKey(),
856
+ userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
857
+ createdAt: timestamp('created_at').defaultNow().notNull(),
858
+ updatedAt: timestamp('updated_at').defaultNow().notNull(),
859
+ }, (t) => ({
860
+ byUser: index('atlassian_account_links_by_user').on(t.userId),
861
+ }));