@bevel-software/platform-core-backend 0.26.0 → 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 (613) hide show
  1. package/agent-guide/access-control.md +17 -0
  2. package/agent-guide/conventions.md +8 -0
  3. package/agent-guide/html-views.md +83 -0
  4. package/agent-guide/new-knowledge-base.md +24 -0
  5. package/agent-guide/tool-manuals.md +10 -0
  6. package/dist/assets.d.ts +19 -0
  7. package/dist/assets.d.ts.map +1 -1
  8. package/dist/assets.js +26 -2
  9. package/dist/assets.js.map +1 -1
  10. package/dist/core/catalog-revision.d.ts +19 -1
  11. package/dist/core/catalog-revision.d.ts.map +1 -1
  12. package/dist/core/catalog-revision.js +14 -3
  13. package/dist/core/catalog-revision.js.map +1 -1
  14. package/dist/core/create-core-server.d.ts +5 -0
  15. package/dist/core/create-core-server.d.ts.map +1 -1
  16. package/dist/core/create-core-server.js +54 -3
  17. package/dist/core/create-core-server.js.map +1 -1
  18. package/dist/core/create-core-services.d.ts +26 -0
  19. package/dist/core/create-core-services.d.ts.map +1 -1
  20. package/dist/core/create-core-services.js +100 -8
  21. package/dist/core/create-core-services.js.map +1 -1
  22. package/dist/core/lifecycle.d.ts +16 -1
  23. package/dist/core/lifecycle.d.ts.map +1 -1
  24. package/dist/core/lifecycle.js +18 -1
  25. package/dist/core/lifecycle.js.map +1 -1
  26. package/dist/core-config.d.ts +21 -0
  27. package/dist/core-config.d.ts.map +1 -1
  28. package/dist/core-config.js +22 -1
  29. package/dist/core-config.js.map +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2 -2
  33. package/dist/index.js.map +1 -1
  34. package/dist/modules/access/access-control.interface.d.ts +8 -0
  35. package/dist/modules/access/access-control.interface.d.ts.map +1 -1
  36. package/dist/modules/access/access-control.service.d.ts +1 -0
  37. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  38. package/dist/modules/access/access-control.service.js +11 -0
  39. package/dist/modules/access/access-control.service.js.map +1 -1
  40. package/dist/modules/access/directory-sync-bot.js +1 -1
  41. package/dist/modules/access/directory-sync-bot.js.map +1 -1
  42. package/dist/modules/agent-guide/agent-guide.d.ts +6 -0
  43. package/dist/modules/agent-guide/agent-guide.d.ts.map +1 -1
  44. package/dist/modules/agent-guide/agent-guide.js +8 -0
  45. package/dist/modules/agent-guide/agent-guide.js.map +1 -1
  46. package/dist/modules/agent-guide/index.d.ts +1 -1
  47. package/dist/modules/agent-guide/index.d.ts.map +1 -1
  48. package/dist/modules/agent-guide/index.js +1 -1
  49. package/dist/modules/agent-guide/index.js.map +1 -1
  50. package/dist/modules/agent-instructions/compose.d.ts +5 -0
  51. package/dist/modules/agent-instructions/compose.d.ts.map +1 -1
  52. package/dist/modules/agent-instructions/compose.js +19 -2
  53. package/dist/modules/agent-instructions/compose.js.map +1 -1
  54. package/dist/modules/agent-instructions/shared-file-rules.js +19 -19
  55. package/dist/modules/agent-instructions/shared-file-rules.js.map +1 -1
  56. package/dist/modules/audit/agent-audit.service.d.ts +21 -2
  57. package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
  58. package/dist/modules/audit/agent-audit.service.js +43 -2
  59. package/dist/modules/audit/agent-audit.service.js.map +1 -1
  60. package/dist/modules/audit/agent-connection.routes.d.ts +34 -0
  61. package/dist/modules/audit/agent-connection.routes.d.ts.map +1 -0
  62. package/dist/modules/audit/agent-connection.routes.js +38 -0
  63. package/dist/modules/audit/agent-connection.routes.js.map +1 -0
  64. package/dist/modules/audit/audit.contract.d.ts +24 -0
  65. package/dist/modules/audit/audit.contract.d.ts.map +1 -1
  66. package/dist/modules/audit/audit.contract.js.map +1 -1
  67. package/dist/modules/audit/index.d.ts +1 -0
  68. package/dist/modules/audit/index.d.ts.map +1 -1
  69. package/dist/modules/audit/index.js +1 -0
  70. package/dist/modules/audit/index.js.map +1 -1
  71. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  72. package/dist/modules/auth/account.routes.js +10 -3
  73. package/dist/modules/auth/account.routes.js.map +1 -1
  74. package/dist/modules/auth/auth.middleware.d.ts +7 -0
  75. package/dist/modules/auth/auth.middleware.d.ts.map +1 -1
  76. package/dist/modules/auth/auth.middleware.js +1 -1
  77. package/dist/modules/auth/auth.middleware.js.map +1 -1
  78. package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -1
  79. package/dist/modules/code-mode/code-mode.tool.js +11 -3
  80. package/dist/modules/code-mode/code-mode.tool.js.map +1 -1
  81. package/dist/modules/database/core-schema.d.ts +96 -0
  82. package/dist/modules/database/core-schema.d.ts.map +1 -1
  83. package/dist/modules/database/core-schema.js +32 -3
  84. package/dist/modules/database/core-schema.js.map +1 -1
  85. package/dist/modules/embed/account-link.service.d.ts +42 -0
  86. package/dist/modules/embed/account-link.service.d.ts.map +1 -0
  87. package/dist/modules/embed/account-link.service.js +50 -0
  88. package/dist/modules/embed/account-link.service.js.map +1 -0
  89. package/dist/modules/embed/embed-link.d.ts +58 -0
  90. package/dist/modules/embed/embed-link.d.ts.map +1 -0
  91. package/dist/modules/embed/embed-link.js +160 -0
  92. package/dist/modules/embed/embed-link.js.map +1 -0
  93. package/dist/modules/embed/embed.errors.d.ts +30 -0
  94. package/dist/modules/embed/embed.errors.d.ts.map +1 -0
  95. package/dist/modules/embed/embed.errors.js +42 -0
  96. package/dist/modules/embed/embed.errors.js.map +1 -0
  97. package/dist/modules/embed/embed.interface.d.ts +204 -0
  98. package/dist/modules/embed/embed.interface.d.ts.map +1 -0
  99. package/dist/modules/embed/embed.interface.js +2 -0
  100. package/dist/modules/embed/embed.interface.js.map +1 -0
  101. package/dist/modules/embed/embed.routes.d.ts +59 -0
  102. package/dist/modules/embed/embed.routes.d.ts.map +1 -0
  103. package/dist/modules/embed/embed.routes.js +343 -0
  104. package/dist/modules/embed/embed.routes.js.map +1 -0
  105. package/dist/modules/embed/embed.service.d.ts +169 -0
  106. package/dist/modules/embed/embed.service.d.ts.map +1 -0
  107. package/dist/modules/embed/embed.service.js +627 -0
  108. package/dist/modules/embed/embed.service.js.map +1 -0
  109. package/dist/modules/embed/embed.tools.d.ts +51 -0
  110. package/dist/modules/embed/embed.tools.d.ts.map +1 -0
  111. package/dist/modules/embed/embed.tools.js +170 -0
  112. package/dist/modules/embed/embed.tools.js.map +1 -0
  113. package/dist/modules/embed/mcp-app.d.ts +64 -0
  114. package/dist/modules/embed/mcp-app.d.ts.map +1 -0
  115. package/dist/modules/embed/mcp-app.js +147 -0
  116. package/dist/modules/embed/mcp-app.js.map +1 -0
  117. package/dist/modules/embed/mcp-app.routes.d.ts +21 -0
  118. package/dist/modules/embed/mcp-app.routes.d.ts.map +1 -0
  119. package/dist/modules/embed/mcp-app.routes.js +36 -0
  120. package/dist/modules/embed/mcp-app.routes.js.map +1 -0
  121. package/dist/modules/github-app/github-app.connection.d.ts +15 -0
  122. package/dist/modules/github-app/github-app.connection.d.ts.map +1 -1
  123. package/dist/modules/github-app/github-app.connection.js +34 -3
  124. package/dist/modules/github-app/github-app.connection.js.map +1 -1
  125. package/dist/modules/kb-fs/locking-filesystem.d.ts +65 -0
  126. package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
  127. package/dist/modules/kb-fs/locking-filesystem.js +300 -0
  128. package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
  129. package/dist/modules/kb-sync/kb-sync.interface.d.ts +5 -0
  130. package/dist/modules/kb-sync/kb-sync.interface.d.ts.map +1 -1
  131. package/dist/modules/kb-sync/kb-sync.service.d.ts.map +1 -1
  132. package/dist/modules/kb-sync/kb-sync.service.js +6 -0
  133. package/dist/modules/kb-sync/kb-sync.service.js.map +1 -1
  134. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
  135. package/dist/modules/mcp/mcp-auth.middleware.js +2 -1
  136. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
  137. package/dist/modules/mcp/mcp.service.d.ts +28 -1
  138. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  139. package/dist/modules/mcp/mcp.service.js +64 -8
  140. package/dist/modules/mcp/mcp.service.js.map +1 -1
  141. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +24 -0
  142. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  143. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +32 -4
  144. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  145. package/dist/modules/onboarding/onboarding.contract.d.ts +80 -0
  146. package/dist/modules/onboarding/onboarding.contract.d.ts.map +1 -0
  147. package/dist/modules/onboarding/onboarding.contract.js +7 -0
  148. package/dist/modules/onboarding/onboarding.contract.js.map +1 -0
  149. package/dist/modules/onboarding/onboarding.routes.d.ts +18 -0
  150. package/dist/modules/onboarding/onboarding.routes.d.ts.map +1 -0
  151. package/dist/modules/onboarding/onboarding.routes.js +81 -0
  152. package/dist/modules/onboarding/onboarding.routes.js.map +1 -0
  153. package/dist/modules/onboarding/starter-pack.service.d.ts +213 -0
  154. package/dist/modules/onboarding/starter-pack.service.d.ts.map +1 -0
  155. package/dist/modules/onboarding/starter-pack.service.js +492 -0
  156. package/dist/modules/onboarding/starter-pack.service.js.map +1 -0
  157. package/dist/modules/onboarding/starter-packs.d.ts +78 -0
  158. package/dist/modules/onboarding/starter-packs.d.ts.map +1 -0
  159. package/dist/modules/onboarding/starter-packs.js +156 -0
  160. package/dist/modules/onboarding/starter-packs.js.map +1 -0
  161. package/dist/modules/plugins/index.d.ts +1 -1
  162. package/dist/modules/plugins/index.d.ts.map +1 -1
  163. package/dist/modules/plugins/index.js +1 -1
  164. package/dist/modules/plugins/index.js.map +1 -1
  165. package/dist/modules/plugins/plugin-provision.service.d.ts +19 -0
  166. package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
  167. package/dist/modules/plugins/plugin-provision.service.js +18 -1
  168. package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
  169. package/dist/modules/plugins/plugins.routes.d.ts +0 -36
  170. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  171. package/dist/modules/plugins/plugins.routes.js +31 -0
  172. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  173. package/dist/modules/settings/deployment-settings.service.d.ts +34 -0
  174. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  175. package/dist/modules/settings/deployment-settings.service.js +134 -1
  176. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  177. package/dist/modules/settings/repository-source.d.ts +1 -0
  178. package/dist/modules/settings/repository-source.d.ts.map +1 -1
  179. package/dist/modules/settings/repository-source.js +3 -3
  180. package/dist/modules/settings/repository-source.js.map +1 -1
  181. package/dist/modules/skills/skills.tools.d.ts.map +1 -1
  182. package/dist/modules/skills/skills.tools.js +50 -32
  183. package/dist/modules/skills/skills.tools.js.map +1 -1
  184. package/dist/modules/tool-auth/connection-key-rejection.d.ts +10 -1
  185. package/dist/modules/tool-auth/connection-key-rejection.d.ts.map +1 -1
  186. package/dist/modules/tool-auth/connection-key-rejection.js +11 -3
  187. package/dist/modules/tool-auth/connection-key-rejection.js.map +1 -1
  188. package/dist/modules/tool-auth/external-api-key.interface.d.ts +8 -0
  189. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
  190. package/dist/modules/tool-auth/external-api-key.service.d.ts +24 -2
  191. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  192. package/dist/modules/tool-auth/external-api-key.service.js +59 -2
  193. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  194. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
  195. package/dist/modules/tool-auth/tool-auth.middleware.js +9 -4
  196. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
  197. package/dist/modules/tool-helpers/index.d.ts +28 -1
  198. package/dist/modules/tool-helpers/index.d.ts.map +1 -1
  199. package/dist/modules/tool-helpers/index.js +28 -1
  200. package/dist/modules/tool-helpers/index.js.map +1 -1
  201. package/dist/modules/tool-helpers/route-argument-check.d.ts +10 -0
  202. package/dist/modules/tool-helpers/route-argument-check.d.ts.map +1 -0
  203. package/dist/modules/tool-helpers/route-argument-check.js +132 -0
  204. package/dist/modules/tool-helpers/route-argument-check.js.map +1 -0
  205. package/dist/modules/tool-helpers/route-tool-schemas.d.ts +89 -0
  206. package/dist/modules/tool-helpers/route-tool-schemas.d.ts.map +1 -0
  207. package/dist/modules/tool-helpers/route-tool-schemas.js +113 -0
  208. package/dist/modules/tool-helpers/route-tool-schemas.js.map +1 -0
  209. package/dist/modules/tool-helpers/tool-def.d.ts +71 -0
  210. package/dist/modules/tool-helpers/tool-def.d.ts.map +1 -1
  211. package/dist/modules/tool-helpers/tool-def.js +70 -6
  212. package/dist/modules/tool-helpers/tool-def.js.map +1 -1
  213. package/dist/modules/tool-helpers/tool-handler.d.ts +46 -6
  214. package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
  215. package/dist/modules/tool-helpers/tool-handler.js +157 -8
  216. package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
  217. package/dist/modules/tool-helpers/tool.contract.d.ts +9 -0
  218. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
  219. package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
  220. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  221. package/dist/modules/tool-manuals/tool-manuals.tools.js +14 -5
  222. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  223. package/dist/modules/tool-registry/description-length.d.ts +6 -2
  224. package/dist/modules/tool-registry/description-length.d.ts.map +1 -1
  225. package/dist/modules/tool-registry/description-length.js +27 -5
  226. package/dist/modules/tool-registry/description-length.js.map +1 -1
  227. package/dist/modules/tool-registry/guide-first.d.ts +4 -0
  228. package/dist/modules/tool-registry/guide-first.d.ts.map +1 -1
  229. package/dist/modules/tool-registry/guide-first.js +9 -1
  230. package/dist/modules/tool-registry/guide-first.js.map +1 -1
  231. package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts +53 -0
  232. package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts.map +1 -1
  233. package/dist/modules/workflow/agent-tools/change-request-read.tools.js +97 -68
  234. package/dist/modules/workflow/agent-tools/change-request-read.tools.js.map +1 -1
  235. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +8 -1
  236. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  237. package/dist/modules/workflow/agent-tools/workflow.tools.js +124 -37
  238. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  239. package/dist/modules/workflow/file-lock.service.d.ts +29 -5
  240. package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
  241. package/dist/modules/workflow/file-lock.service.js +62 -5
  242. package/dist/modules/workflow/file-lock.service.js.map +1 -1
  243. package/dist/modules/workflow/git/git.service.d.ts +72 -1
  244. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  245. package/dist/modules/workflow/git/git.service.js +172 -36
  246. package/dist/modules/workflow/git/git.service.js.map +1 -1
  247. package/dist/modules/workflow/git/node-git-runner.d.ts +15 -0
  248. package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
  249. package/dist/modules/workflow/git/node-git-runner.js +78 -6
  250. package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
  251. package/dist/modules/workflow/pending-commits.service.d.ts +15 -0
  252. package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
  253. package/dist/modules/workflow/pending-commits.service.js +25 -1
  254. package/dist/modules/workflow/pending-commits.service.js.map +1 -1
  255. package/dist/modules/workflow/pending-commits.worker.d.ts +6 -1
  256. package/dist/modules/workflow/pending-commits.worker.d.ts.map +1 -1
  257. package/dist/modules/workflow/pending-commits.worker.js +23 -6
  258. package/dist/modules/workflow/pending-commits.worker.js.map +1 -1
  259. package/dist/modules/workflow/recovery-bot.js +1 -1
  260. package/dist/modules/workflow/recovery-bot.js.map +1 -1
  261. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
  262. package/dist/modules/workflow/review-workflow/review-workflow.service.js +2 -1
  263. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
  264. package/dist/modules/workflow/sanitize-error.d.ts +16 -0
  265. package/dist/modules/workflow/sanitize-error.d.ts.map +1 -1
  266. package/dist/modules/workflow/sanitize-error.js +45 -0
  267. package/dist/modules/workflow/sanitize-error.js.map +1 -1
  268. package/dist/modules/workflow/workflow.service.d.ts +183 -15
  269. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  270. package/dist/modules/workflow/workflow.service.js +805 -106
  271. package/dist/modules/workflow/workflow.service.js.map +1 -1
  272. package/dist/modules/workspace/agent-download.builder.d.ts +105 -0
  273. package/dist/modules/workspace/agent-download.builder.d.ts.map +1 -0
  274. package/dist/modules/workspace/agent-download.builder.js +238 -0
  275. package/dist/modules/workspace/agent-download.builder.js.map +1 -0
  276. package/dist/modules/workspace/agent-download.routes.d.ts +77 -0
  277. package/dist/modules/workspace/agent-download.routes.d.ts.map +1 -0
  278. package/dist/modules/workspace/agent-download.routes.js +156 -0
  279. package/dist/modules/workspace/agent-download.routes.js.map +1 -0
  280. package/dist/modules/workspace/agent-download.store.d.ts +225 -0
  281. package/dist/modules/workspace/agent-download.store.d.ts.map +1 -0
  282. package/dist/modules/workspace/agent-download.store.js +423 -0
  283. package/dist/modules/workspace/agent-download.store.js.map +1 -0
  284. package/dist/modules/workspace/agent-upload.store.d.ts +10 -1
  285. package/dist/modules/workspace/agent-upload.store.d.ts.map +1 -1
  286. package/dist/modules/workspace/agent-upload.store.js +16 -6
  287. package/dist/modules/workspace/agent-upload.store.js.map +1 -1
  288. package/dist/modules/workspace/file-readers/raw-mime.d.ts +6 -0
  289. package/dist/modules/workspace/file-readers/raw-mime.d.ts.map +1 -0
  290. package/dist/modules/workspace/file-readers/raw-mime.js +38 -0
  291. package/dist/modules/workspace/file-readers/raw-mime.js.map +1 -0
  292. package/dist/modules/workspace/file-readers/text-reader.d.ts +5 -5
  293. package/dist/modules/workspace/file-readers/text-reader.d.ts.map +1 -1
  294. package/dist/modules/workspace/file-readers/text-reader.js +5 -8
  295. package/dist/modules/workspace/file-readers/text-reader.js.map +1 -1
  296. package/dist/modules/workspace/first-run.d.ts +111 -0
  297. package/dist/modules/workspace/first-run.d.ts.map +1 -0
  298. package/dist/modules/workspace/first-run.js +181 -0
  299. package/dist/modules/workspace/first-run.js.map +1 -0
  300. package/dist/modules/workspace/move-links.d.ts +92 -0
  301. package/dist/modules/workspace/move-links.d.ts.map +1 -0
  302. package/dist/modules/workspace/move-links.js +173 -0
  303. package/dist/modules/workspace/move-links.js.map +1 -0
  304. package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
  305. package/dist/modules/workspace/startup/steps/seed-tree.js +3 -13
  306. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  307. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  308. package/dist/modules/workspace/workspace.routes.js +63 -22
  309. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  310. package/dist/modules/workspace/workspace.service.d.ts +75 -2
  311. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  312. package/dist/modules/workspace/workspace.service.js +197 -24
  313. package/dist/modules/workspace/workspace.service.js.map +1 -1
  314. package/dist/modules/workspace/workspace.tools.d.ts +59 -1
  315. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  316. package/dist/modules/workspace/workspace.tools.js +443 -65
  317. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  318. package/dist/modules/write-access/write-access.d.ts.map +1 -1
  319. package/dist/modules/write-access/write-access.js +9 -0
  320. package/dist/modules/write-access/write-access.js.map +1 -1
  321. package/dist/shared/domain-errors.d.ts +73 -1
  322. package/dist/shared/domain-errors.d.ts.map +1 -1
  323. package/dist/shared/domain-errors.js +86 -12
  324. package/dist/shared/domain-errors.js.map +1 -1
  325. package/dist/shared/git.contract.d.ts +10 -1
  326. package/dist/shared/git.contract.d.ts.map +1 -1
  327. package/dist/shared/git.contract.js.map +1 -1
  328. package/dist/shared/utf8-text.d.ts +15 -0
  329. package/dist/shared/utf8-text.d.ts.map +1 -0
  330. package/dist/shared/utf8-text.js +20 -0
  331. package/dist/shared/utf8-text.js.map +1 -0
  332. package/dist/tenancy/static-tenant-source.d.ts +2 -1
  333. package/dist/tenancy/static-tenant-source.d.ts.map +1 -1
  334. package/dist/tenancy/static-tenant-source.js +9 -2
  335. package/dist/tenancy/static-tenant-source.js.map +1 -1
  336. package/mcp-app/page.html +349 -0
  337. package/migrations/0017_atlassian_account_links.sql +37 -0
  338. package/migrations/meta/0017_snapshot.json +2396 -0
  339. package/migrations/meta/_journal.json +8 -1
  340. package/package.json +5 -3
  341. package/src/__tests__/packaged-assets-ship.test.ts +16 -4
  342. package/src/assets.ts +28 -2
  343. package/src/core/__tests__/catalog-revision.test.ts +40 -0
  344. package/src/core/__tests__/gated-boot.test.ts +1 -0
  345. package/src/core/__tests__/lifecycle.test.ts +14 -0
  346. package/src/core/catalog-revision.ts +15 -2
  347. package/src/core/create-core-server.ts +67 -3
  348. package/src/core/create-core-services.ts +140 -6
  349. package/src/core/lifecycle.ts +28 -2
  350. package/src/core-config.ts +24 -1
  351. package/src/index.ts +2 -2
  352. package/src/modules/access/__tests__/access-control.service.test.ts +19 -0
  353. package/src/modules/access/access-control.interface.ts +13 -0
  354. package/src/modules/access/access-control.service.ts +16 -0
  355. package/src/modules/access/directory-sync-bot.ts +1 -1
  356. package/src/modules/agent-guide/__tests__/agent-guide.test.ts +58 -0
  357. package/src/modules/agent-guide/__tests__/agent-guide.tools.test.ts +19 -1
  358. package/src/modules/agent-guide/agent-guide.ts +9 -0
  359. package/src/modules/agent-guide/index.ts +1 -0
  360. package/src/modules/agent-instructions/__tests__/shared-file-rules.test.ts +14 -0
  361. package/src/modules/agent-instructions/compose.ts +17 -2
  362. package/src/modules/agent-instructions/shared-file-rules.ts +19 -19
  363. package/src/modules/audit/__tests__/agent-audit.service.test.ts +64 -4
  364. package/src/modules/audit/__tests__/agent-connection.routes.test.ts +102 -0
  365. package/src/modules/audit/agent-audit.service.ts +58 -3
  366. package/src/modules/audit/agent-connection.routes.ts +56 -0
  367. package/src/modules/audit/audit.contract.ts +26 -0
  368. package/src/modules/audit/index.ts +1 -0
  369. package/src/modules/auth/__tests__/account.routes.test.ts +5 -3
  370. package/src/modules/auth/account.routes.ts +10 -3
  371. package/src/modules/auth/auth.middleware.ts +1 -1
  372. package/src/modules/code-mode/__tests__/code-mode.tool.test.ts +18 -2
  373. package/src/modules/code-mode/code-mode.tool.ts +13 -2
  374. package/src/modules/database/core-schema.ts +33 -3
  375. package/src/modules/embed/__tests__/account-links.migration.test.ts +98 -0
  376. package/src/modules/embed/__tests__/embed-link.test.ts +122 -0
  377. package/src/modules/embed/__tests__/embed.routes.test.ts +362 -0
  378. package/src/modules/embed/__tests__/embed.service.lock.test.ts +193 -0
  379. package/src/modules/embed/__tests__/embed.service.test.ts +805 -0
  380. package/src/modules/embed/__tests__/embed.tools.test.ts +304 -0
  381. package/src/modules/embed/__tests__/mcp-app.test.ts +207 -0
  382. package/src/modules/embed/account-link.service.ts +76 -0
  383. package/src/modules/embed/embed-link.ts +180 -0
  384. package/src/modules/embed/embed.errors.ts +43 -0
  385. package/src/modules/embed/embed.interface.ts +203 -0
  386. package/src/modules/embed/embed.routes.ts +363 -0
  387. package/src/modules/embed/embed.service.ts +705 -0
  388. package/src/modules/embed/embed.tools.ts +206 -0
  389. package/src/modules/embed/mcp-app.routes.ts +41 -0
  390. package/src/modules/embed/mcp-app.ts +173 -0
  391. package/src/modules/github-app/__tests__/github-app.test.ts +76 -0
  392. package/src/modules/github-app/github-app.connection.ts +38 -4
  393. package/src/modules/kb-fs/__tests__/move-with-edits.test.ts +304 -0
  394. package/src/modules/kb-fs/locking-filesystem.ts +287 -0
  395. package/src/modules/kb-sync/__tests__/kb-sync.service.test.ts +35 -0
  396. package/src/modules/kb-sync/kb-sync.interface.ts +2 -0
  397. package/src/modules/kb-sync/kb-sync.service.ts +6 -0
  398. package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +68 -11
  399. package/src/modules/mcp/__tests__/mcp-proxy-helpers.test.ts +37 -2
  400. package/src/modules/mcp/__tests__/mcp.app.e2e.test.ts +200 -0
  401. package/src/modules/mcp/__tests__/mcp.e2e.test.ts +3 -1
  402. package/src/modules/mcp/__tests__/mcp.service.test.ts +23 -13
  403. package/src/modules/mcp/__tests__/tool-call-interface.e2e.test.ts +499 -0
  404. package/src/modules/mcp/mcp-auth.middleware.ts +2 -1
  405. package/src/modules/mcp/mcp.service.ts +81 -12
  406. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +42 -4
  407. package/src/modules/onboarding/__tests__/onboarding.routes.test.ts +163 -0
  408. package/src/modules/onboarding/__tests__/starter-pack.service.test.ts +635 -0
  409. package/src/modules/onboarding/__tests__/starter-packs.test.ts +169 -0
  410. package/src/modules/onboarding/onboarding.contract.ts +85 -0
  411. package/src/modules/onboarding/onboarding.routes.ts +85 -0
  412. package/src/modules/onboarding/starter-pack.service.ts +580 -0
  413. package/src/modules/onboarding/starter-packs.ts +182 -0
  414. package/src/modules/plugins/__tests__/plugins.tools.test.ts +25 -2
  415. package/src/modules/plugins/index.ts +1 -0
  416. package/src/modules/plugins/plugin-provision.service.ts +22 -1
  417. package/src/modules/plugins/plugins.routes.ts +29 -0
  418. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +150 -1
  419. package/src/modules/settings/__tests__/repository-source.test.ts +9 -0
  420. package/src/modules/settings/deployment-settings.service.ts +131 -1
  421. package/src/modules/settings/repository-source.ts +4 -4
  422. package/src/modules/skills/__tests__/skills.tools.description.test.ts +5 -1
  423. package/src/modules/skills/skills.tools.ts +55 -35
  424. package/src/modules/tool-auth/__tests__/connection-key-rejection.test.ts +32 -0
  425. package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +65 -0
  426. package/src/modules/tool-auth/connection-key-rejection.ts +13 -3
  427. package/src/modules/tool-auth/external-api-key.interface.ts +9 -0
  428. package/src/modules/tool-auth/external-api-key.service.ts +61 -4
  429. package/src/modules/tool-auth/tool-auth.middleware.ts +13 -4
  430. package/src/modules/tool-helpers/__tests__/branch-declaration.test.ts +502 -0
  431. package/src/modules/tool-helpers/__tests__/route-argument-check.test.ts +337 -0
  432. package/src/modules/tool-helpers/index.ts +34 -1
  433. package/src/modules/tool-helpers/route-argument-check.ts +149 -0
  434. package/src/modules/tool-helpers/route-tool-schemas.ts +171 -0
  435. package/src/modules/tool-helpers/tool-def.ts +132 -7
  436. package/src/modules/tool-helpers/tool-handler.ts +196 -8
  437. package/src/modules/tool-helpers/tool.contract.ts +9 -0
  438. package/src/modules/tool-manuals/tool-manuals.tools.ts +15 -5
  439. package/src/modules/tool-registry/__tests__/own-tool-schemas.test.ts +14 -1
  440. package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +23 -10
  441. package/src/modules/tool-registry/description-length.ts +34 -7
  442. package/src/modules/tool-registry/guide-first.ts +8 -1
  443. package/src/modules/workflow/__tests__/file-lock.service.deletion-gate.test.ts +104 -0
  444. package/src/modules/workflow/__tests__/pending-commits.repository-replaced.test.ts +66 -0
  445. package/src/modules/workflow/__tests__/pending-commits.worker.test.ts +31 -2
  446. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +110 -6
  447. package/src/modules/workflow/__tests__/sanitize-error.test.ts +89 -1
  448. package/src/modules/workflow/__tests__/workflow.routes.push-refused.test.ts +202 -0
  449. package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +6 -6
  450. package/src/modules/workflow/__tests__/workflow.service.delete-branch.test.ts +1026 -0
  451. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +468 -10
  452. package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +4 -0
  453. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +5 -4
  454. package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +54 -2
  455. package/src/modules/workflow/agent-tools/__tests__/change-request-read.tools.test.ts +41 -5
  456. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +127 -2
  457. package/src/modules/workflow/agent-tools/change-request-read.tools.ts +157 -122
  458. package/src/modules/workflow/agent-tools/workflow.tools.ts +129 -35
  459. package/src/modules/workflow/file-lock.service.ts +67 -5
  460. package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +164 -0
  461. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +48 -1
  462. package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +231 -2
  463. package/src/modules/workflow/git/git.service.ts +176 -38
  464. package/src/modules/workflow/git/node-git-runner.ts +82 -7
  465. package/src/modules/workflow/pending-commits.service.ts +29 -1
  466. package/src/modules/workflow/pending-commits.worker.ts +24 -6
  467. package/src/modules/workflow/recovery-bot.ts +1 -1
  468. package/src/modules/workflow/review-workflow/review-workflow.service.ts +2 -1
  469. package/src/modules/workflow/sanitize-error.ts +50 -0
  470. package/src/modules/workflow/workflow.service.ts +879 -112
  471. package/src/modules/workspace/__tests__/agent-downloads.test.ts +823 -0
  472. package/src/modules/workspace/__tests__/first-run.test.ts +234 -0
  473. package/src/modules/workspace/__tests__/git-internals.security.test.ts +5 -2
  474. package/src/modules/workspace/__tests__/md-links.test.ts +353 -0
  475. package/src/modules/workspace/__tests__/move-links.test.ts +261 -0
  476. package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +219 -0
  477. package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -0
  478. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +102 -0
  479. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +52 -5
  480. package/src/modules/workspace/__tests__/workspace.routes.folder-zip-access.test.ts +190 -0
  481. package/src/modules/workspace/__tests__/workspace.service.forget-clone-races.test.ts +8 -4
  482. package/src/modules/workspace/__tests__/workspace.service.test.ts +50 -8
  483. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +44 -1
  484. package/src/modules/workspace/__tests__/workspace.tools.test.ts +409 -12
  485. package/src/modules/workspace/agent-download.builder.ts +308 -0
  486. package/src/modules/workspace/agent-download.routes.ts +183 -0
  487. package/src/modules/workspace/agent-download.store.ts +533 -0
  488. package/src/modules/workspace/agent-upload.store.ts +23 -7
  489. package/src/modules/workspace/file-readers/raw-mime.ts +40 -0
  490. package/src/modules/workspace/file-readers/text-reader.ts +5 -8
  491. package/src/modules/workspace/first-run.ts +222 -0
  492. package/src/modules/workspace/move-links.ts +237 -0
  493. package/src/modules/workspace/startup/steps/seed-tree.ts +3 -12
  494. package/src/modules/workspace/workspace.routes.ts +64 -22
  495. package/src/modules/workspace/workspace.service.ts +202 -25
  496. package/src/modules/workspace/workspace.tools.ts +492 -63
  497. package/src/modules/write-access/__tests__/write-access.test.ts +13 -0
  498. package/src/modules/write-access/write-access.ts +9 -0
  499. package/src/shared/domain-errors.ts +108 -11
  500. package/src/shared/git.contract.ts +8 -1
  501. package/src/shared/utf8-text.ts +21 -0
  502. package/src/tenancy/__tests__/static-tenant-source.test.ts +1 -0
  503. package/src/tenancy/static-tenant-source.ts +10 -2
  504. package/starter-packs/README.md +103 -0
  505. package/starter-packs/engineering/KnowledgeBase/About us.md +9 -0
  506. package/starter-packs/engineering/KnowledgeBase/Architecture.md +9 -0
  507. package/starter-packs/engineering/KnowledgeBase/Glossary.md +9 -0
  508. package/starter-packs/engineering/KnowledgeBase/How we ship.md +9 -0
  509. package/starter-packs/engineering/Plugins/engineering-starter/LICENSE +21 -0
  510. package/starter-packs/engineering/Plugins/engineering-starter/SOURCE.md +20 -0
  511. package/starter-packs/engineering/Plugins/engineering-starter/access.md +19 -0
  512. package/starter-packs/engineering/Plugins/engineering-starter/plugin.json +10 -0
  513. package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/SKILL.md +171 -0
  514. package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/sections/phase-2a-startup-diagnostic.md +157 -0
  515. package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/sections/phase-2b-builder-brainstorm.md +39 -0
  516. package/starter-packs/engineering/Plugins/engineering-starter/skills/plan-ceo-review/SKILL.md +144 -0
  517. package/starter-packs/engineering/Plugins/engineering-starter/skills/plan-eng-review/SKILL.md +144 -0
  518. package/starter-packs/engineering/Plugins/engineering-starter/skills/review/SKILL.md +80 -0
  519. package/starter-packs/engineering/Plugins/engineering-starter/skills/review/checklist.md +184 -0
  520. package/starter-packs/engineering/pack.yaml +11 -0
  521. package/starter-packs/general/KnowledgeBase/About us.md +9 -0
  522. package/starter-packs/general/KnowledgeBase/Glossary.md +9 -0
  523. package/starter-packs/general/KnowledgeBase/How we work.md +9 -0
  524. package/starter-packs/general/Plugins/general-starter/LICENSE +202 -0
  525. package/starter-packs/general/Plugins/general-starter/SOURCE.md +10 -0
  526. package/starter-packs/general/Plugins/general-starter/access.md +19 -0
  527. package/starter-packs/general/Plugins/general-starter/plugin.json +10 -0
  528. package/starter-packs/general/Plugins/general-starter/skills/memory-management/SKILL.md +332 -0
  529. package/starter-packs/general/Plugins/general-starter/skills/productivity-start/SKILL.md +163 -0
  530. package/starter-packs/general/Plugins/general-starter/skills/productivity-update/SKILL.md +167 -0
  531. package/starter-packs/general/Plugins/general-starter/skills/task-management/SKILL.md +83 -0
  532. package/starter-packs/general/pack.yaml +10 -0
  533. package/starter-packs/operations/KnowledgeBase/Glossary.md +9 -0
  534. package/starter-packs/operations/KnowledgeBase/How we work.md +9 -0
  535. package/starter-packs/operations/KnowledgeBase/Processes.md +9 -0
  536. package/starter-packs/operations/KnowledgeBase/Tools we use.md +9 -0
  537. package/starter-packs/operations/KnowledgeBase/Vendors.md +9 -0
  538. package/starter-packs/operations/Plugins/operations-starter/LICENSE +202 -0
  539. package/starter-packs/operations/Plugins/operations-starter/SOURCE.md +10 -0
  540. package/starter-packs/operations/Plugins/operations-starter/access.md +19 -0
  541. package/starter-packs/operations/Plugins/operations-starter/plugin.json +10 -0
  542. package/starter-packs/operations/Plugins/operations-starter/skills/capacity-plan/SKILL.md +111 -0
  543. package/starter-packs/operations/Plugins/operations-starter/skills/change-request/SKILL.md +119 -0
  544. package/starter-packs/operations/Plugins/operations-starter/skills/compliance-tracking/SKILL.md +44 -0
  545. package/starter-packs/operations/Plugins/operations-starter/skills/process-doc/SKILL.md +80 -0
  546. package/starter-packs/operations/Plugins/operations-starter/skills/process-optimization/SKILL.md +39 -0
  547. package/starter-packs/operations/Plugins/operations-starter/skills/risk-assessment/SKILL.md +40 -0
  548. package/starter-packs/operations/Plugins/operations-starter/skills/runbook/SKILL.md +85 -0
  549. package/starter-packs/operations/Plugins/operations-starter/skills/status-report/SKILL.md +75 -0
  550. package/starter-packs/operations/Plugins/operations-starter/skills/vendor-review/SKILL.md +102 -0
  551. package/starter-packs/operations/pack.yaml +12 -0
  552. package/starter-packs/sales/KnowledgeBase/About us.md +9 -0
  553. package/starter-packs/sales/KnowledgeBase/Customers.md +9 -0
  554. package/starter-packs/sales/KnowledgeBase/Glossary.md +9 -0
  555. package/starter-packs/sales/KnowledgeBase/How we sell.md +9 -0
  556. package/starter-packs/sales/KnowledgeBase/Objections.md +9 -0
  557. package/starter-packs/sales/KnowledgeBase/Pricing.md +9 -0
  558. package/starter-packs/sales/Plugins/sales-starter/LICENSE +202 -0
  559. package/starter-packs/sales/Plugins/sales-starter/SOURCE.md +10 -0
  560. package/starter-packs/sales/Plugins/sales-starter/access.md +19 -0
  561. package/starter-packs/sales/Plugins/sales-starter/plugin.json +10 -0
  562. package/starter-packs/sales/Plugins/sales-starter/skills/account-context/SKILL.md +94 -0
  563. package/starter-packs/sales/Plugins/sales-starter/skills/account-plan/SKILL.md +95 -0
  564. package/starter-packs/sales/Plugins/sales-starter/skills/account-research/SKILL.md +99 -0
  565. package/starter-packs/sales/Plugins/sales-starter/skills/account-tiering/SKILL.md +101 -0
  566. package/starter-packs/sales/Plugins/sales-starter/skills/call-prep/SKILL.md +111 -0
  567. package/starter-packs/sales/Plugins/sales-starter/skills/call-summary/SKILL.md +111 -0
  568. package/starter-packs/sales/Plugins/sales-starter/skills/close-plan/SKILL.md +106 -0
  569. package/starter-packs/sales/Plugins/sales-starter/skills/competitive-intelligence/SKILL.md +102 -0
  570. package/starter-packs/sales/Plugins/sales-starter/skills/create-an-asset/SKILL.md +105 -0
  571. package/starter-packs/sales/Plugins/sales-starter/skills/crm-hygiene-check/SKILL.md +103 -0
  572. package/starter-packs/sales/Plugins/sales-starter/skills/customer-health/SKILL.md +108 -0
  573. package/starter-packs/sales/Plugins/sales-starter/skills/customer-voice/SKILL.md +94 -0
  574. package/starter-packs/sales/Plugins/sales-starter/skills/daily-briefing/SKILL.md +61 -0
  575. package/starter-packs/sales/Plugins/sales-starter/skills/deal-advance-gap/SKILL.md +102 -0
  576. package/starter-packs/sales/Plugins/sales-starter/skills/deal-review/SKILL.md +105 -0
  577. package/starter-packs/sales/Plugins/sales-starter/skills/deal-signals/SKILL.md +96 -0
  578. package/starter-packs/sales/Plugins/sales-starter/skills/deal-slip-scenario/SKILL.md +104 -0
  579. package/starter-packs/sales/Plugins/sales-starter/skills/draft-outreach/SKILL.md +116 -0
  580. package/starter-packs/sales/Plugins/sales-starter/skills/end-of-day/SKILL.md +114 -0
  581. package/starter-packs/sales/Plugins/sales-starter/skills/expansion-whitespace/SKILL.md +97 -0
  582. package/starter-packs/sales/Plugins/sales-starter/skills/forecast/SKILL.md +100 -0
  583. package/starter-packs/sales/Plugins/sales-starter/skills/handle-objection/SKILL.md +93 -0
  584. package/starter-packs/sales/Plugins/sales-starter/skills/inbox-sweep/SKILL.md +114 -0
  585. package/starter-packs/sales/Plugins/sales-starter/skills/lead-triage/SKILL.md +106 -0
  586. package/starter-packs/sales/Plugins/sales-starter/skills/log-activity/SKILL.md +111 -0
  587. package/starter-packs/sales/Plugins/sales-starter/skills/pipeline-review/SKILL.md +97 -0
  588. package/starter-packs/sales/Plugins/sales-starter/skills/renewal-radar/SKILL.md +95 -0
  589. package/starter-packs/sales/Plugins/sales-starter/skills/rep-context/SKILL.md +90 -0
  590. package/starter-packs/sales/Plugins/sales-starter/skills/route-lead/SKILL.md +111 -0
  591. package/starter-packs/sales/Plugins/sales-starter/skills/sales-setup/SKILL.md +200 -0
  592. package/starter-packs/sales/Plugins/sales-starter/skills/schedule-meeting/SKILL.md +99 -0
  593. package/starter-packs/sales/Plugins/sales-starter/skills/stakeholder-map/SKILL.md +107 -0
  594. package/starter-packs/sales/Plugins/sales-starter/skills/team-pipeline/SKILL.md +105 -0
  595. package/starter-packs/sales/Plugins/sales-starter/skills/update-opportunity/SKILL.md +112 -0
  596. package/starter-packs/sales/Plugins/sales-starter/skills/weekly-wrap/SKILL.md +90 -0
  597. package/starter-packs/sales/Plugins/sales-starter/skills/win-loss-review/SKILL.md +88 -0
  598. package/starter-packs/sales/pack.yaml +13 -0
  599. package/starter-packs/support/KnowledgeBase/Escalations.md +9 -0
  600. package/starter-packs/support/KnowledgeBase/Glossary.md +9 -0
  601. package/starter-packs/support/KnowledgeBase/Known issues.md +9 -0
  602. package/starter-packs/support/KnowledgeBase/Products.md +9 -0
  603. package/starter-packs/support/KnowledgeBase/Tone of voice.md +9 -0
  604. package/starter-packs/support/Plugins/support-starter/LICENSE +202 -0
  605. package/starter-packs/support/Plugins/support-starter/SOURCE.md +10 -0
  606. package/starter-packs/support/Plugins/support-starter/access.md +19 -0
  607. package/starter-packs/support/Plugins/support-starter/plugin.json +10 -0
  608. package/starter-packs/support/Plugins/support-starter/skills/customer-escalation/SKILL.md +246 -0
  609. package/starter-packs/support/Plugins/support-starter/skills/customer-research/SKILL.md +250 -0
  610. package/starter-packs/support/Plugins/support-starter/skills/draft-response/SKILL.md +416 -0
  611. package/starter-packs/support/Plugins/support-starter/skills/kb-article/SKILL.md +350 -0
  612. package/starter-packs/support/Plugins/support-starter/skills/ticket-triage/SKILL.md +273 -0
  613. package/starter-packs/support/pack.yaml +12 -0
@@ -17,6 +17,10 @@ import { getDb, type Database } from '../modules/database/connection.js';
17
17
  import { runCoreMigrations } from '../modules/database/migrate.js';
18
18
  import { coreMigrationsDir } from '../assets.js';
19
19
  import { WorkspaceService } from '../modules/workspace/workspace.service.js';
20
+ import { AccountLinkService } from '../modules/embed/account-link.service.js';
21
+ import { EmbedService } from '../modules/embed/embed.service.js';
22
+ import { McpAppService, type IMcpAppService } from '../modules/embed/mcp-app.js';
23
+ import { createFileReaderRegistry } from '../modules/workspace/file-readers/file-reader.registry.js';
20
24
  import { RoutineWritePolicyService } from '../modules/workspace/routine-write-policy.js';
21
25
  import { KbStartupRunner } from '../modules/workspace/startup/kb-startup-runner.js';
22
26
  import { GroupsToPluginsStep } from '../modules/workspace/startup/steps/groups-to-plugins.step.js';
@@ -26,7 +30,7 @@ import { PersonalSpacesStep } from '../modules/workspace/startup/steps/personal-
26
30
  import { TemplateFilesStep } from '../modules/workspace/startup/steps/template-files.step.js';
27
31
  import { RolesYamlStep } from '../modules/workspace/startup/steps/roles-yaml.step.js';
28
32
  import { buildSeedTree } from '../modules/workspace/startup/steps/seed-tree.js';
29
- import { DeploymentSettingsService } from '../modules/settings/deployment-settings.service.js';
33
+ import { DeploymentSettingsService, retireMergedBranchesOn } from '../modules/settings/deployment-settings.service.js';
30
34
  import { KbSyncService } from '../modules/kb-sync/kb-sync.service.js';
31
35
  import { NodeFs } from '../modules/kb-fs/node-fs.js';
32
36
  import { assertKbDirNameFree } from '../modules/kb-fs/repo-path.js';
@@ -55,17 +59,21 @@ function parseDomainList(raw: string): string[] {
55
59
  }
56
60
  import { SpillStore } from '../modules/workspace/spill-store.js';
57
61
  import { AgentUploadStore, assertUploadsRootOutsideWorkspaces } from '../modules/workspace/agent-upload.store.js';
62
+ import { AgentDownloadStore, type IAgentDownloadStore } from '../modules/workspace/agent-download.store.js';
63
+ import { createDownloadFetcherIdentifier } from '../modules/workspace/agent-download.routes.js';
64
+ import type { Request } from 'express';
58
65
  import { DocExtractService } from '../modules/workspace/file-readers/doc-extract.service.js';
59
66
  import { UuidSessionSink, type ISessionSink } from '../modules/workspace/session-sink.js';
60
67
  import { AuthService } from '../modules/auth/auth.service.js';
61
68
  import { AccountErasureService } from '../modules/auth/account-erasure.service.js';
62
69
  import { OidcAuthProvider, oidcSettingsFrom } from '../modules/auth/oidc-auth-provider.js';
63
- import { createAuthMiddleware } from '../modules/auth/auth.middleware.js';
70
+ import { createAuthMiddleware, readAuthCookie } from '../modules/auth/auth.middleware.js';
64
71
  import { AccessControlService, loadActiveGroups } from '../modules/access/access-control.service.js';
65
72
  import { CreatorAccessService } from '../modules/access/creator-access.js';
66
73
  import { ChangeReadGate } from '../modules/access/change-read-gate.js';
67
74
  import { GroupsAdminService } from '../modules/access/groups-admin.service.js';
68
75
  import { UserAccessRemovalService } from '../modules/access/user-access-removal.service.js';
76
+ import { makeRolesYamlWriteValidator } from '../modules/access-model/roles-yaml-guard.js';
69
77
  import { PendingSkillsService, SkillService } from '../modules/skills/index.js';
70
78
  import { PendingToolsService, ToolManualService } from '../modules/tool-manuals/index.js';
71
79
  import { McpServerEditService } from '../modules/tool-manuals/mcp-server-edit.service.js';
@@ -110,6 +118,7 @@ import { ReviewWorkflowService } from '../modules/workflow/review-workflow/revie
110
118
  import { FileLockService } from '../modules/workflow/file-lock.service.js';
111
119
  import { WorkflowEventBus } from '../modules/workflow/event-bus.js';
112
120
  import { FileChangeNotifier } from '../modules/kb-fs/file-change-notifier.js';
121
+ import { StarterPackService } from '../modules/onboarding/starter-pack.service.js';
113
122
  import { WorkflowService } from '../modules/workflow/workflow.service.js';
114
123
  import { WorkflowHooks } from '../modules/workflow/workflow-hooks.js';
115
124
  import { PendingCommitsService } from '../modules/workflow/pending-commits.service.js';
@@ -132,6 +141,7 @@ import {
132
141
  } from '../modules/tool-auth/internal-token.service.js';
133
142
  import {
134
143
  createToolAuthMiddleware,
144
+ createTokenVerifier,
135
145
  createManualAuthMiddleware,
136
146
  } from '../modules/tool-auth/tool-auth.middleware.js';
137
147
  import { unmeteredLlmUsage, type ILlmUsageMeter } from '../modules/tool-auth/llm-usage-meter.js';
@@ -229,6 +239,14 @@ export interface CoreServices {
229
239
  spillStore: SpillStore;
230
240
  /** The bytes an agent uploaded, held until `apply_file_upload` lands them or their token expires. */
231
241
  agentUploadStore: AgentUploadStore;
242
+ /** The bytes `request_file_download` captured, held until their one-time link is fetched or expires. */
243
+ agentDownloadStore: IAgentDownloadStore;
244
+ /**
245
+ * Every user a download fetch identifies itself as, by its bearer and its
246
+ * session cookie — none when it carries none that verifies — so the
247
+ * download route can refuse a link presented by someone it was not issued to.
248
+ */
249
+ agentDownloadFetcher: (req: Request) => Promise<string[]>;
232
250
  docExtractService: DocExtractService;
233
251
  accessControl: AccessControlService;
234
252
  creatorAccess: CreatorAccessService;
@@ -258,6 +276,11 @@ export interface CoreServices {
258
276
  toolDeleteService: ToolDeleteService;
259
277
  pluginIndexService: PluginIndexService;
260
278
  pluginProvisionService: PluginProvisionService;
279
+ /**
280
+ * "What does your team do?" — the starter pack a new knowledge base's admin
281
+ * may fill it from, and the record of what was chosen. See modules/onboarding.
282
+ */
283
+ starterPackService: StarterPackService;
261
284
  joinRequestsService: JoinRequestsService;
262
285
  /**
263
286
  * Records a join request and finishes it in the background. Its `sweep()`
@@ -335,6 +358,14 @@ export interface CoreServices {
335
358
  connectionProbeService: ConnectionProbeService;
336
359
  externalApiKeyService: ExternalApiKeyService;
337
360
  internalTokenService: InternalTokenService;
361
+ /**
362
+ * The embed surface: the token-minted page a chat host frames, and the
363
+ * account links that let an outside identity reach it. Exposed so an
364
+ * overlay can mint for its own consumers and register a node-id resolver.
365
+ */
366
+ embedService: EmbedService;
367
+ /** The MCP Apps this deployment serves — the `open_page` view and its sandbox metadata. */
368
+ mcpAppService: IMcpAppService;
338
369
  mcpService: McpService;
339
370
  mcpAuthMiddleware: ReturnType<typeof createMcpAuthMiddleware>;
340
371
  mcpOAuthProvider: BevelOAuthProvider;
@@ -685,6 +716,29 @@ export async function createCoreServices(
685
716
  publicBaseUrl: config.publicBackendUrl,
686
717
  tokenPrefix: config.uploadTokenPrefix,
687
718
  });
719
+ // The way OUT: bytes `request_file_download` captured, held beside the
720
+ // upload root — outside every workspace, for the same reason — until their
721
+ // one-time link is fetched or expires.
722
+ const agentDownloadsRoot = path.resolve(config.agentUploadsRoot, '..', 'agent-downloads');
723
+ // An upload root that is itself named `agent-downloads` would make the two
724
+ // stores one directory, each sweeping the other's files.
725
+ if (agentDownloadsRoot === path.resolve(config.agentUploadsRoot)) {
726
+ throw new Error(
727
+ 'AGENT_UPLOADS_ROOT must not be a directory named `agent-downloads`: that name, beside it, is the agent download root.',
728
+ );
729
+ }
730
+ await assertUploadsRootOutsideWorkspaces(agentDownloadsRoot, config.workspacesRoot, {
731
+ name: 'The agent download root (`agent-downloads`, beside AGENT_UPLOADS_ROOT)',
732
+ why:
733
+ 'captured download bytes wait there for their one-time links, so a root inside a workspace would let the ' +
734
+ 'file tools read them. Point AGENT_UPLOADS_ROOT at a directory whose parent is outside WORKSPACES_ROOT.',
735
+ });
736
+ const agentDownloadStore = new AgentDownloadStore({
737
+ root: agentDownloadsRoot,
738
+ publicBaseUrl: config.publicBackendUrl,
739
+ // `<tenant>-down_`: recognisable by shape beside the upload token.
740
+ tokenPrefix: config.uploadTokenPrefix.replace(/up_$/, 'down_'),
741
+ });
688
742
  // Office-document/PDF text extraction for `read_file`/`grep`, cached by
689
743
  // content hash beside the workspaces root (see `DocExtractionCache`).
690
744
  const docExtractService = new DocExtractService(config.docExtractCacheRoot);
@@ -869,6 +923,9 @@ export async function createCoreServices(
869
923
  // it reach every hook point.
870
924
  workflowHooks,
871
925
  );
926
+ // The leftover-branch cleanup asks the Deployment page at every round, so
927
+ // switching it off there applies without a restart.
928
+ workflowService.leftoverCleanupEnabled = () => retireMergedBranchesOn(settings.resolve('retireMergedBranches'));
872
929
 
873
930
  // Join requests: derived entirely from two copies of a plugin's `access.md`
874
931
  // (the request's branch vs the default branch), so it holds no state — it
@@ -1053,6 +1110,27 @@ export async function createCoreServices(
1053
1110
  [config.adminEmail],
1054
1111
  );
1055
1112
 
1113
+ // The starter-pack question: one commit on the default branch through the
1114
+ // same batch write the roles admin uses, the choice kept as a deployment
1115
+ // setting. Read by its routes and by `start_session`'s first-run note.
1116
+ const starterPackService = new StarterPackService({
1117
+ packsDir: config.starterPacksDir,
1118
+ kb,
1119
+ workspaceService,
1120
+ workflow: workflowService,
1121
+ adminAccess,
1122
+ settings,
1123
+ accessControl,
1124
+ disk,
1125
+ pluginSource,
1126
+ pluginLocks: pluginProvisionService,
1127
+ events: eventBus,
1128
+ fileChanges: fileChangeNotifier,
1129
+ // Its own lock: one starter-pack choice at a time, a concern no other
1130
+ // service's mutex serialises.
1131
+ choosing: new WorkspaceMutex(),
1132
+ });
1133
+
1056
1134
  // In-app update check: lazily compares the running release version against
1057
1135
  // the newest published GitHub release, only when an admin's browser asks —
1058
1136
  // no timers, so a deployment nobody looks at makes zero calls. The flag
@@ -1152,9 +1230,13 @@ export async function createCoreServices(
1152
1230
  // Connection keys also come as GitHub-shaped links (`gho_…`, kind
1153
1231
  // `github-link`): the same key, minted by the marketplace facade below when
1154
1232
  // a person connects an account on claude.ai, told apart by its stored kind.
1155
- const externalApiKeyService = new ExternalApiKeyService(db, config.externalApiKeyPrefix, {
1156
- [GITHUB_LINK_KEY_KIND]: GITHUB_LINK_KEY_SPEC,
1157
- });
1233
+ const externalApiKeyService = new ExternalApiKeyService(
1234
+ db,
1235
+ config.externalApiKeyPrefix,
1236
+ { [GITHUB_LINK_KEY_KIND]: GITHUB_LINK_KEY_SPEC },
1237
+ // A key's first use tells its owner's open tabs that the agent arrived.
1238
+ eventBus,
1239
+ );
1158
1240
 
1159
1241
  // The facade that lets products which sync marketplaces only from a GitHub
1160
1242
  // Enterprise Server (claude.ai, Cowork) add the per-user marketplace:
@@ -1192,6 +1274,34 @@ export async function createCoreServices(
1192
1274
  const agentAuditService = new AgentAuditService(db, externalApiKeyService, () =>
1193
1275
  retentionDaysFrom(settings.resolve('auditRetentionDays')),
1194
1276
  );
1277
+ // The embed surface. It reads files through the workspace service and
1278
+ // judges them with the same access resolver the app file page uses, so what
1279
+ // a reader may see and change inside a chat is what they may see and change
1280
+ // in the app — never a second answer to the same question.
1281
+ const embedService = new EmbedService(
1282
+ // The RESOLVED checkout folder, not the env's: `config.kbDirName` is only
1283
+ // the environment value, empty on a deployment that took the default or
1284
+ // named it in setup, and every path the embed builds starts with it.
1285
+ { ...config, kbDirName },
1286
+ kb,
1287
+ workspaceService,
1288
+ accessControl,
1289
+ authService,
1290
+ workflowService,
1291
+ gitService,
1292
+ new AccountLinkService(db),
1293
+ // The SAME extension-to-reader registry `read_file` dispatches on, so the
1294
+ // embed answer to "is this text, or bytes a renderer fetches?" cannot
1295
+ // disagree with what a read of the file returns.
1296
+ createFileReaderRegistry(docExtractService),
1297
+ // The SAME pre-disk gate the file editor and the agent tools run: a
1298
+ // `roles.yaml` that would not parse is refused before it is written, from
1299
+ // a chat exactly as from the app.
1300
+ makeRolesYamlWriteValidator(kbDirName),
1301
+ );
1302
+ // The `ui://` view `open_page` carries, with the one origin it may frame:
1303
+ // this deployment own public origin.
1304
+ const mcpAppService = new McpAppService({ publicFrontendUrl: config.publicFrontendUrl });
1195
1305
  const mcpService = new McpService(
1196
1306
  {
1197
1307
  // Loopback to our own REST tool surface — 127.0.0.1 (not localhost) to pin
@@ -1225,6 +1335,9 @@ export async function createCoreServices(
1225
1335
  (bearer) => mcpOAuthProvider.revokeByAccessToken(bearer),
1226
1336
  // Every attributable call lands in the Audit log through this.
1227
1337
  agentAuditService,
1338
+ // The views the endpoint serves over resources/read, and the tools that
1339
+ // carry them.
1340
+ mcpAppService,
1228
1341
  );
1229
1342
  // A changed secret invalidates what the proxy built from the old value for
1230
1343
  // that user (null = shared secret → everyone): remembered manual failures,
@@ -1247,6 +1360,8 @@ export async function createCoreServices(
1247
1360
  stateSecret: config.jwtSecret,
1248
1361
  publicFrontendUrl: config.publicFrontendUrl,
1249
1362
  tokenPrefix: config.mcpOAuthTokenPrefix,
1363
+ // An agent connection's first use tells its owner's open tabs the agent arrived.
1364
+ events: eventBus,
1250
1365
  });
1251
1366
  // RFC 9728 pointer carried on every MCP 401 challenge so OAuth-capable
1252
1367
  // clients discover the AS. Single source of truth for the resource id.
@@ -1283,8 +1398,22 @@ export async function createCoreServices(
1283
1398
  loadActiveGroups,
1284
1399
  });
1285
1400
  const writeAccess = ports.writeAccess ?? alwaysWritable;
1286
- const toolHandlerFactory = createToolHandlerFactory(resolveToolContext, writeAccess);
1401
+ // The branch every tool call runs on is resolved by the handler, before the
1402
+ // tool: the default read live (a rename in the settings is the next call's
1403
+ // default), the existence asked without cloning anything.
1404
+ const toolHandlerFactory = createToolHandlerFactory(resolveToolContext, writeAccess, {
1405
+ defaultBranch: () => kb.defaultBranch,
1406
+ isMissing: (branch) => workspaceService.isBranchMissing(branch),
1407
+ });
1287
1408
  const toolAuthMiddleware = createToolAuthMiddleware(externalApiKeyService, internalTokenService, authService);
1409
+ const verifyToolToken = createTokenVerifier(externalApiKeyService, internalTokenService, authService);
1410
+ // Every credential kind this server issues — connection keys, internal
1411
+ // tokens and app sessions (bearer or cookie) — so a fetch carrying another
1412
+ // user's identity of ANY kind is refused the link.
1413
+ const agentDownloadFetcher: (req: Request) => Promise<string[]> = createDownloadFetcherIdentifier(
1414
+ { verifyToolToken, verifySession: (token) => authService.verifyToken(token) },
1415
+ readAuthCookie,
1416
+ );
1288
1417
  // Read-only manual endpoints accept the above PLUS a browser JWT, so a
1289
1418
  // logged-in user can browse the catalog with their session. Execution routes
1290
1419
  // keep `toolAuthMiddleware` (no JWT), so a session can read but not invoke.
@@ -1452,6 +1581,8 @@ export async function createCoreServices(
1452
1581
  kbDirName,
1453
1582
  spillStore,
1454
1583
  agentUploadStore,
1584
+ agentDownloadStore,
1585
+ agentDownloadFetcher,
1455
1586
  docExtractService,
1456
1587
  accessControl,
1457
1588
  creatorAccess,
@@ -1466,6 +1597,7 @@ export async function createCoreServices(
1466
1597
  agentGuideSections: agentGuideSectionsReader,
1467
1598
  pluginIndexService,
1468
1599
  pluginProvisionService,
1600
+ starterPackService,
1469
1601
  joinRequestsService,
1470
1602
  pluginJoinRequestJobs,
1471
1603
  pluginLinkIndex,
@@ -1499,6 +1631,8 @@ export async function createCoreServices(
1499
1631
  connectionProbeService,
1500
1632
  externalApiKeyService,
1501
1633
  internalTokenService,
1634
+ embedService,
1635
+ mcpAppService,
1502
1636
  mcpService,
1503
1637
  mcpAuthMiddleware,
1504
1638
  mcpOAuthProvider,
@@ -291,7 +291,7 @@ export interface BootableCore {
291
291
  config: { workspacesRoot: string };
292
292
  kbDirName: string;
293
293
  kbStartupRunner: Pick<KbStartupRunner, 'runAll' | 'retryUntilMaintained'>;
294
- workflowService: Pick<WorkflowService, 'closeChangeRequestsWithDeletedBranches'>;
294
+ workflowService: Pick<WorkflowService, 'closeChangeRequestsWithDeletedBranches' | 'tidyAfterSweep'>;
295
295
  pluginJoinRequestJobs: Pick<PluginJoinRequestJobs, 'startSweeping'>;
296
296
  /**
297
297
  * The startup phase's retry, when the boot survived an unreachable remote
@@ -390,7 +390,11 @@ export async function startCore<C extends BootableCore>(
390
390
  crLog.info(`closed ${n} change request${n === 1 ? '' : 's'} with a deleted branch`);
391
391
  }
392
392
  })
393
- .catch((err) => crLog.warn('deleted-branch sweep failed:', { err }));
393
+ .catch((err) => crLog.warn('deleted-branch sweep failed:', { err }))
394
+ // Then the tidy-up: open requests that propose nothing are closed, and the
395
+ // branches merged requests left behind removed (behind its own setting).
396
+ // Fails safe on a failed fetch, and never throws.
397
+ .then(() => core.workflowService.tidyAfterSweep());
394
398
 
395
399
  // Recorded join requests that are still owed, resumed — now, and then on a
396
400
  // timer. SEQUENCED AFTER the startup phase for the same reason as the sweep
@@ -437,6 +441,15 @@ export interface CoreStopDeps {
437
441
  * Optional: a caller that has not built one passes nothing.
438
442
  */
439
443
  agentUploadStore?: { stopSweeping(): void; drainSweep(): Promise<void> };
444
+ /** The agent download store, whose sweep deletes captured bytes nobody fetched — stopped for the same reason. */
445
+ agentDownloadStore?: { stopSweeping(): void; drainSweep(): Promise<void> };
446
+ /**
447
+ * The workflow service, for the tidy-up it runs after each sweep (closing
448
+ * empty requests, removing leftover branches): detached from whatever
449
+ * started it, so stopped and awaited here before the pool goes. Optional:
450
+ * a caller that has not built one passes nothing.
451
+ */
452
+ workflowService?: { stopTidying(): void; drainTidy(): Promise<void> };
440
453
  /** The startup phase's retry, if the boot left one asking — see {@link BootableCore.startupRetry}. */
441
454
  startupRetry?: { stop(): void } | null;
442
455
  /** The database — its pool is ended last, once nothing above can still need it. */
@@ -524,10 +537,14 @@ async function releaseCore(deps: CoreStopDeps, remaining: () => number, log: (m:
524
537
  // synchronous, and it only clears an interval and tells a sweep already
525
538
  // running to stop deleting.
526
539
  deps.agentUploadStore?.stopSweeping();
540
+ deps.agentDownloadStore?.stopSweeping();
527
541
  // A startup phase still asking for an unreachable remote stops asking:
528
542
  // synchronous, and nothing after it must be able to clone into a
529
543
  // workspaces folder that is about to belong to nobody.
530
544
  deps.startupRetry?.stop();
545
+ // The post-sweep tidy-up: no new round, and the one under way stops at its
546
+ // next request or branch. Synchronous.
547
+ deps.workflowService?.stopTidying();
531
548
  // Clearing the interval stops future ticks; it does nothing to a job a
532
549
  // tick already started, which holds a claim it heartbeats through the
533
550
  // pool and is mid-clone or mid-push. Awaited here, in the budget: a job
@@ -543,6 +560,15 @@ async function releaseCore(deps: CoreStopDeps, remaining: () => number, log: (m:
543
560
  if (deps.agentUploadStore) {
544
561
  await bounded(deps.agentUploadStore.drainSweep(), remaining(), 'finishing the upload sweep', log);
545
562
  }
563
+ if (deps.agentDownloadStore) {
564
+ await bounded(deps.agentDownloadStore.drainSweep(), remaining(), 'finishing the download sweep', log);
565
+ }
566
+ // The tidy-up in flight fetches and deletes branches through the pool and
567
+ // the default branch's checkout: awaited, so the next graph for this
568
+ // tenant cannot find a branch deletion still running under it.
569
+ if (deps.workflowService) {
570
+ await bounded(deps.workflowService.drainTidy(), remaining(), 'finishing the branch tidy-up', log);
571
+ }
546
572
  await bounded(deps.commitWorker.stop(), remaining(), 'stopping the commit worker', log);
547
573
  if (deps.secretsScope !== undefined) unregisterBevelSecretsVariableLoader(deps.secretsScope);
548
574
  await bounded(closeDb(deps.db), remaining(), 'ending the database pool', log);
@@ -1,7 +1,7 @@
1
1
  import dotenv from 'dotenv';
2
2
  import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
- import { defaultKbTemplateDir } from './assets.js';
4
+ import { defaultKbTemplateDir, defaultStarterPacksDir } from './assets.js';
5
5
  import { assertKeyDecodesTo32Bytes } from './shared/token-crypto.js';
6
6
  import { DEFAULT_GIT_TIMEOUT_MS } from './modules/workflow/git/node-git-runner.js';
7
7
  import { DEFAULT_DB_SCHEMA, assertSchemaName } from './modules/database/connection.js';
@@ -103,11 +103,13 @@ export interface TenantConfig {
103
103
  readonly gitUsername: string;
104
104
  readonly gitToken: string;
105
105
  readonly kbTemplateDir: string;
106
+ readonly starterPacksDir: string;
106
107
  readonly updateCheckEnabled: boolean;
107
108
  readonly loginPasswordEnabled: boolean;
108
109
  readonly allowedEmailDomains: string[];
109
110
  readonly secretsEncKey: string;
110
111
  readonly internalTokenSecret: string;
112
+ readonly embedSharedSecret: string;
111
113
  readonly trustProxy: string;
112
114
  readonly gitTimeoutMs: number;
113
115
  readonly publicBackendUrl: string;
@@ -276,6 +278,14 @@ export class CoreConfig implements TenantConfig, ProcessConfig {
276
278
  * existing one. Override with `KB_TEMPLATE_DIR`.
277
279
  */
278
280
  readonly kbTemplateDir: string;
281
+ /**
282
+ * Filesystem path to the starter packs a new knowledge base's admin may
283
+ * pick from (the `starter-packs/` folder shipped inside this package — see
284
+ * `defaultStarterPacksDir()`): one folder per team, each a `pack.yaml` with
285
+ * the pages and the plugin it adds. A distribution offers its own with
286
+ * `STARTER_PACKS_DIR`; a folder holding no valid pack offers none.
287
+ */
288
+ readonly starterPacksDir: string;
279
289
  /**
280
290
  * In-app update check. When true (default), `GET /api/update-check` lazily
281
291
  * asks api.github.com for the newest Hexis release — only when an admin's
@@ -337,6 +347,17 @@ export class CoreConfig implements TenantConfig, ProcessConfig {
337
347
  * independently of user sessions.
338
348
  */
339
349
  readonly internalTokenSecret: string;
350
+ /**
351
+ * The shared secret the Atlassian connector presents to \`POST
352
+ * /api/embed/token\` (\`EMBED_SHARED_SECRET\`). Unset on a deployment that
353
+ * has no connector pointed at it, which 404s that one route — the embed
354
+ * surface itself needs no secret, because the MCP App mints through the
355
+ * authenticated MCP session instead.
356
+ *
357
+ * There is deliberately NO framing setting beside it: any site may frame
358
+ * the embed page (see the embed module), so there is no allowlist to keep.
359
+ */
360
+ readonly embedSharedSecret: string;
340
361
  /**
341
362
  * Express `trust proxy` setting, from `TRUST_PROXY`: the number of reverse
342
363
  * proxy hops in front of this backend (e.g. `1`), or an address/CIDR list
@@ -477,6 +498,7 @@ export class CoreConfig implements TenantConfig, ProcessConfig {
477
498
  // Default: the `kb-template/` folder shipped inside this package (works
478
499
  // both from src/ and compiled dist/ — see assets.ts).
479
500
  this.kbTemplateDir = process.env.KB_TEMPLATE_DIR || defaultKbTemplateDir();
501
+ this.starterPacksDir = process.env.STARTER_PACKS_DIR || defaultStarterPacksDir();
480
502
  this.updateCheckEnabled =
481
503
  (process.env.UPDATE_CHECK ?? 'true').trim().toLowerCase() !== 'false';
482
504
  this.allowedEmailDomains = (process.env.ALLOWED_EMAIL_DOMAINS || '')
@@ -503,6 +525,7 @@ export class CoreConfig implements TenantConfig, ProcessConfig {
503
525
  // key never gets past this line.
504
526
  assertKeyDecodesTo32Bytes(this.secretsEncKey, secretsKeySource);
505
527
  this.internalTokenSecret = (process.env.INTERNAL_TOKEN_SECRET || '').trim();
528
+ this.embedSharedSecret = (process.env.EMBED_SHARED_SECRET || '').trim();
506
529
  // Setting DOMAIN declares "the bundled Caddy `https` profile fronts this
507
530
  // deployment" — one proxy hop, and the public origin IS that domain. The
508
531
  // three values below therefore default from it, so `DOMAIN=x.example.com`
package/src/index.ts CHANGED
@@ -47,8 +47,8 @@ export {
47
47
  type LeasedWorker,
48
48
  } from './core/lifecycle.js';
49
49
 
50
- // Packaged assets (migrations/, kb-template/, agent-guide/) + the migration runners.
51
- export { agentGuideDir, coreMigrationsDir, defaultKbTemplateDir } from './assets.js';
50
+ // Packaged assets (migrations/, kb-template/, agent-guide/, starter-packs/) + the migration runners.
51
+ export { agentGuideDir, coreMigrationsDir, defaultKbTemplateDir, defaultStarterPacksDir } from './assets.js';
52
52
  export {
53
53
  runCoreMigrations,
54
54
  runEnterpriseMigrations,
@@ -216,6 +216,25 @@ describe('AccessControlService', () => {
216
216
  expect(await svc.canWrite(workspaceId, 'ali@bevel.software', 'Knowledge/Secret/Foo.md')).toBe(false);
217
217
  });
218
218
 
219
+ // What deleting a nested access.md (delete_file, or the app's delete) does:
220
+ // the folder falls back to its parent's rules, nothing else to undo.
221
+ it('once a nested access.md is deleted, its folder follows the parent\'s rules', async () => {
222
+ const { workspaceDir, repo } = await seedWorkspace(root, workspaceId);
223
+ await writeFile(repo, 'roles.yaml', ROLES_YAML);
224
+ await writeFile(repo, 'access.md', '---\nread:\n - everyone\nwrite:\n - Admin\n---\n');
225
+ await writeFile(repo, 'Team/access.md', '---\nread:\n - deny Felix Kissel <felix@example.com>\n---\n');
226
+ await writeFile(repo, 'Team/plan.md', 'plan');
227
+
228
+ const svc = new AccessControlService(stubWorkspaceService(workspaceId, workspaceDir), PROCESS_MAP_DIR, new NodeFs());
229
+ expect(await svc.canRead(workspaceId, 'felix@example.com', 'Team/plan.md')).toBe(false);
230
+
231
+ await fs.rm(path.join(repo, 'Team/access.md'));
232
+ svc.invalidate(workspaceId);
233
+
234
+ expect(await svc.canRead(workspaceId, 'felix@example.com', 'Team/plan.md')).toBe(true);
235
+ expect(await svc.canWrite(workspaceId, 'felix@example.com', 'Team/plan.md')).toBe(false);
236
+ });
237
+
219
238
  it('closeness beats tier: a closer everyone grant overrides a farther email deny', async () => {
220
239
  const { workspaceDir, repo } = await seedWorkspace(root, workspaceId);
221
240
  await writeFile(repo, 'roles.yaml', ROLES_YAML);
@@ -263,6 +263,19 @@ export interface IAccessControl {
263
263
  relativePath: string,
264
264
  ): Promise<boolean>;
265
265
 
266
+ /**
267
+ * Batched `canDownload` — one config load per call, the same resolution
268
+ * as the single form, each path's own frontmatter `download:` rules
269
+ * included. A folder download judges every file it would pack through
270
+ * this, so a folder of a thousand files costs one model load, not a
271
+ * thousand.
272
+ */
273
+ canDownloadBatch(
274
+ workspaceId: string,
275
+ userEmail: string,
276
+ relativePaths: string[],
277
+ ): Promise<Map<string, boolean>>;
278
+
266
279
  /**
267
280
  * True iff `userEmail` is an `owner` of `relativePath` per the current
268
281
  * access tree, resolved from the `owner:` lists alone (the `write` /
@@ -1581,6 +1581,22 @@ export class AccessControlService implements IAccessControl {
1581
1581
  return hasPermissionResolved(model, 'download', userEmail, relativePath, own);
1582
1582
  }
1583
1583
 
1584
+ async canDownloadBatch(
1585
+ workspaceId: string,
1586
+ userEmail: string,
1587
+ relativePaths: string[],
1588
+ ): Promise<Map<string, boolean>> {
1589
+ const model = await this.loadModel(workspaceId);
1590
+ const repoDir = await this.repoDir(workspaceId);
1591
+ // Parallel own-entries reads, memoized — same shape as `canWriteBatch`.
1592
+ const owns = await Promise.all(relativePaths.map((p) => this.cachedOwnEntries(workspaceId, repoDir, p)));
1593
+ const result = new Map<string, boolean>();
1594
+ relativePaths.forEach((p, i) => {
1595
+ result.set(p, hasPermissionResolved(model, 'download', userEmail, p, owns[i]));
1596
+ });
1597
+ return result;
1598
+ }
1599
+
1584
1600
  async canOwnerBatch(
1585
1601
  workspaceId: string,
1586
1602
  userEmail: string,
@@ -35,7 +35,7 @@ export async function ensureDirectorySyncBot(db: Database): Promise<AuthUser> {
35
35
  .returning();
36
36
  if (inserted.length > 0) {
37
37
  const row = inserted[0];
38
- log.info(`created sync-bot user id=${row.id} email=${row.email}`);
38
+ log.info(`created sync-bot user id=${row.id}`);
39
39
  return { id: row.id, email: row.email, name: row.name, avatarUrl: row.avatarUrl ?? undefined };
40
40
  }
41
41
  const [row] = await db
@@ -299,6 +299,18 @@ describe('what the guide tells an agent', () => {
299
299
  expect(prose).toContain('add people to existing roles, and use a GROUP for a task- or team-scoped set of people');
300
300
  });
301
301
 
302
+ it('describes delete_branch where it says what an agent does with branches', async () => {
303
+ const text = section(await composeAgentGuide(DEFAULT_KB_LAYOUT), '### An agent proposes and syncs; a person merges');
304
+ const prose = text.replace(/\s+/g, ' ');
305
+ expect(prose).toContain('`delete_branch`');
306
+ expect(prose).toContain('Only its author');
307
+ expect(prose).toContain('`dryRun: true`');
308
+ expect(prose).toContain('`discardUnmerged: true`');
309
+ expect(prose).toContain('that proposes nothing is closed by the delete');
310
+ expect(prose).toContain('its author can withdraw it, or an Admin can decline it, in the app');
311
+ expect(prose).toContain('`lastCommit`');
312
+ });
313
+
302
314
  it('documents giving a role to a group, with an example that parses as a valid roles.yaml', async () => {
303
315
  const text = section(await composeAgentGuide(DEFAULT_KB_LAYOUT), '### Giving a role to a group');
304
316
  const prose = text.replace(/\s+/g, ' ');
@@ -326,3 +338,49 @@ describe('what the guide tells an agent', () => {
326
338
  expect(parsed.index.byEmail.get('pat@example.com')?.has('role/admin')).toBe(false);
327
339
  });
328
340
  });
341
+
342
+ /**
343
+ * The HTML views section: what an agent writing a live page is told about the
344
+ * frame. Its link rules are pinned against the renderer by core-frontend's
345
+ * `htmlViewsGuide.test.ts`, which reads the same file; what is pinned here is
346
+ * that it is served like every other section and that a distribution may
347
+ * reshape it.
348
+ */
349
+ describe('the HTML views section', () => {
350
+ it('is served on its own, inside the whole guide, titled "HTML views"', async () => {
351
+ const sections = await agentGuideSections(DEFAULT_KB_LAYOUT);
352
+ const html = sections.find((s) => s.id === 'html-views')!;
353
+ expect(html.title).toBe('HTML views');
354
+ expect(html.body).not.toContain('{{');
355
+ expect(await composeAgentGuide(DEFAULT_KB_LAYOUT)).toContain(html.body);
356
+ // After the tool manuals, before the conventions.
357
+ const ids = sections.map((s) => s.id);
358
+ expect(ids.indexOf('html-views')).toBe(ids.indexOf('tool-manuals') + 1);
359
+ });
360
+
361
+ it('describes the frame, the two members core puts on window.bevel, and a fragment that scrolls the page', async () => {
362
+ const text = section(await composeAgentGuide(DEFAULT_KB_LAYOUT), '## HTML views').replace(/\s+/g, ' ');
363
+ expect(text).toContain('**No network.**');
364
+ expect(text).toContain('**Inline scripts and styles only.**');
365
+ expect(text).toContain('**Scripts run as ES modules**');
366
+ expect(text).toContain('**No browser storage.**');
367
+ expect(text).toContain('**No host navigation.**');
368
+ expect(text).toContain('`window.bevel.openNode(href)`');
369
+ expect(text).toContain('`window.bevel.navigate(href)`');
370
+ expect(text).toContain('A distribution may add data members of its own to `window.bevel`');
371
+ expect(text).toContain('**A bare fragment scrolls the page.**');
372
+ // Rendered for the deployment's layout like every other section.
373
+ const docs = section(await composeAgentGuide({ ...DEFAULT_KB_LAYOUT, knowledgeBaseDir: 'Docs' }), '## HTML views');
374
+ expect(docs).toContain('/workspace/main/Docs/Alice.md');
375
+ });
376
+
377
+ it('lets a distribution replace the section or drop it', async () => {
378
+ const replaced = await composeAgentGuide(DEFAULT_KB_LAYOUT, (sections) =>
379
+ sections.map((s) => (s.id === 'html-views' ? { id: s.id, body: '## HTML views\n\nOurs, graph-aware.\n' } : s)),
380
+ );
381
+ expect(section(replaced, '## HTML views').trim()).toBe('Ours, graph-aware.');
382
+ const dropped = await agentGuideSections(DEFAULT_KB_LAYOUT, (sections) => sections.filter((s) => s.id !== 'html-views'));
383
+ expect(dropped.map((s) => s.id)).not.toContain('html-views');
384
+ expect(joinGuideSections(dropped)).not.toContain('## HTML views');
385
+ });
386
+ });
@@ -9,7 +9,8 @@ import { createToolHandlerFactory } from '../../tool-helpers/tool-handler.js';
9
9
  import type { ToolContext } from '../../tool-helpers/tool.contract.js';
10
10
  import { toolDef } from '../../tool-helpers/tool-def.js';
11
11
  import { GET_AGENT_GUIDE_TOOL, registerAgentGuideTool } from '../agent-guide.tools.js';
12
- import type { RenderedGuideSection } from '../agent-guide.js';
12
+ import { DEFAULT_KB_LAYOUT } from '@bevel-software/platform-shared';
13
+ import { agentGuideSections, joinGuideSections, type RenderedGuideSection } from '../agent-guide.js';
13
14
 
14
15
  let server: Server | null = null;
15
16
 
@@ -186,4 +187,21 @@ describe('get_agent_guide', () => {
186
187
  sectionsNow(SECTIONS);
187
188
  expect(await describedAs()).toContain('`introduction` (Knowledge base)');
188
189
  });
190
+
191
+ it('returns the platform\'s HTML views section on its own, and inside the whole guide', async () => {
192
+ const { call, registry, sectionsNow } = await serve();
193
+ const platform = await agentGuideSections(DEFAULT_KB_LAYOUT);
194
+ sectionsNow([...platform]);
195
+ const html = platform.find((s) => s.id === 'html-views')!;
196
+ expect(await call({ section: 'html-views' })).toEqual({
197
+ status: 200,
198
+ body: { guide: html.body, section: 'html-views', title: 'HTML views' },
199
+ });
200
+ const whole = await call();
201
+ expect(whole.body.guide).toBe(joinGuideSections(platform));
202
+ expect(String(whole.body.guide)).toContain('## HTML views');
203
+ // The description lists it, so an agent knows it can ask for it.
204
+ const def = (await registry.listExternal()).find((t) => t.name === GET_AGENT_GUIDE_TOOL)!;
205
+ expect(def.description).toContain('`html-views`');
206
+ });
189
207
  });
@@ -79,6 +79,13 @@ export type AgentGuideReader = () => Promise<string>;
79
79
  /** The computed section: the rules every file tool shares. */
80
80
  export const WORKING_WITH_FILES_SECTION_ID = 'working-with-files';
81
81
 
82
+ /**
83
+ * What to do on a knowledge base nobody has written in yet: the section the
84
+ * `firstRun` note `start_session` answers with points at (see
85
+ * workspace/first-run.ts, which names it by this constant).
86
+ */
87
+ export const NEW_KNOWLEDGE_BASE_SECTION_ID = 'new-knowledge-base';
88
+
82
89
  /**
83
90
  * Core's sections, in reading order. Every id but the shared-rules one names
84
91
  * a file in the package's `agent-guide/` folder.
@@ -91,8 +98,10 @@ export const CORE_SECTION_IDS: readonly string[] = Object.freeze([
91
98
  'access-control',
92
99
  'skills',
93
100
  'tool-manuals',
101
+ 'html-views',
94
102
  'conventions',
95
103
  'finding-things',
104
+ NEW_KNOWLEDGE_BASE_SECTION_ID,
96
105
  ]);
97
106
 
98
107
  /**
@@ -1,6 +1,7 @@
1
1
  export {
2
2
  AGENT_GUIDE_FILE,
3
3
  CORE_SECTION_IDS,
4
+ NEW_KNOWLEDGE_BASE_SECTION_ID,
4
5
  PLATFORM_GUIDE_SEPARATOR,
5
6
  WORKING_WITH_FILES_SECTION_ID,
6
7
  agentGuideSections,