@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
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Starter packs: the pages and the plugin a new knowledge base can be filled
3
+ * with in one click, chosen by what the team does.
4
+ *
5
+ * A pack is a folder under the packs root (`starter-packs/` in this package,
6
+ * or a distribution's `STARTER_PACKS_DIR`):
7
+ *
8
+ * <id>/pack.yaml id, name, description, order, firstPagePrompt, suggestedPages
9
+ * <id>/KnowledgeBase/… pages, under the DEFAULT layout's folder names
10
+ * <id>/Plugins/<name>/… a team plugin in the normal plugin layout
11
+ * <id>/Skills/… shared skills, if a pack carries any
12
+ *
13
+ * The three folders are written under the deployment's OWN names for them
14
+ * (`KnowledgeBase/` lands in whatever `knowledgeBaseDir` is), so a pack is
15
+ * authored once and fits every layout. Anything else in a pack folder (a
16
+ * README, notes for whoever maintains it) is the pack's, not the knowledge
17
+ * base's, and is never copied.
18
+ *
19
+ * A pack that does not read as one — no `pack.yaml`, a field missing or of
20
+ * the wrong kind, an id that is not its folder's name — is passed over with
21
+ * a warning: one broken folder must not take the choice away from everyone.
22
+ *
23
+ * The disk is read through the one walk and the one probe
24
+ * (`shared/fs.contract.ts`), handed in by the caller; only a file's bytes are
25
+ * read here, which neither contract covers.
26
+ */
27
+
28
+ import fs from 'node:fs/promises';
29
+ import path from 'node:path';
30
+ import { parse as parseYaml } from 'yaml';
31
+ import { renderKbLayoutPlaceholders, type KbLayout } from '@bevel-software/platform-shared';
32
+ import type { IFsProbe, ITreeWalker, WalkedEntry } from '../../shared/fs.contract.js';
33
+ import { logger } from '../../shared/logging.js';
34
+ import { utf8Text } from '../../shared/utf8-text.js';
35
+
36
+ const log = logger('starter-packs');
37
+
38
+ /** The file that makes a folder a pack. */
39
+ export const PACK_MANIFEST = 'pack.yaml';
40
+
41
+ /** The answer that chooses no pack: "Skip, I'll start from scratch". Never a pack's id. */
42
+ export const NO_STARTER_PACK = 'none';
43
+
44
+ /** A pack id: the folder's name, kebab-case, so it is safe in a URL, a setting and a path. */
45
+ const PACK_ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
46
+
47
+ /** The pack's own folders, by their default-layout names, and the layout key each one is written under. */
48
+ export const PACK_ROOTS: ReadonlyArray<readonly [string, keyof Pick<KbLayout, 'knowledgeBaseDir' | 'pluginsDir' | 'skillsDir'>]> = [
49
+ ['KnowledgeBase', 'knowledgeBaseDir'],
50
+ ['Plugins', 'pluginsDir'],
51
+ ['Skills', 'skillsDir'],
52
+ ];
53
+
54
+ /** What a chip shows, and the order the chips come in. */
55
+ export interface StarterPackSummary {
56
+ id: string;
57
+ name: string;
58
+ description: string;
59
+ order: number;
60
+ }
61
+
62
+ export interface StarterPack extends StarterPackSummary {
63
+ /** Replaces the generic "write your first page" request for a team that chose this pack. */
64
+ firstPagePrompt: string;
65
+ /** The pages the agent's first-run note offers to draft. */
66
+ suggestedPages: string[];
67
+ /** The pack's folder, absolute. */
68
+ dir: string;
69
+ }
70
+
71
+ /** One file a pack would add, at the path it would have in the knowledge base. */
72
+ export interface StarterPackFile {
73
+ /** Repository-relative, under the deployment's layout: `KnowledgeBase/About us.md`, `Plugins/x/skills/y/SKILL.md`. */
74
+ repoPath: string;
75
+ /** Which of the pack's folders it came from, by its default name. */
76
+ root: (typeof PACK_ROOTS)[number][0];
77
+ /** The bytes to write: text with the layout placeholders filled, or the file as it is. */
78
+ content: string | Buffer;
79
+ }
80
+
81
+ /**
82
+ * Every valid pack under `root`, chip order first (then name). A root that
83
+ * is not there offers no packs; it is not an error, since a distribution may
84
+ * ship none.
85
+ */
86
+ export async function loadStarterPacks(disk: IFsProbe, root: string): Promise<StarterPack[]> {
87
+ let entries: WalkedEntry[] | null;
88
+ try {
89
+ entries = await disk.listDir(root);
90
+ } catch (err) {
91
+ log.warn(`could not read the starter packs folder "${root}" — no packs offered:`, { err });
92
+ return [];
93
+ }
94
+ if (entries === null) return [];
95
+ const packs: StarterPack[] = [];
96
+ for (const entry of entries) {
97
+ if (!entry.isDirectory() || entry.name.startsWith('.')) continue;
98
+ const pack = await readStarterPack(disk, path.join(root, entry.name));
99
+ if (pack) packs.push(pack);
100
+ }
101
+ return packs.sort((a, b) => a.order - b.order || a.name.localeCompare(b.name));
102
+ }
103
+
104
+ /** The pack in `dir`, or null (with a warning saying why) when it does not read as one. */
105
+ export async function readStarterPack(disk: IFsProbe, dir: string): Promise<StarterPack | null> {
106
+ const folder = path.basename(dir);
107
+ let raw: string;
108
+ try {
109
+ raw = await disk.readTextFile(path.join(dir, PACK_MANIFEST));
110
+ } catch {
111
+ log.warn(`starter pack "${folder}" has no readable ${PACK_MANIFEST} — skipped.`);
112
+ return null;
113
+ }
114
+ let parsed: unknown;
115
+ try {
116
+ parsed = parseYaml(raw);
117
+ } catch (err) {
118
+ log.warn(`starter pack "${folder}": ${PACK_MANIFEST} is not valid YAML — skipped.`, {
119
+ error: err instanceof Error ? err.message : String(err),
120
+ });
121
+ return null;
122
+ }
123
+ const problem = packProblem(parsed, folder);
124
+ if (problem) {
125
+ log.warn(`starter pack "${folder}": ${problem} — skipped.`);
126
+ return null;
127
+ }
128
+ const m = parsed as Record<string, unknown>;
129
+ return {
130
+ id: m.id as string,
131
+ name: (m.name as string).trim(),
132
+ description: (m.description as string).trim(),
133
+ order: m.order as number,
134
+ firstPagePrompt: (m.firstPagePrompt as string).trim(),
135
+ suggestedPages: (m.suggestedPages as string[]).map((p) => p.trim()),
136
+ dir,
137
+ };
138
+ }
139
+
140
+ /** Why a parsed `pack.yaml` is not a pack, or null when it is one. */
141
+ export function packProblem(manifest: unknown, folder: string): string | null {
142
+ if (typeof manifest !== 'object' || manifest === null || Array.isArray(manifest)) {
143
+ return `${PACK_MANIFEST} is not a mapping`;
144
+ }
145
+ const m = manifest as Record<string, unknown>;
146
+ if (typeof m.id !== 'string' || !PACK_ID_RE.test(m.id)) return '`id` must be lowercase letters, digits and hyphens';
147
+ if (m.id !== folder) return `\`id\` ("${m.id}") must be the folder's name`;
148
+ if (m.id === NO_STARTER_PACK) return `"${NO_STARTER_PACK}" is reserved for skipping`;
149
+ for (const key of ['name', 'description', 'firstPagePrompt'] as const) {
150
+ if (typeof m[key] !== 'string' || !(m[key] as string).trim()) return `\`${key}\` must be a non-empty string`;
151
+ }
152
+ if (typeof m.order !== 'number' || !Number.isFinite(m.order)) return '`order` must be a number';
153
+ if (!Array.isArray(m.suggestedPages) || m.suggestedPages.some((p) => typeof p !== 'string' || !p.trim())) {
154
+ return '`suggestedPages` must be a list of page names';
155
+ }
156
+ return null;
157
+ }
158
+
159
+ /**
160
+ * Every file the pack would add, at its path under `layout`, in walk order.
161
+ * The knowledge-base walk lists them: dot-entries are left behind (an
162
+ * editor's or an OS's droppings, never content), and so is anything that is
163
+ * not a regular file — a pack is files. A pack folder that is not there, or
164
+ * is a file where a folder was expected, holds nothing; a folder in one that
165
+ * cannot be listed is the error, since a pack with a hole is not the pack.
166
+ */
167
+ export async function starterPackFiles(disk: ITreeWalker, pack: StarterPack, layout: Required<KbLayout>): Promise<StarterPackFile[]> {
168
+ const out: StarterPackFile[] = [];
169
+ for (const [root, layoutKey] of PACK_ROOTS) {
170
+ const base = path.join(pack.dir, root);
171
+ for (const rel of await disk.walkFiles(base, () => true, { strict: true })) {
172
+ const bytes = await fs.readFile(path.join(base, ...rel.split('/')));
173
+ const text = utf8Text(bytes);
174
+ out.push({
175
+ repoPath: `${layout[layoutKey]}/${rel}`,
176
+ root,
177
+ content: text === null ? bytes : renderKbLayoutPlaceholders(text, layout),
178
+ });
179
+ }
180
+ }
181
+ return out;
182
+ }
@@ -6,7 +6,11 @@ import { InternalTokenService } from '../../tool-auth/internal-token.service.js'
6
6
  import { createToolAuthMiddleware } from '../../tool-auth/tool-auth.middleware.js';
7
7
  import { keyOrSessionAuth } from '../../tool-auth/key-or-session.middleware.js';
8
8
  import { createAuthMiddleware } from '../../auth/auth.middleware.js';
9
- import { registerPluginsTools, CREATE_PLUGIN, MY_PLUGIN } from '../plugins.tools.js';
9
+ import { DEFAULT_KB_LAYOUT, validateKbLayout } from '@bevel-software/platform-shared';
10
+ import { testKbContext } from '../../../__tests__/kb-context.js';
11
+ import { CLIENT_SHORT_CUT, TOOL_DESCRIPTION_CAP, clientVisibleLength } from '../../tool-registry/description-length.js';
12
+ import { GUIDE_FIRST_SENTENCE } from '../../tool-registry/guide-first.js';
13
+ import { registerPluginsTools, CREATE_PLUGIN, myPluginDef, myPluginDescription } from '../plugins.tools.js';
10
14
  import { createPluginCreationRoutes } from '../plugins.routes.js';
11
15
  import { PluginProvisionError } from '../plugin-provision.service.js';
12
16
 
@@ -20,18 +24,165 @@ import { PluginProvisionError } from '../plugin-provision.service.js';
20
24
 
21
25
  const ALICE = { id: 'user-alice', email: 'alice@x.com', name: 'Alice' };
22
26
 
27
+ /** `my_plugin` as the catalog lists it for `layout`, on the external surface. */
28
+ async function listedMyPlugin(layout = DEFAULT_KB_LAYOUT): Promise<{ description: string }> {
29
+ const registry = new ToolRegistry();
30
+ registerPluginsTools(registry, testKbContext({ layout }));
31
+ const listed = (await registry.listExternal({ userEmail: ALICE.email })).find((t) => t.name === 'my_plugin');
32
+ expect(listed, 'my_plugin is not in the external catalog').toBeDefined();
33
+ return listed as { description: string };
34
+ }
35
+
36
+ /** The rule, in the words a client must be handed before any cut. */
37
+ const RULE = [
38
+ 'personal plugin',
39
+ 'their own skills and tools',
40
+ 'they go under the knowledge root',
41
+ 'ask where under the knowledge root',
42
+ 'restricted so only they can read it',
43
+ 'never write it here, even if asked',
44
+ ];
45
+
23
46
  describe('the tool definitions', () => {
24
47
  it('describe the creation endpoints, and reach every surface', async () => {
25
48
  expect((CREATE_PLUGIN.tool_call_template as { url: string }).url).toBe('${API_URL}/api/plugins');
26
- expect((MY_PLUGIN.tool_call_template as { url: string }).url).toBe('${API_URL}/api/plugins/personal');
49
+ expect((myPluginDef(DEFAULT_KB_LAYOUT).tool_call_template as { url: string }).url).toBe(
50
+ '${API_URL}/api/plugins/personal',
51
+ );
27
52
  const registry = new ToolRegistry();
28
- registerPluginsTools(registry);
53
+ registerPluginsTools(registry, testKbContext());
29
54
  for (const tools of [await registry.listExternal({ userEmail: ALICE.email }), await registry.listInternal({ userEmail: ALICE.email })]) {
30
55
  expect(tools.map((t) => t.name)).toEqual(expect.arrayContaining(['my_plugin', 'create_plugin']));
31
56
  }
32
57
  });
33
58
  });
34
59
 
60
+ /**
61
+ * What `my_plugin` TELLS an agent. A personal plugin holds its owner's skills
62
+ * and tools; nothing under the plugins root is in the knowledge graph and a
63
+ * personal plugin is readable only by its owner, so a note filed there is
64
+ * never found as knowledge again. The old description opened by calling the
65
+ * folder "their personal space in the knowledge base", which read as an
66
+ * invitation to file one. Pinned here because the text IS the change: nothing
67
+ * refuses such a write, before or after (see the last test in this block).
68
+ */
69
+ describe('what my_plugin tells an agent about the personal plugin', () => {
70
+ it('states the rule, naming this deployment\'s knowledge root', async () => {
71
+ const { description } = await listedMyPlugin();
72
+ expect(description).toContain("The caller's personal plugin: their own skills and tools");
73
+ expect(description).toContain('Notes, knowledge and other documents do NOT go here; they go under the knowledge root.');
74
+ expect(description).toContain('The knowledge root here is `KnowledgeBase/`.');
75
+ // A private request gets a QUESTION and the restrictable folder, never the
76
+ // personal plugin — not even when the user asks for it outright.
77
+ expect(description).toContain('ask where under the knowledge root it should go');
78
+ expect(description).toContain('restricted so only they can read it');
79
+ expect(description).toContain('never write it here, even if asked');
80
+ // The name the app shows, and none of the three phrases that sent agents here.
81
+ for (const retired of ['personal space', 'private space', 'own space']) {
82
+ expect(description, retired).not.toContain(retired);
83
+ }
84
+ });
85
+
86
+ it('names a RENAMED knowledge root, and never the default one', async () => {
87
+ const renamed = { knowledgeBaseDir: 'Docs', skillsDir: 'Abilities', pluginsDir: 'Extensions' };
88
+ const { description } = await listedMyPlugin(renamed);
89
+ expect(description).toContain('The knowledge root here is `Docs/`.');
90
+ expect(description).not.toContain('KnowledgeBase');
91
+ });
92
+
93
+ /**
94
+ * The save that completes first-run setup applies the names the admin just
95
+ * chose IN THAT REQUEST, with no restart, so a description built once at
96
+ * registration would go on naming a folder the deployment no longer has.
97
+ * Rewritten in place, which is why both surfaces see it: they hold the same
98
+ * object.
99
+ */
100
+ it('follows a layout applied after registration, on both surfaces', async () => {
101
+ const registry = new ToolRegistry();
102
+ const kb = testKbContext();
103
+ registerPluginsTools(registry, kb);
104
+ kb.applyLayout({ knowledgeBaseDir: 'Docs', skillsDir: 'Abilities', pluginsDir: 'Extensions' });
105
+ for (const tools of [await registry.listExternal(), await registry.listInternal()]) {
106
+ const description = tools.find((t) => t.name === 'my_plugin')!.description!;
107
+ expect(description).toContain('The knowledge root here is `Docs/`.');
108
+ expect(description).not.toContain('KnowledgeBase');
109
+ }
110
+ });
111
+
112
+ /**
113
+ * claude.ai cuts a tool description near `CLIENT_SHORT_CUT` characters, and
114
+ * it counts from the guide-first sentence the registry puts in front of every
115
+ * listed tool. So the rule has to be inside that window of the text A CLIENT
116
+ * IS HANDED, with the `skillsDir` mechanics — which the guide states in full
117
+ * anyway — as what a short client loses instead.
118
+ */
119
+ it(`states the whole rule within the first ${CLIENT_SHORT_CUT} characters a client is handed`, async () => {
120
+ for (const layout of [DEFAULT_KB_LAYOUT, { knowledgeBaseDir: 'Docs', skillsDir: 'Abilities', pluginsDir: 'Extensions' }]) {
121
+ const { description } = await listedMyPlugin(layout);
122
+ expect(description.startsWith(`${GUIDE_FIRST_SENTENCE} `), 'the opener is counted too').toBe(true);
123
+ const cut = description.slice(0, CLIENT_SHORT_CUT);
124
+ const root = layout.knowledgeBaseDir;
125
+ for (const phrase of [...RULE, `The knowledge root here is \`${root}/\`.`]) {
126
+ expect(cut, `"${phrase}" falls past the ${CLIENT_SHORT_CUT}-character cut`).toContain(phrase);
127
+ }
128
+ }
129
+ });
130
+
131
+ /**
132
+ * A folder name may run to 255 bytes. The root is named once, after the rule,
133
+ * so even the longest name a deployment can choose leaves the whole rule
134
+ * inside the cut and the whole text inside the cap.
135
+ */
136
+ it('keeps the rule inside the cut, and the text inside the cap, for the longest root name', async () => {
137
+ const longest = { knowledgeBaseDir: 'K'.repeat(255), skillsDir: 'Skills', pluginsDir: 'Plugins' };
138
+ expect(validateKbLayout(longest), 'the name is one a deployment may choose').toBeNull();
139
+ const listed = await listedMyPlugin(longest);
140
+ const cut = listed.description.slice(0, CLIENT_SHORT_CUT);
141
+ for (const phrase of RULE) {
142
+ expect(cut, `"${phrase}" falls past the ${CLIENT_SHORT_CUT}-character cut`).toContain(phrase);
143
+ }
144
+ expect(listed.description).toContain(`The knowledge root here is \`${longest.knowledgeBaseDir}/\`.`);
145
+ expect(clientVisibleLength({ name: 'my_plugin', description: listed.description })).toBeLessThanOrEqual(
146
+ TOOL_DESCRIPTION_CAP,
147
+ );
148
+ });
149
+
150
+ /** Only the description changed: the call an agent makes is the call it made. */
151
+ it('keeps its endpoint, inputs, outputs and tags exactly as they were', () => {
152
+ const def = myPluginDef(DEFAULT_KB_LAYOUT);
153
+ expect((def.tool_call_template as { url: string; http_method: string }).url).toBe('${API_URL}/api/plugins/personal');
154
+ expect((def.tool_call_template as { http_method: string }).http_method).toBe('POST');
155
+ // The flat inputs are wrapped under `body` by `toolDef`; `my_plugin` takes
156
+ // none, so the envelope is optional too and `my_plugin({})` is a call
157
+ // that matches (see `bodyEnvelope`).
158
+ expect(def.inputs).toEqual({
159
+ type: 'object',
160
+ properties: { body: { type: 'object', properties: {}, additionalProperties: false } },
161
+ additionalProperties: false,
162
+ });
163
+ expect(Object.keys((def.outputs as { properties: Record<string, unknown> }).properties)).toEqual([
164
+ 'path',
165
+ 'skillsDir',
166
+ 'folder',
167
+ 'name',
168
+ 'displayName',
169
+ 'created',
170
+ ]);
171
+ expect(def.tags).toEqual(['plugins', 'skills', 'write']);
172
+ // Byte-identical on every layout but the description.
173
+ const renamed = myPluginDef({ knowledgeBaseDir: 'Docs', skillsDir: 'Abilities', pluginsDir: 'Extensions' });
174
+ expect({ ...renamed, description: '' }).toEqual({ ...def, description: '' });
175
+ expect(renamed.description).not.toBe(def.description);
176
+ });
177
+
178
+ /** A layout given with untrimmed names is read the way every other reader reads it. */
179
+ it('reads the layout through the same resolver the rest of the platform uses', () => {
180
+ expect(myPluginDescription({ knowledgeBaseDir: ' Docs ', skillsDir: 'Skills', pluginsDir: 'Plugins' })).toContain(
181
+ '`Docs/`',
182
+ );
183
+ });
184
+ });
185
+
35
186
  describe('the creation endpoints behind the key-or-session gate', () => {
36
187
  const ensurePersonalPlugin = vi.fn(async (user: { id: string }) => ({
37
188
  folder: `personal-${user.id}`,
@@ -112,7 +263,7 @@ describe('the creation endpoints behind the key-or-session gate', () => {
112
263
  expect(createPlugin).toHaveBeenLastCalledWith(expect.objectContaining({ id: ALICE.id }), 'Ops', undefined);
113
264
  });
114
265
 
115
- it("my_plugin's endpoint ensures the caller's own space for a key holder", async () => {
266
+ it("my_plugin's endpoint ensures the caller's own personal plugin for a key holder", async () => {
116
267
  const base = await start();
117
268
  const res = await post(base, '/api/plugins/personal', {}, 'bevel_alice');
118
269
  expect(res.status).toBe(200);
@@ -129,4 +280,26 @@ describe('the creation endpoints behind the key-or-session gate', () => {
129
280
  expect(refused.status).toBe(404);
130
281
  expect(await refused.json()).toEqual({ error: 'There is no folder "Nope" under Plugins/.' });
131
282
  });
283
+
284
+ it('refuses an agent call whose arguments do not match the tool, before anything is provisioned', async () => {
285
+ // These two routes ARE the tools, so they check a call against what the
286
+ // tools declare, as every route-hosted tool does. `my_plugin` takes no
287
+ // arguments; `create_plugin` takes a non-empty `name` and an optional `parent`.
288
+ myPluginDef(DEFAULT_KB_LAYOUT);
289
+ const base = await start();
290
+ const stray = await post(base, '/api/plugins/personal', { unexpected: 1 }, 'bevel_alice');
291
+ expect(stray.status).toBe(400);
292
+ const strayBody = (await stray.json()) as { kind: string; error: string };
293
+ expect(strayBody.kind).toBe('arguments-do-not-match');
294
+ expect(strayBody.error).toContain('"unexpected" is not an argument of this tool.');
295
+ expect(strayBody.error.split('\n').pop()).toBe('Call: KNOWLEDGE_BASE.my_plugin({})');
296
+ expect(ensurePersonalPlugin).not.toHaveBeenCalled();
297
+
298
+ const empty = await post(base, '/api/plugins', { name: '' }, 'bevel_alice');
299
+ expect(empty.status).toBe(400);
300
+ expect(((await empty.json()) as { error: string }).error).toContain(
301
+ '"name" must be at least 1 character(s) long, but 0 was given.',
302
+ );
303
+ expect(createPlugin).not.toHaveBeenCalled();
304
+ });
132
305
  });
@@ -4,6 +4,7 @@ export {
4
4
  PluginProvisionError,
5
5
  pluginAccessMd,
6
6
  personalAccessMd,
7
+ withCreatorGrants,
7
8
  } from './plugin-provision.service.js';
8
9
  export { JoinRequestsService, type JoinRequest } from './join-requests.service.js';
9
10
  export {
@@ -151,6 +151,20 @@ export class PluginProvisionService {
151
151
  */
152
152
  private readonly creations = new WorkspaceMutex();
153
153
 
154
+ /**
155
+ * Run `fn` holding the creation lock of every plugin name in `names` — for
156
+ * a writer outside this service that publishes plugins of its own (a
157
+ * starter pack) and whose name check and commit must be one step against
158
+ * a creation or a deletion of the same name. The set is taken in one
159
+ * `runAll`; `fn` must not take this lock again (see `WorkspaceMutex`).
160
+ */
161
+ withIdentities<T>(names: string[], fn: () => Promise<T>): Promise<T> {
162
+ return this.creations.runAll(
163
+ names.map((name) => `plugin:${pluginManifestName(name)}`),
164
+ fn,
165
+ );
166
+ }
167
+
154
168
  constructor(
155
169
  private readonly workspaceService: WorkspaceService,
156
170
  private readonly commits: ProvisionCommitDriver,
@@ -693,7 +707,14 @@ export function personalAccessMd(creator: { name: string; email: string }): stri
693
707
  return spliceGrant(seeded, 'read', creatorPrincipal(creator), { allowScalar: false, target: 'node' }).text;
694
708
  }
695
709
 
696
- function withCreatorGrants(base: string, creator: { name: string; email: string }): string {
710
+ /**
711
+ * `base` — an access.md in the two-block shape — with `creator` named under
712
+ * `read`, `write` and `owner` of the folder: how a plugin made by someone is
713
+ * run by them. Exported for the one other door that brings a plugin into
714
+ * being, a starter pack (`modules/onboarding`), whose shipped rules it adds
715
+ * the admin who applied the pack to.
716
+ */
717
+ export function withCreatorGrants(base: string, creator: { name: string; email: string }): string {
697
718
  const principal = creatorPrincipal(creator);
698
719
  let out = base;
699
720
  for (const verb of ['read', 'write', 'owner'] as const) {
@@ -16,6 +16,7 @@ import { domainErrorBody } from '../../shared/http-errors.js';
16
16
  import { pluginFolderBelowRoot } from './plugins.service.js';
17
17
  import type { KbContext } from '../../shared/kb-context.js';
18
18
  import { PluginProvisionError, type PluginProvisionService } from './plugin-provision.service.js';
19
+ import { argumentsRefusal } from '../tool-helpers/route-argument-check.js';
19
20
  import { PluginLinkError, type PluginLinksService } from './plugin-links.service.js';
20
21
  import { PluginRenameError, type PluginRenameService } from './plugin-rename.service.js';
21
22
  import type { JoinRequestsService } from './join-requests.service.js';
@@ -64,6 +65,24 @@ import type {
64
65
  * middleware change can never silently un-gate one. Nothing here is reachable
65
66
  * with an agent connection key or a manual-auth bearer.
66
67
  */
68
+ /**
69
+ * Answer the arguments-do-not-match refusal when the body does not match the
70
+ * tool hosted at this route; `true` when it answered. A body that is not a
71
+ * JSON object is refused here too, with the sentence `toolHandler` uses, so a
72
+ * `null` or an array never reaches the handler as if it were `{}`.
73
+ */
74
+ function refuseMismatchedArguments(req: express.Request, res: express.Response): boolean {
75
+ const body: unknown = req.body === undefined ? {} : req.body;
76
+ if (typeof body !== 'object' || body === null || Array.isArray(body)) {
77
+ res.status(400).json({ error: 'Request body must be a JSON object.' });
78
+ return true;
79
+ }
80
+ const mismatch = argumentsRefusal(req.originalUrl, body as Record<string, unknown>, req.query);
81
+ if (!mismatch) return false;
82
+ res.status(mismatch.status).json({ ...mismatch.details, error: mismatch.message });
83
+ return true;
84
+ }
85
+
67
86
  /**
68
87
  * The two doors through which plugin folders come to exist — ONE
69
88
  * implementation each, for the app and for agents alike:
@@ -96,6 +115,11 @@ export function createPluginCreationRoutes(
96
115
  res.status(401).json({ error: 'Unauthenticated' });
97
116
  return;
98
117
  }
118
+ // These two routes ARE the `create_plugin` and `my_plugin` tools, so an
119
+ // agent's call is checked against what those tools declare, exactly as a
120
+ // route-hosted tool's is in `toolHandler`: a call that does not match is
121
+ // refused before anything is provisioned.
122
+ if (refuseMismatchedArguments(req, res)) return;
99
123
  // `req.body` is undefined when no JSON body was sent at all — that is a
100
124
  // 400, not a destructuring crash.
101
125
  const { name, parent } = (req.body ?? {}) as { name?: string; parent?: unknown };
@@ -129,6 +153,11 @@ export function createPluginCreationRoutes(
129
153
  res.status(401).json({ error: 'Unauthenticated' });
130
154
  return;
131
155
  }
156
+ // These two routes ARE the `create_plugin` and `my_plugin` tools, so an
157
+ // agent's call is checked against what those tools declare, exactly as a
158
+ // route-hosted tool's is in `toolHandler`: a call that does not match is
159
+ // refused before anything is provisioned.
160
+ if (refuseMismatchedArguments(req, res)) return;
132
161
  try {
133
162
  res.json(await provision.ensurePersonalPlugin(user));
134
163
  } catch (err) {
@@ -1,3 +1,5 @@
1
+ import { resolveKbLayout, type KbLayout } from '@bevel-software/platform-shared';
2
+ import type { KbContext } from '../../shared/kb-context.js';
1
3
  import type { IToolRegistry, UtcpTool } from '../tool-registry/tool.contract.js';
2
4
  import { toolDef } from '../tool-helpers/tool-def.js';
3
5
 
@@ -21,9 +23,24 @@ import { toolDef } from '../tool-helpers/tool-def.js';
21
23
  * agent exactly as for a person; a refusal comes back as the endpoint's own
22
24
  * 4xx with its message.
23
25
  */
24
- export function registerPluginsTools(registry: IToolRegistry): void {
25
- registry.registerExternalTool(MY_PLUGIN);
26
- registry.registerInternalTool(MY_PLUGIN);
26
+ export function registerPluginsTools(registry: IToolRegistry, kb: KbContext): void {
27
+ // ONE object on both surfaces, so the rewrite below reaches both of them.
28
+ // The registry holds this object, and re-registering under the same name
29
+ // would throw as a duplicate.
30
+ const myPlugin = myPluginDef(kb.layout);
31
+ registry.registerExternalTool(myPlugin);
32
+ registry.registerInternalTool(myPlugin);
33
+ /**
34
+ * `my_plugin`'s description NAMES the knowledge root, so its text has to
35
+ * follow the layout: the save that completes first-run setup applies the
36
+ * names the admin just chose in that same request, without a restart, and a
37
+ * description built once at registration would go on sending notes to a
38
+ * folder this deployment no longer has. Rewritten in place, exactly as the
39
+ * workspace tools' descriptions are (see `workspace.tools.ts`).
40
+ */
41
+ kb.onLayoutApplied(() => {
42
+ myPlugin.description = myPluginDescription(kb.layout);
43
+ });
27
44
  registry.registerExternalTool(CREATE_PLUGIN);
28
45
  registry.registerInternalTool(CREATE_PLUGIN);
29
46
  }
@@ -41,21 +58,64 @@ const PROVISIONED_OUTPUT = {
41
58
  },
42
59
  } as const;
43
60
 
44
- export const MY_PLUGIN: UtcpTool = toolDef({
45
- name: 'my_plugin',
46
- description:
47
- "The caller's own private plugin — their personal space in the knowledge base, created on first use. " +
61
+ /**
62
+ * What an agent reads about the personal plugin, for the layout in effect.
63
+ *
64
+ * THE RULE COMES FIRST, and the order is the substance of it rather than a
65
+ * matter of style. A personal plugin holds its owner's skills and tools;
66
+ * nothing under the plugins root is part of the knowledge graph, and a
67
+ * personal plugin is readable only by its owner — so a note filed there is
68
+ * never found as knowledge again, by anyone, including its author's next
69
+ * agent. Agents asked to "save this for me" were reading the old opening,
70
+ * "their personal space in the knowledge base", as an invitation to do
71
+ * precisely that.
72
+ *
73
+ * Stated ahead of the mechanics of writing a skill, not after them, because
74
+ * claude.ai cuts a tool description near `CLIENT_SHORT_CUT` characters (see
75
+ * `tool-registry/description-length.ts`) counted from the guide-first sentence
76
+ * the registry puts in front of every listed tool. What survives that cut is
77
+ * decided by ORDER, so the rule sits inside it and the `skillsDir` detail —
78
+ * which the guide states in full anyway — is what a short client loses.
79
+ * The root is named ONCE, after the rule rather than inside it: a folder name
80
+ * may run to 255 bytes, and repeated within the rule it could push the rule
81
+ * itself past the cut and the whole text past `TOOL_DESCRIPTION_CAP`.
82
+ * `plugins.tools.test.ts` pins that placement rather than trusting this note.
83
+ *
84
+ * It REFUSES nothing. The write gate accepts every file in a personal plugin
85
+ * exactly as it did before; this text is the whole of the change.
86
+ */
87
+ export function myPluginDescription(layout: KbLayout): string {
88
+ const knowledge = `\`${resolveKbLayout(layout).knowledgeBaseDir}/\``;
89
+ return (
90
+ "The caller's personal plugin: their own skills and tools, created on first use. " +
91
+ 'Notes, knowledge and other documents do NOT go here; they go under the knowledge root. ' +
92
+ 'For something the user wants kept private, ask where under the knowledge root it should go and say a ' +
93
+ 'folder there can be restricted so only they can read it; never write it here, even if asked. ' +
94
+ `The knowledge root here is ${knowledge}. ` +
48
95
  'Returns its folder and where skills go inside it (`skillsDir`); write a skill there as ' +
49
96
  '`<skillsDir>/<skill-name>/SKILL.md` with the file tools, opening with the Agent Skills frontmatter ' +
50
97
  '(`name`, `description`, and `metadata.version` such as `"1.0.0"`). Readable only by its owner — not even admins — and ' +
51
- 'never listed as a shared plugin. Idempotent: calling it again returns the same folder.',
52
- path: '/api/plugins/personal',
53
- inputs: { type: 'object', properties: {}, additionalProperties: false },
54
- outputs: PROVISIONED_OUTPUT,
55
- // `write`: both make folders and commit — a read-scoped caller's manual
56
- // must not advertise them (see `isWriteTool` in the manual routes).
57
- tags: ['plugins', 'skills', 'write'],
58
- });
98
+ 'never listed as a shared plugin. Idempotent: calling it again returns the same folder.'
99
+ );
100
+ }
101
+
102
+ /**
103
+ * The `my_plugin` definition for `layout`. Everything but the description is
104
+ * the same on every deployment and byte-identical to what it has always been:
105
+ * the same endpoint, the same (empty) inputs, the same outputs, the same tags.
106
+ */
107
+ export function myPluginDef(layout: KbLayout): UtcpTool {
108
+ return toolDef({
109
+ name: 'my_plugin',
110
+ description: myPluginDescription(layout),
111
+ path: '/api/plugins/personal',
112
+ inputs: { type: 'object', properties: {}, additionalProperties: false },
113
+ outputs: PROVISIONED_OUTPUT,
114
+ // `write`: both make folders and commit — a read-scoped caller's manual
115
+ // must not advertise them (see `isWriteTool` in the manual routes).
116
+ tags: ['plugins', 'skills', 'write'],
117
+ });
118
+ }
59
119
 
60
120
  export const CREATE_PLUGIN: UtcpTool = toolDef({
61
121
  name: 'create_plugin',