@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
@@ -49,6 +49,8 @@ interface Harness {
49
49
  server: Server;
50
50
  baseUrl: string;
51
51
  canDownload: ReturnType<typeof vi.fn>;
52
+ canReadBatch: ReturnType<typeof vi.fn>;
53
+ canDownloadBatch: ReturnType<typeof vi.fn>;
52
54
  canWrite: ReturnType<typeof vi.fn>;
53
55
  createFolderZip: ReturnType<typeof vi.fn>;
54
56
  }
@@ -70,14 +72,21 @@ async function makeHarness(opts: {
70
72
  return opts.canDownload;
71
73
  });
72
74
  const canWrite = vi.fn();
75
+ // The /file/raw route now read-gates before the download gate; these tests
76
+ // exercise the download verb, so reads pass.
77
+ const canReadBatch = vi.fn(async (_w: string, _e: string, paths: string[]) => new Map(paths.map((p) => [p, true])));
78
+ // Every entry of a folder is judged for download too; by default each gets
79
+ // the folder's own verdict.
80
+ const canDownloadBatch = vi.fn(async (_w: string, _e: string, paths: string[]) =>
81
+ new Map(paths.map((p) => [p, opts.canDownload])),
82
+ );
73
83
  const accessControl: IAccessControl = {
74
84
  canWrite,
75
85
  canWriteBatch: vi.fn(),
76
- // The /file/raw route now read-gates before the download gate; these tests
77
- // exercise the download verb, so reads pass.
78
86
  canRead: vi.fn(async () => true),
79
- canReadBatch: vi.fn(async (_w: string, _e: string, paths: string[]) => new Map(paths.map((p) => [p, true]))),
87
+ canReadBatch,
80
88
  canDownload,
89
+ canDownloadBatch,
81
90
  eligibleWriters: vi.fn(),
82
91
  eligibleWriterEmails: vi.fn(),
83
92
  invalidate: vi.fn(),
@@ -152,7 +161,7 @@ async function makeHarness(opts: {
152
161
  throw new Error(`Unexpected server.address() shape: ${JSON.stringify(addr)}`);
153
162
  }
154
163
  const port = (addr as AddressInfo).port;
155
- return { server, baseUrl: `http://127.0.0.1:${port}`, canDownload, canWrite, createFolderZip };
164
+ return { server, baseUrl: `http://127.0.0.1:${port}`, canDownload, canReadBatch, canDownloadBatch, canWrite, createFolderZip };
156
165
  }
157
166
 
158
167
  async function closeServer(server: Server): Promise<void> {
@@ -338,6 +347,8 @@ describe('GET /workspace/:id/folder/zip — gated on Download role', () => {
338
347
  expect(res.status).toBe(200);
339
348
  expect(res.headers.get('content-type')).toBe('application/zip');
340
349
  expect(res.headers.get('x-content-type-options')).toBe('nosniff');
350
+ // The archive holds one caller's verdicts, so a shared cache never keeps it.
351
+ expect(res.headers.get('cache-control')).toBe('private, no-store');
341
352
  const dispo = res.headers.get('content-disposition');
342
353
  expect(dispo).toBeTruthy();
343
354
  expect(dispo).toContain('attachment');
@@ -349,7 +360,43 @@ describe('GET /workspace/:id/folder/zip — gated on Download role', () => {
349
360
  // verb is resolved on its repo-relative form, and the service is handed the
350
361
  // repository path it was judged as.
351
362
  expect(h.canDownload).toHaveBeenCalledWith(WORKSPACE_ID, USER.email, 'Knowledge/Sales');
352
- expect(h.createFolderZip).toHaveBeenCalledWith(WORKSPACE_ID, `${KB}/Knowledge/Sales`);
363
+ expect(h.createFolderZip.mock.calls[0]!.slice(0, 2)).toEqual([WORKSPACE_ID, `${KB}/Knowledge/Sales`]);
364
+ });
365
+
366
+ it('judges every file the zip would pack: unreadable ones and undownloadable ones are left out', async () => {
367
+ h = await makeHarness({ canDownload: true });
368
+ // What the service finds under the folder; the route's filter decides.
369
+ const found = ['Knowledge/Sales/open.md', 'Knowledge/Sales/hidden.md', 'Knowledge/Sales/no-save.md'];
370
+ h.canReadBatch.mockImplementation(async (_w: string, _e: string, paths: string[]) =>
371
+ new Map(paths.map((p) => [p, p !== 'Knowledge/Sales/hidden.md'])),
372
+ );
373
+ h.canDownloadBatch.mockImplementation(async (_w: string, _e: string, paths: string[]) =>
374
+ new Map(paths.map((p) => [p, p !== 'Knowledge/Sales/no-save.md'])),
375
+ );
376
+ let packed: ReadonlySet<string> | null = null;
377
+ h.createFolderZip.mockImplementation(
378
+ async (_id: string, _p: string, include: (paths: string[]) => Promise<ReadonlySet<string>>) => {
379
+ packed = await include(found);
380
+ return ZIP_BYTES;
381
+ },
382
+ );
383
+
384
+ const res = await fetch(
385
+ `${h.baseUrl}/api/workspace/${WORKSPACE_ID}/folder/zip?path=${encodeURIComponent('Knowledge/Sales')}&download=1`,
386
+ );
387
+
388
+ expect(res.status).toBe(200);
389
+ expect([...packed!]).toEqual(['Knowledge/Sales/open.md']);
390
+ // Read first, then download on what is readable: a file the caller may
391
+ // not see is never asked about for download, so nothing about it is
392
+ // computed or counted.
393
+ expect(h.canReadBatch).toHaveBeenCalledWith(WORKSPACE_ID, USER.email, found);
394
+ expect(h.canDownloadBatch).toHaveBeenCalledWith(WORKSPACE_ID, USER.email, [
395
+ 'Knowledge/Sales/open.md',
396
+ 'Knowledge/Sales/no-save.md',
397
+ ]);
398
+ // The count covers the readable file left out, not the hidden one.
399
+ expect(res.headers.get('x-withheld-files')).toBe('1');
353
400
  });
354
401
 
355
402
  it('user without Download role gets 403 and no zip is built', async () => {
@@ -0,0 +1,190 @@
1
+ import type { Server } from 'node:http';
2
+ import type { AddressInfo } from 'node:net';
3
+ import fs from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import os from 'node:os';
6
+ import express from 'express';
7
+ import AdmZip from 'adm-zip';
8
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
9
+ import { testKbContext } from '../../../__tests__/kb-context.js';
10
+ import { NodeFs } from '../../kb-fs/node-fs.js';
11
+ import type { IWorkflowService } from '@bevel-software/platform-shared';
12
+ import type { ICreatorAccess } from '../../access-model/creator.js';
13
+ import type { IAdminAccessService } from '../../admin/admin.interface.js';
14
+ import type { WorkflowEventBus } from '../../workflow/event-bus.js';
15
+ import type { AuthService } from '../../auth/auth.service.js';
16
+ import { AccessControlService } from '../../access/access-control.service.js';
17
+ import { createWorkspaceRoutes } from '../workspace.routes.js';
18
+ import { WorkspaceService } from '../workspace.service.js';
19
+
20
+ /**
21
+ * The folder download over the REAL resolver and the REAL zip builder.
22
+ *
23
+ * `download` on a folder let the caller ask for its zip, and the zip then
24
+ * packed every file under the folder: no file was judged against its own
25
+ * rules, so a caller got files whose frontmatter denied them `download`, files
26
+ * whose frontmatter denied them `read`, and whole sub-folders a nested
27
+ * access.md closed to them — files the per-file route refused and the file
28
+ * tree never showed (found 2026-10-07). The four cases below are the ones
29
+ * that were verified leaking; each must now be absent from the archive, and
30
+ * the one the caller may download must still be in it.
31
+ */
32
+
33
+ const KB = 'knowledge-base';
34
+ const WORKSPACE_ID = 'target-company-state';
35
+
36
+ const stubCreatorAccess: ICreatorAccess = {
37
+ planForCreate: async () => null,
38
+ grantInExtractedFile: async () => null,
39
+ noteAccessFileWritten: () => {},
40
+ };
41
+
42
+ let caller = { id: 'user-1', email: 'ana@x.io', name: 'Ana' };
43
+
44
+ const ROLES_YAML = `roles:
45
+ Admin:
46
+ - admin@x.io
47
+ `;
48
+
49
+ /** The folder Ana may download, with the files the rules below decide over. */
50
+ const FILES: Record<string, string> = {
51
+ 'Shared/access.md': '---\n---\ndownload:\n - Ana <ana@x.io>\n',
52
+ 'Shared/Open.md': '# open\n',
53
+ 'Shared/Node-Deny-Download.md': '---\ndownload:\n - deny Ana <ana@x.io>\n---\n# no save\n',
54
+ 'Shared/Node-Deny-Read.md': '---\nread:\n - deny Ana <ana@x.io>\n---\n# hidden\n',
55
+ 'Shared/Inner/access.md': '---\n---\nread:\n - deny Ana <ana@x.io>\ndownload:\n - deny Ana <ana@x.io>\n',
56
+ 'Shared/Inner/Plan.md': '# hidden plan\n',
57
+ };
58
+
59
+ interface Harness {
60
+ server: Server;
61
+ baseUrl: string;
62
+ }
63
+
64
+ describe('GET /folder/zip judges every file it packs (real resolver, real zip)', () => {
65
+ let root: string;
66
+ let h: Harness | null = null;
67
+
68
+ beforeEach(async () => {
69
+ root = await fs.mkdtemp(path.join(os.tmpdir(), 'bevel-zip-access-'));
70
+ caller = { id: 'user-1', email: 'ana@x.io', name: 'Ana' };
71
+ });
72
+
73
+ afterEach(async () => {
74
+ if (h) {
75
+ await new Promise<void>((resolve, reject) => h!.server.close((e) => (e ? reject(e) : resolve())));
76
+ h = null;
77
+ }
78
+ await fs.rm(root, { recursive: true, force: true });
79
+ });
80
+
81
+ async function makeHarness(files: Record<string, string>): Promise<Harness> {
82
+ const workspaceDir = path.join(root, WORKSPACE_ID);
83
+ const repo = path.join(workspaceDir, KB);
84
+ // A `.git` folder is what makes the service adopt the clone without cloning.
85
+ await fs.mkdir(path.join(repo, '.git'), { recursive: true });
86
+ for (const [rel, contents] of Object.entries({ 'roles.yaml': ROLES_YAML, ...files })) {
87
+ const abs = path.join(repo, rel);
88
+ await fs.mkdir(path.dirname(abs), { recursive: true });
89
+ await fs.writeFile(abs, contents);
90
+ }
91
+
92
+ const workspaceService = new WorkspaceService(
93
+ root,
94
+ 'https://example.invalid/kb.git',
95
+ testKbContext({ kbDirName: KB }),
96
+ new NodeFs(),
97
+ );
98
+ const accessControl = new AccessControlService(workspaceService, KB, new NodeFs());
99
+ const authService = { getUserById: async () => caller } as unknown as AuthService;
100
+
101
+ const app = express();
102
+ app.use(express.json());
103
+ app.use('/api', (req, _res, next) => {
104
+ (req as unknown as { userId: string }).userId = caller.id;
105
+ next();
106
+ });
107
+ app.use(
108
+ '/api',
109
+ createWorkspaceRoutes(
110
+ workspaceService,
111
+ authService,
112
+ {} as unknown as IWorkflowService,
113
+ {} as unknown as WorkflowEventBus,
114
+ accessControl,
115
+ testKbContext({ kbDirName: KB }),
116
+ stubCreatorAccess,
117
+ { isAdmin: async () => false } as unknown as IAdminAccessService,
118
+ new NodeFs(),
119
+ ),
120
+ );
121
+ const server = await new Promise<Server>((resolve) => {
122
+ const s = app.listen(0, () => resolve(s));
123
+ });
124
+ const addr = server.address() as AddressInfo;
125
+ return { server, baseUrl: `http://127.0.0.1:${addr.port}` };
126
+ }
127
+
128
+ const zipOf = (base: string, folder: string) =>
129
+ fetch(`${base}/api/workspace/${WORKSPACE_ID}/folder/zip?path=${encodeURIComponent(folder)}&download=1`);
130
+
131
+ const entriesOf = async (res: Response) =>
132
+ new AdmZip(Buffer.from(await res.arrayBuffer()))
133
+ .getEntries()
134
+ .map((e) => e.entryName)
135
+ .sort();
136
+
137
+ it('packs the file the caller may download, and none of the ones their own rules withhold', async () => {
138
+ h = await makeHarness(FILES);
139
+
140
+ const res = await zipOf(h.baseUrl, `${KB}/Shared`);
141
+
142
+ expect(res.status).toBe(200);
143
+ expect(res.headers.get('content-type')).toBe('application/zip');
144
+ // Ana's archive, with Ana's verdicts: never served to anyone else from a cache.
145
+ expect(res.headers.get('cache-control')).toBe('private, no-store');
146
+ expect(await entriesOf(res)).toEqual(['Shared/Open.md', 'Shared/access.md']);
147
+ // One file Ana can see but not save is counted; the two she cannot see
148
+ // and the closed folder are not — the count says nothing the tree does not.
149
+ expect(res.headers.get('x-withheld-files')).toBe('1');
150
+ });
151
+
152
+ it('the per-file route agrees on every one of them', async () => {
153
+ h = await makeHarness(FILES);
154
+ const raw = (p: string) =>
155
+ fetch(`${h!.baseUrl}/api/workspace/${WORKSPACE_ID}/file/raw?path=${encodeURIComponent(`${KB}/${p}`)}&download=1`);
156
+
157
+ expect((await raw('Shared/Open.md')).status).toBe(200);
158
+ expect((await raw('Shared/Node-Deny-Download.md')).status).toBe(403);
159
+ expect((await raw('Shared/Node-Deny-Read.md')).status).toBe(403);
160
+ expect((await raw('Shared/Inner/Plan.md')).status).toBe(403);
161
+ });
162
+
163
+ it('still refuses the folder itself to someone with no download grant', async () => {
164
+ h = await makeHarness(FILES);
165
+ caller = { id: 'user-2', email: 'mallory@x.io', name: 'Mallory' };
166
+
167
+ const res = await zipOf(h.baseUrl, `${KB}/Shared`);
168
+
169
+ expect(res.status).toBe(403);
170
+ });
171
+
172
+ // `access.md` itself stays in HERE: this fixture's declares nothing for
173
+ // itself (its frontmatter is empty), so the folder's rules — which admit
174
+ // the caller — admit the file too. That is not a guarantee: an `access.md`
175
+ // is judged like any file, by its own frontmatter and the folder chain, and
176
+ // one whose frontmatter denies the caller its read is left out of the
177
+ // archive exactly as the single-file route would refuse it.
178
+ it('answers an archive holding only the grant file, not an error, when every content file is withheld', async () => {
179
+ h = await makeHarness({
180
+ 'Shared/access.md': '---\n---\ndownload:\n - Ana <ana@x.io>\n',
181
+ 'Shared/Only.md': '---\ndownload:\n - deny Ana <ana@x.io>\n---\n# no save\n',
182
+ });
183
+
184
+ const res = await zipOf(h.baseUrl, `${KB}/Shared`);
185
+
186
+ expect(res.status).toBe(200);
187
+ expect(await entriesOf(res)).toEqual(['Shared/access.md']);
188
+ expect(res.headers.get('x-withheld-files')).toBe('1');
189
+ });
190
+ });
@@ -136,14 +136,14 @@ describe('a platform file stays in its folder', () => {
136
136
  await fs.rm(h.workspaceDir, { recursive: true, force: true });
137
137
  });
138
138
 
139
- // Each of the four, at a place the platform reads it from. `access.md` and
140
- // `.bevelignore` are read wherever they sit; `roles.yaml` and `AGENTS.md`
141
- // are read from the repository root only.
139
+ // Each of the three, at a place the platform reads it from. `access.md` and
140
+ // `.bevelignore` are read wherever they sit; `roles.yaml` is read from the
141
+ // repository root only. (`AGENTS.md` is not among them: the agent guide is
142
+ // served from code, so a root `AGENTS.md` is the organisation's own page.)
142
143
  const PLATFORM_FILES = [
143
144
  { name: 'access.md', at: `${KB}/Sales/access.md` },
144
145
  { name: '.bevelignore', at: `${KB}/Sales/.bevelignore` },
145
146
  { name: 'roles.yaml', at: `${KB}/roles.yaml` },
146
- { name: 'AGENTS.md', at: `${KB}/AGENTS.md` },
147
147
  ];
148
148
 
149
149
  it.each(PLATFORM_FILES)('refuses a rename of $name with the sentence', async ({ name, at }) => {
@@ -188,13 +188,12 @@ describe('a platform file stays in its folder', () => {
188
188
  },
189
189
  );
190
190
 
191
- // The recovery move, for each of the four, from the place a misplaced copy
191
+ // The recovery move, for each of the three, from the place a misplaced copy
192
192
  // is actually found to the place the platform reads it.
193
193
  const RESTORES = [
194
194
  { name: 'access.md', from: `${KB}/Misplaced/access.md`, to: `${KB}/access.md`, dest: 'access.md' },
195
195
  { name: '.bevelignore', from: `${KB}/Misplaced/.bevelignore`, to: `${KB}/.bevelignore`, dest: '.bevelignore' },
196
196
  { name: 'roles.yaml', from: `${KB}/Misplaced/roles.yaml`, to: `${KB}/roles.yaml`, dest: 'roles.yaml' },
197
- { name: 'AGENTS.md', from: `${KB}/Misplaced/AGENTS.md`, to: `${KB}/AGENTS.md`, dest: 'AGENTS.md' },
198
197
  ];
199
198
 
200
199
  it.each(RESTORES)(
@@ -265,6 +264,14 @@ describe('a platform file stays in its folder', () => {
265
264
 
266
265
  expect(h.moveEntry).not.toHaveBeenCalled();
267
266
  expect(h.acquireLock).not.toHaveBeenCalled();
267
+
268
+ // A root `AGENTS.md` is NOT a platform file any more — the guide is served
269
+ // from code — so a note renamed to it is an ordinary move that lands.
270
+ const guide = await move(h, `${KB}/Sales/deal.md`, `${KB}/AGENTS.md`);
271
+ expect(guide.status).toBe(200);
272
+ expect(guide.body).toEqual({ status: 'moved' });
273
+ expect(h.moveEntry).toHaveBeenCalledTimes(1);
274
+ expect(h.moveEntry).toHaveBeenCalledWith(WORKSPACE_ID, `${KB}/Sales/deal.md`, `${KB}/AGENTS.md`);
268
275
  });
269
276
 
270
277
  it('a destination that fills up after the access check is caught under the lock', async () => {
@@ -318,11 +325,15 @@ describe('a platform file stays in its folder', () => {
318
325
  }
319
326
  });
320
327
 
321
- it('a nested roles.yaml or AGENTS.md is ordinary content and moves freely', async () => {
322
- // They are read from the root and nowhere else, so a nested file of
323
- // either name carries no platform meaning to protect.
328
+ it('a nested roles.yaml, and an AGENTS.md anywhere, are ordinary content and move freely', async () => {
329
+ // `roles.yaml` is read from the root and nowhere else, so a nested file
330
+ // of that name carries no platform meaning to protect. An `AGENTS.md` is
331
+ // never read as configuration: the platform's guide is served from code,
332
+ // so the organisation's own file moves and renames like any page, at the
333
+ // root included.
324
334
  expect((await move(h, `${KB}/Sales/roles.yaml`, `${KB}/Sales/old-roles.yaml`)).status).toBe(200);
325
335
  expect((await move(h, `${KB}/Sales/AGENTS.md`, `${KB}/Legal/AGENTS.md`)).status).toBe(200);
326
- expect(h.moveEntry).toHaveBeenCalledTimes(2);
336
+ expect((await move(h, `${KB}/AGENTS.md`, `${KB}/Handbook/AGENTS.md`)).status).toBe(200);
337
+ expect(h.moveEntry).toHaveBeenCalledTimes(3);
327
338
  });
328
339
  });
@@ -127,6 +127,13 @@ describe('a bootstrap in flight when the working copy is taken away', () => {
127
127
  const svc = service(runner);
128
128
  // Nothing on disk: this is a first clone, which is what takes seconds.
129
129
  const opening = svc.getOrCreateForBranch(BRANCH);
130
+ // Told, rather than handed a cached path to a working copy of the
131
+ // repository that was replaced — which every later read would ENOENT on,
132
+ // with nothing left to re-clone it. The expectation is attached NOW: the
133
+ // refusal lands somewhere inside the timer turns below, and a rejection
134
+ // with no handler on it across a turn is what Vitest reports as unhandled
135
+ // — a flake that failed the suite on CI with every test green.
136
+ const refused = expect(opening).rejects.toThrow(/replaced while the "main" working copy was being created/);
130
137
  await vi.waitFor(() => expect(calls.length).toBeGreaterThan(0));
131
138
 
132
139
  // The replacement lands while the clone runs.
@@ -139,9 +146,6 @@ describe('a bootstrap in flight when the working copy is taken away', () => {
139
146
  await new Promise((r) => setTimeout(r, 0));
140
147
  }
141
148
 
142
- // Told, rather than handed a cached path to a working copy of the
143
- // repository that was replaced — which every later read would ENOENT on,
144
- // with nothing left to re-clone it.
145
- await expect(opening).rejects.toThrow(/replaced while the "main" working copy was being created/);
149
+ await refused;
146
150
  });
147
151
  });
@@ -698,13 +698,55 @@ describe('WorkspaceService.createFolderZip', () => {
698
698
  }));
699
699
  }
700
700
 
701
+ /** The filter a caller with every permission passes: pack everything found. */
702
+ const ALL = async (paths: string[]) => new Set(paths);
703
+
704
+ it('packs only what the filter allows, and asks it once with every file as a repository path', async () => {
705
+ const dir = path.join(repoDir, 'judged');
706
+ await fs.mkdir(path.join(dir, 'inner'), { recursive: true });
707
+ await fs.writeFile(path.join(dir, 'open.md'), 'open');
708
+ await fs.writeFile(path.join(dir, 'withheld.md'), 'withheld');
709
+ await fs.writeFile(path.join(dir, 'inner', 'deep.md'), 'deep');
710
+ const asked: string[][] = [];
711
+ const include = async (paths: string[]) => {
712
+ asked.push([...paths].sort());
713
+ return new Set(paths.filter((p) => p !== 'judged/withheld.md'));
714
+ };
715
+
716
+ const buf = await svc.createFolderZip(workspaceId, 'judged', include);
717
+
718
+ // Asked once, with every file the walk found, keyed the way the access
719
+ // rules are: relative to the repository, not to the folder or the workspace.
720
+ expect(asked).toEqual([['judged/inner/deep.md', 'judged/open.md', 'judged/withheld.md']]);
721
+ const names = (await unzipEntries(buf)).map((e) => e.name).sort();
722
+ expect(names).toEqual(['judged/inner/deep.md', 'judged/open.md']);
723
+ });
724
+
725
+ it('keys the files the same way whether the folder is written with a trailing slash or not', async () => {
726
+ const dir = path.join(repoDir, 'slashed');
727
+ await fs.mkdir(dir, { recursive: true });
728
+ await fs.writeFile(path.join(dir, 'a.md'), 'a');
729
+ const asked: string[][] = [];
730
+ const include = async (paths: string[]) => {
731
+ asked.push(paths);
732
+ return new Set(paths);
733
+ };
734
+
735
+ await svc.createFolderZip(workspaceId, 'slashed/', include);
736
+ await svc.createFolderZip(workspaceId, `${'knowledge-base'}/slashed//`, include);
737
+
738
+ // A `slashed//a.md` key would match no verdict, and the filter would
739
+ // withhold the whole folder without a word.
740
+ expect(asked).toEqual([['slashed/a.md'], ['slashed/a.md']]);
741
+ });
742
+
701
743
  it('zips a folder prefixing entries with the folder name', async () => {
702
744
  const dir = path.join(repoDir, 'docs');
703
745
  await fs.mkdir(dir, { recursive: true });
704
746
  await fs.writeFile(path.join(dir, 'a.md'), 'alpha');
705
747
  await fs.writeFile(path.join(dir, 'b.md'), 'beta');
706
748
 
707
- const buf = await svc.createFolderZip(workspaceId, 'docs');
749
+ const buf = await svc.createFolderZip(workspaceId, 'docs', ALL);
708
750
  const entries = await unzipEntries(buf);
709
751
  const names = entries.map((e) => e.name).sort();
710
752
  expect(names).toEqual(['docs/a.md', 'docs/b.md']);
@@ -719,7 +761,7 @@ describe('WorkspaceService.createFolderZip', () => {
719
761
  await fs.writeFile(path.join(dir, 'nested', 'mid.md'), 'mid');
720
762
  await fs.writeFile(path.join(dir, 'nested', 'deep', 'leaf.md'), 'leaf');
721
763
 
722
- const buf = await svc.createFolderZip(workspaceId, 'tree');
764
+ const buf = await svc.createFolderZip(workspaceId, 'tree', ALL);
723
765
  const names = (await unzipEntries(buf)).map((e) => e.name).sort();
724
766
  expect(names).toEqual([
725
767
  'tree/nested/deep/leaf.md',
@@ -736,7 +778,7 @@ describe('WorkspaceService.createFolderZip', () => {
736
778
  await fs.writeFile(path.join(dir, '.gitkeep'), '');
737
779
  await fs.writeFile(path.join(dir, 'real.md'), 'real');
738
780
 
739
- const buf = await svc.createFolderZip(workspaceId, 'mixed');
781
+ const buf = await svc.createFolderZip(workspaceId, 'mixed', ALL);
740
782
  const names = (await unzipEntries(buf)).map((e) => e.name).sort();
741
783
  expect(names).toEqual(['mixed/real.md']);
742
784
  });
@@ -748,7 +790,7 @@ describe('WorkspaceService.createFolderZip', () => {
748
790
  await fs.writeFile(path.join(dir, 'public.md'), 'pub');
749
791
  await fs.writeFile(path.join(dir, 'secret.md'), 'shh');
750
792
 
751
- const buf = await svc.createFolderZip(workspaceId, 'with-ignore');
793
+ const buf = await svc.createFolderZip(workspaceId, 'with-ignore', ALL);
752
794
  const names = (await unzipEntries(buf)).map((e) => e.name).sort();
753
795
  expect(names).toContain('with-ignore/public.md');
754
796
  expect(names).not.toContain('with-ignore/secret.md');
@@ -756,17 +798,17 @@ describe('WorkspaceService.createFolderZip', () => {
756
798
 
757
799
  it('refuses to zip a file (not a directory)', async () => {
758
800
  await fs.writeFile(path.join(repoDir, 'lone.md'), 'one');
759
- await expect(svc.createFolderZip(workspaceId, 'lone.md')).rejects.toThrow('Not a directory');
801
+ await expect(svc.createFolderZip(workspaceId, 'lone.md', ALL)).rejects.toThrow('Not a directory');
760
802
  });
761
803
 
762
804
  it('refuses a traversing path, and reads an unprefixed one as the repository folder', async () => {
763
- await expect(svc.createFolderZip(workspaceId, '../escape')).rejects.toThrow(
805
+ await expect(svc.createFolderZip(workspaceId, '../escape', ALL)).rejects.toThrow(
764
806
  'is outside the knowledge base repository',
765
807
  );
766
808
  // The unprefixed spelling is the repository's own folder, so it zips.
767
809
  await fs.mkdir(path.join(repoDir, 'unprefixed'), { recursive: true });
768
810
  await fs.writeFile(path.join(repoDir, 'unprefixed', 'a.md'), 'a');
769
- const buf = await svc.createFolderZip(workspaceId, 'unprefixed');
811
+ const buf = await svc.createFolderZip(workspaceId, 'unprefixed', ALL);
770
812
  expect((await unzipEntries(buf)).map((e) => e.name)).toEqual(['unprefixed/a.md']);
771
813
  });
772
814
 
@@ -796,7 +838,7 @@ describe('WorkspaceService.createFolderZip', () => {
796
838
  return result;
797
839
  });
798
840
  try {
799
- await expect(svc.createFolderZip(workspaceId, 'too-big'))
841
+ await expect(svc.createFolderZip(workspaceId, 'too-big', ALL))
800
842
  .rejects.toBeInstanceOf(FolderTooLargeError);
801
843
  } finally {
802
844
  statSpy.mockRestore();
@@ -5,6 +5,7 @@ import { tmpdir } from 'node:os';
5
5
  import { DEFAULT_KB_LAYOUT } from '@bevel-software/platform-shared';
6
6
  import { testKbContext } from '../../../__tests__/kb-context.js';
7
7
  import { ToolRegistry } from '../../tool-registry/tool-registry.js';
8
+ import { GUIDE_FIRST_SENTENCE } from '../../tool-registry/guide-first.js';
8
9
  import { createToolHandlerFactory } from '../../tool-helpers/tool-handler.js';
9
10
  import type { ToolAuth } from '../../tool-auth/tool-auth.middleware.js';
10
11
  import type { IAccessControl } from '../../access/access-control.interface.js';
@@ -14,19 +15,18 @@ import { SpillStore } from '../spill-store.js';
14
15
  import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
15
16
  import { ToolDescriptionNotes } from '../../workspace/agent-access.gate.js';
16
17
  import { registerWorkspaceTools } from '../workspace.tools.js';
17
- import { sharedFileRulesSection, sharedRulesPointer } from '../../agent-instructions/shared-file-rules.js';
18
+ import { sharedFileRulesSection } from '../../agent-instructions/shared-file-rules.js';
18
19
 
19
20
  /**
20
- * What the platform TELLS AN AGENT about the conventions file, under the
21
- * default name and under a deployment's own.
21
+ * What the platform TELLS AN AGENT about the guide.
22
22
  *
23
- * The conventions reminder and the platform-file list are SHARED RULES now —
24
- * stated in the handshake instructions and in the managed agent guide, once
25
- * each — so their wording is asserted against that one text. What each tool
26
- * description still has to get right is the POINTER at the end, which names the
27
- * guide by the name this deployment gave it; that is the only place a remote
28
- * agent learns which file to open, and it has no checkout, so no harness reads
29
- * that file for it.
23
+ * The conventions reminder and the platform-file list are SHARED RULES —
24
+ * stated in the handshake instructions and in the guide, once each — so their
25
+ * wording is asserted against that one text. What each tool description has
26
+ * to get right is its OPENING: the one sentence saying to call
27
+ * `get_agent_guide` first, which the catalog puts at the front of every tool
28
+ * (see tool-registry/guide-first.ts); a remote agent has no checkout, so that
29
+ * sentence and the rule are the only places it learns what to read first.
30
30
  */
31
31
  const KB_DIR = 'knowledge-base';
32
32
  /** The context the tools read; a case applies a deployment's own names to it. */
@@ -64,70 +64,48 @@ async function listed(registry: ToolRegistry): Promise<Map<string, string>> {
64
64
 
65
65
  afterEach(() => kb.applyLayout({ ...DEFAULT_KB_LAYOUT }));
66
66
 
67
- describe("what names the guide, under the default name and under a deployment's own", () => {
68
- it('names AGENTS.md, and CLAUDE.md beside it, under the default name', () => {
67
+ describe('what tells an agent to read the guide first', () => {
68
+ it('tells an agent to call get_agent_guide first, and that AGENTS.md answers with the same guide after the organisation\'s own', () => {
69
69
  const rules = sharedFileRulesSection(kb.layout);
70
- expect(rules).toContain(
71
- 'read `AGENTS.md` at the KB root — or `CLAUDE.md` on a knowledge base seeded before it was renamed',
72
- );
70
+ expect(rules).toContain("call `get_agent_guide` and read the platform's guide");
71
+ expect(rules).toContain('read_file on `AGENTS.md` at the KB root answers with the same guide');
72
+ expect(rules).toContain("after the organisation's own conventions file of that name");
73
+ expect(rules).toContain('`CLAUDE.md`');
74
+ // One name on every deployment: the rule names no other.
75
+ expect(rules).not.toContain('HEXIS.md');
73
76
  });
74
77
 
75
- it("points every entrypoint at the section, by the guide's own name", async () => {
78
+ it('opens every entrypoint with the guide-first sentence, reads included', async () => {
76
79
  const byName = await descriptions();
77
- // On EVERY entrypoint, reads included: any of them can be a session's first.
78
- for (const name of ['grep', 'list_files', 'file_stat', 'write_file', 'move_file']) {
79
- expect(byName.get(name), name).toContain('see "Working with files" in AGENTS.md.');
80
+ for (const name of ['grep', 'list_files', 'file_stat', 'read_file', 'write_file', 'move_file', 'start_session']) {
81
+ expect(byName.get(name)!.startsWith(`${GUIDE_FIRST_SENTENCE} `), name).toBe(true);
82
+ // Once, at the front — never again further down.
83
+ expect(byName.get(name)!.split(GUIDE_FIRST_SENTENCE), name).toHaveLength(2);
80
84
  }
81
85
  });
82
86
 
83
- it("names the configured file first and the organisation's own AGENTS.md second", () => {
84
- kb.applyLayout({ ...DEFAULT_KB_LAYOUT, agentsFile: 'HEXIS.md' });
85
- const note = sharedFileRulesSection(kb.layout);
86
- expect(note).toContain('read `HEXIS.md` at the KB root, then `AGENTS.md` if it also exists');
87
- expect(note).toContain("the organisation's own conventions");
88
- // Ours first: an agent that reads only one must read the platform's.
89
- expect(note.indexOf('`HEXIS.md`')).toBeLessThan(note.indexOf('`AGENTS.md`'));
90
- // The legacy name is still offered, for a KB seeded before the rename.
91
- expect(note).toContain('`CLAUDE.md`');
92
- });
93
-
94
- it('lists the platform files under the configured name, and no longer under AGENTS.md', () => {
87
+ it('lists the guide under no name as a platform file, and ignores a name a deployment saved for it', () => {
95
88
  kb.applyLayout({ ...DEFAULT_KB_LAYOUT, agentsFile: 'HEXIS.md' });
96
89
  const rules = sharedFileRulesSection(kb.layout);
97
- // Listed with the depth each one counts at — `access.md` and
98
- // `.bevelignore` govern the folder they sit in, the other two are read from
99
- // the root — because the names alone would have an agent refuse a nested
100
- // `HEXIS.md` it may rename.
101
- expect(rules).toContain('`access.md` or `.bevelignore` in any folder, `roles.yaml` or `HEXIS.md` at the repository root');
102
- // The customer's file is content on such a deployment, so the rule that
103
- // refuses a move must not claim it.
104
- expect(rules.replace(/`AGENTS\.md` if it also exists/g, '')).not.toContain('`AGENTS.md`');
105
- });
106
-
107
- it('keeps naming AGENTS.md as a platform file under the default name', () => {
108
- expect(sharedFileRulesSection(kb.layout)).toContain(
109
- '`access.md` or `.bevelignore` in any folder, `roles.yaml` or `AGENTS.md` at the repository root',
110
- );
90
+ expect(rules).toContain('`access.md` or `.bevelignore` in any folder, `roles.yaml` at the repository root');
91
+ expect(rules).not.toContain('HEXIS.md');
92
+ expect(rules).toBe(sharedFileRulesSection(DEFAULT_KB_LAYOUT));
111
93
  });
112
94
 
113
95
  /**
114
96
  * First-run setup on a fresh deployment: the tools are mounted at boot, under
115
97
  * the defaults, and the save that COMPLETES setup applies the admin's names
116
- * in that same request — without a restart, deliberately, so the KB phase it
117
- * runs next scaffolds the names they chose. A catalog built once at boot
118
- * would go on naming `AGENTS.md` to every agent that connected afterwards.
98
+ * in that same request — without a restart. Nothing in the opening sentence
99
+ * moves with a name, so what the catalog said at boot is what it says after.
119
100
  */
120
- it('follows a layout applied after the tools were mounted', async () => {
101
+ it('says the same thing after a layout is applied as it did at the mount', async () => {
121
102
  const registry = new ToolRegistry();
122
103
  const atMount = await descriptions(registry);
123
- expect(atMount.get('grep')).toContain('in AGENTS.md.');
124
-
125
- kb.applyLayout({ ...DEFAULT_KB_LAYOUT, agentsFile: 'HEXIS.md' });
126
-
104
+ kb.applyLayout({ ...DEFAULT_KB_LAYOUT, knowledgeBaseDir: 'Docs' });
127
105
  const now = await listed(registry);
128
106
  for (const name of ['grep', 'file_stat', 'delete_file', 'move_file']) {
129
- expect(now.get(name), name).toContain(sharedRulesPointer(kb.layout));
130
- expect(now.get(name), name).not.toContain('in AGENTS.md.');
107
+ expect(now.get(name)!.startsWith(GUIDE_FIRST_SENTENCE), name).toBe(true);
108
+ expect(now.get(name), name).toBe(atMount.get(name));
131
109
  }
132
110
  });
133
111
  });