@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
@@ -21,7 +21,8 @@ import type { IAccessControl } from '../../access/access-control.interface.js';
21
21
  import { createMcpRoutes } from '../../mcp/mcp.routes.js';
22
22
  import { McpService } from '../../mcp/mcp.service.js';
23
23
  import { testKbContext } from '../../../__tests__/kb-context.js';
24
- import { sharedFileRules, sharedFileRulesSection, sharedRulesPointer } from '../../agent-instructions/shared-file-rules.js';
24
+ import { sharedFileRules, sharedFileRulesSection } from '../../agent-instructions/shared-file-rules.js';
25
+ import { GUIDE_FIRST_SENTENCE } from '../../tool-registry/guide-first.js';
25
26
 
26
27
  /**
27
28
  * Who decodes escape sequences in written content a second time — settled on
@@ -386,9 +387,9 @@ describe('what the write tools tell an agent about escape sequences', () => {
386
387
  .filter(([, d]) => d.includes('decode escape sequences in arguments before sending') || d.includes('some clients decode them in arguments'))
387
388
  .map(([n]) => n);
388
389
  expect(carrying).toEqual([]);
389
- // Each of the three still points at where the warning is.
390
+ // Each of the three still opens by sending the agent to the guide, where the warning is.
390
391
  for (const name of ['write_file', 'write_files', 'edit_file']) {
391
- expect(served[name], name).toContain(sharedRulesPointer(testKbContext().layout).trim());
392
+ expect(served[name]!.startsWith(GUIDE_FIRST_SENTENCE), name).toBe(true);
392
393
  }
393
394
  });
394
395
  });
@@ -0,0 +1,234 @@
1
+ import { mkdir, mkdtemp, rm, stat, symlink, writeFile } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { DEFAULT_KB_LAYOUT } from '@bevel-software/platform-shared';
6
+ import { defaultKbTemplateDir } from '../../../assets.js';
7
+ import { agentGuideSections } from '../../agent-guide/index.js';
8
+ import { NodeFs } from '../../kb-fs/node-fs.js';
9
+ import {
10
+ FIRST_RUN_SECTION_ID,
11
+ FOLDER_BUDGET,
12
+ STARTER_GUIDE_FILE,
13
+ firstRunNote,
14
+ knowledgeFolderIsNew,
15
+ type MayRead,
16
+ } from '../first-run.js';
17
+
18
+ /**
19
+ * What makes a knowledge base "new" for the `firstRun` note: nothing in its
20
+ * knowledge folder but the starter guide the template seeds. Pinned here on a
21
+ * real checkout; the route that returns the note is exercised in
22
+ * workspace.tools.test.ts.
23
+ */
24
+ describe('knowledgeFolderIsNew', () => {
25
+ const disk = new NodeFs();
26
+ const KNOWLEDGE = 'KnowledgeBase';
27
+ /** The checkout, and its knowledge folder. */
28
+ let repo = '';
29
+ let dir = '';
30
+ const isNew = (starter?: ReadonlyMap<string, string>, mayRead?: MayRead) =>
31
+ knowledgeFolderIsNew(disk, repo, KNOWLEDGE, starter, mayRead);
32
+ const everyone: MayRead = async (rels) => new Map(rels.map((rel) => [rel, true]));
33
+
34
+ beforeEach(async () => {
35
+ repo = await mkdtemp(join(tmpdir(), 'bevel-first-run-unit-'));
36
+ dir = join(repo, KNOWLEDGE);
37
+ await mkdir(dir);
38
+ await writeFile(join(dir, STARTER_GUIDE_FILE), '# How to get started\n');
39
+ });
40
+
41
+ afterEach(async () => {
42
+ await rm(repo, { recursive: true, force: true });
43
+ });
44
+
45
+ it('is new with only the starter guide', async () => {
46
+ expect(await isNew()).toBe(true);
47
+ });
48
+
49
+ it('is new with nothing at all: a starter guide someone deleted leaves an empty knowledge base', async () => {
50
+ await rm(join(dir, STARTER_GUIDE_FILE));
51
+ expect(await isNew()).toBe(true);
52
+ });
53
+
54
+ it('passes over empty folders, their placeholders, dot-files and access rules', async () => {
55
+ await mkdir(join(dir, 'Customers', 'Archive'), { recursive: true });
56
+ await writeFile(join(dir, 'Customers', '.gitkeep'), '');
57
+ await writeFile(join(dir, 'Customers', 'access.md'), '# Access\n');
58
+ await writeFile(join(dir, '.DS_Store'), '');
59
+ expect(await isNew()).toBe(true);
60
+ });
61
+
62
+ it('is not new once a page sits beside the starter guide', async () => {
63
+ await writeFile(join(dir, 'Glossary.md'), '# Glossary\n');
64
+ expect(await isNew()).toBe(false);
65
+ });
66
+
67
+ it('is not new once a page sits in a folder, of any kind', async () => {
68
+ await mkdir(join(dir, 'Products'), { recursive: true });
69
+ await writeFile(join(dir, 'Products', 'Pricing.pdf'), 'bytes');
70
+ expect(await isNew()).toBe(false);
71
+ });
72
+
73
+ it('counts a file named like the starter guide below the top as a page', async () => {
74
+ await mkdir(join(dir, 'Team'), { recursive: true });
75
+ await writeFile(join(dir, 'Team', STARTER_GUIDE_FILE), '# Our own onboarding\n');
76
+ expect(await isNew()).toBe(false);
77
+ });
78
+
79
+ it('is not new when the folder is not there: a shape the template never made is not greeted', async () => {
80
+ expect(await knowledgeFolderIsNew(disk, repo, 'missing')).toBe(false);
81
+ });
82
+
83
+ it('passes over a starter pack page that still holds what the pack wrote, line endings aside', async () => {
84
+ await mkdir(join(dir, 'Team'), { recursive: true });
85
+ await writeFile(join(dir, 'About us.md'), '# About us\r\n\r\nAsk your agent: _Draft this_\r\n');
86
+ await writeFile(join(dir, 'Team', 'Glossary.md'), '# Glossary\n');
87
+ const starter = new Map([
88
+ ['About us.md', '# About us\n\nAsk your agent: _Draft this_\n'],
89
+ ['Team/Glossary.md', '# Glossary\n'],
90
+ ]);
91
+ expect(await isNew(starter)).toBe(true);
92
+ // The same pages count without the pack to recognise them by.
93
+ expect(await isNew()).toBe(false);
94
+ });
95
+
96
+ it('is not new once someone fills a starter page in', async () => {
97
+ await writeFile(join(dir, 'About us.md'), '# About us\n\nWe make bicycles.\n');
98
+ expect(await isNew(new Map([['About us.md', '# About us\n']]))).toBe(false);
99
+ });
100
+
101
+ it('sees what the explorer sees: a page a `.bevelignore` hides, in the folder or at the repository root, is not there', async () => {
102
+ await mkdir(join(dir, 'Drafts'), { recursive: true });
103
+ await writeFile(join(dir, 'Drafts', 'Plan.md'), '# Plan\n');
104
+ await writeFile(join(dir, '.bevelignore'), 'Drafts/\n');
105
+ expect(await isNew()).toBe(true);
106
+ // The rules above the folder apply on the way down as well.
107
+ await rm(join(dir, '.bevelignore'));
108
+ expect(await isNew()).toBe(false);
109
+ await writeFile(join(repo, '.bevelignore'), 'Drafts/\n');
110
+ expect(await isNew()).toBe(true);
111
+ // A knowledge folder the root's rules hide is one the explorer never enters: not greeted.
112
+ await writeFile(join(repo, '.bevelignore'), `${KNOWLEDGE}/\n`);
113
+ expect(await isNew()).toBe(false);
114
+ });
115
+
116
+ it("answers for the caller when asked to: a page they may not read does not make the folder old for them", async () => {
117
+ await mkdir(join(dir, 'Leadership'), { recursive: true });
118
+ await writeFile(join(dir, 'Leadership', 'Plan.md'), '# Plan\n');
119
+ const seen: string[][] = [];
120
+ const nobody: MayRead = async (rels) => {
121
+ seen.push(rels);
122
+ return new Map(rels.map((rel) => [rel, false]));
123
+ };
124
+ expect(await isNew(undefined, nobody)).toBe(true);
125
+ // Asked about the page, and only the page: folders are entered, not judged.
126
+ expect(seen).toEqual([['Leadership/Plan.md']]);
127
+
128
+ expect(await isNew(undefined, everyone)).toBe(false);
129
+ // Without anyone to ask, a page is a page.
130
+ expect(await isNew()).toBe(false);
131
+ });
132
+
133
+ it("enters every folder, as the agent's listing shows every folder: a page a deeper rule opens counts", async () => {
134
+ await mkdir(join(dir, 'Leadership', 'Shared'), { recursive: true });
135
+ await writeFile(join(dir, 'Leadership', 'Plan.md'), '# Plan\n');
136
+ await writeFile(join(dir, 'Leadership', 'Shared', 'Note.md'), '# Note\n');
137
+ const asked: string[][] = [];
138
+ const sharedOnly: MayRead = async (rels) => {
139
+ asked.push(rels);
140
+ return new Map(rels.map((rel) => [rel, rel === 'Leadership/Shared/Note.md']));
141
+ };
142
+ expect(await isNew(undefined, sharedOnly)).toBe(false);
143
+ // Each folder's pages in turn; the readable one ends the walk.
144
+ expect(asked).toEqual([['Leadership/Plan.md'], ['Leadership/Shared/Note.md']]);
145
+ });
146
+
147
+ it('counts nothing the caller may not read, however much of it there is', async () => {
148
+ const many = 1001;
149
+ await Promise.all(Array.from({ length: many }, (_, i) => writeFile(join(dir, `Secret-${i}.md`), '# Secret\n')));
150
+ const asked: number[] = [];
151
+ const nobody: MayRead = async (rels) => {
152
+ asked.push(rels.length);
153
+ return new Map(rels.map((rel) => [rel, false]));
154
+ };
155
+ expect(await isNew(undefined, nobody)).toBe(true);
156
+ // Judged in chunks, every one of them.
157
+ expect(asked.reduce((n, k) => n + k, 0)).toBe(many);
158
+ expect(Math.max(...asked)).toBeLessThanOrEqual(200);
159
+ // One the caller may read, anywhere among them, and the folder is old.
160
+ const justOne: MayRead = async (rels) => new Map(rels.map((rel) => [rel, rel === `Secret-${many - 1}.md`]));
161
+ expect(await isNew(undefined, justOne)).toBe(false);
162
+ });
163
+
164
+ it('stops at its folder budget: that many folders and no page is not a new knowledge base', async () => {
165
+ // The knowledge folder itself counts, so this many below it is one over.
166
+ await Promise.all(Array.from({ length: FOLDER_BUDGET }, (_, i) => mkdir(join(dir, `Team-${i}`), { recursive: true })));
167
+ expect(await isNew()).toBe(false);
168
+ // Nobody is asked about a folder: with no page in sight the budget alone answers.
169
+ const asked: string[][] = [];
170
+ const nobody: MayRead = async (rels) => {
171
+ asked.push(rels);
172
+ return new Map(rels.map((rel) => [rel, false]));
173
+ };
174
+ expect(await isNew(undefined, nobody)).toBe(false);
175
+ expect(asked).toEqual([]);
176
+ // One fewer, and the walk lists them all.
177
+ await rm(join(dir, 'Team-0'), { recursive: true });
178
+ expect(await isNew()).toBe(true);
179
+ });
180
+
181
+ it('passes a link over by kind: not a page, never read through, never asked about', async () => {
182
+ try {
183
+ await symlink(join(tmpdir(), 'elsewhere.md'), join(dir, 'Alias.md'));
184
+ } catch {
185
+ return; // no symlinks on this machine: nothing to pass over
186
+ }
187
+ const asked: string[][] = [];
188
+ const everyoneAsked: MayRead = async (rels) => {
189
+ asked.push(rels);
190
+ return new Map(rels.map((rel) => [rel, true]));
191
+ };
192
+ expect(await isNew(undefined, everyoneAsked)).toBe(true);
193
+ expect(asked).toEqual([]);
194
+ expect(await isNew()).toBe(true);
195
+ });
196
+ });
197
+
198
+ describe('the firstRun note', () => {
199
+ it('names the starter guide the template really seeds', async () => {
200
+ const seeded = await stat(join(defaultKbTemplateDir(), 'KnowledgeBase', STARTER_GUIDE_FILE));
201
+ expect(seeded.isFile()).toBe(true);
202
+ });
203
+
204
+ it('points at a section the guide has, which says what to do', async () => {
205
+ const sections = await agentGuideSections(DEFAULT_KB_LAYOUT, undefined, { kbDirName: 'kb-checkout' });
206
+ const section = sections.find((s) => s.id === FIRST_RUN_SECTION_ID);
207
+ expect(section, `the guide has no "${FIRST_RUN_SECTION_ID}" section`).toBeDefined();
208
+ expect(section!.body).toContain('`firstRun`');
209
+ // The folder spelled as the note spells it: the checkout-prefixed form the file tools report.
210
+ const folder = `kb-checkout/${DEFAULT_KB_LAYOUT.knowledgeBaseDir}`;
211
+ expect(section!.body).toContain(`\`${folder}/\``);
212
+ expect(firstRunNote(folder)).toContain(`\`${folder}/\``);
213
+ expect(section!.body).toMatch(/once per conversation/i);
214
+ });
215
+
216
+ it('says what to offer and that the person\'s own request comes first', () => {
217
+ const note = firstRunNote('knowledge-base/KnowledgeBase');
218
+ expect(note).toContain('`knowledge-base/KnowledgeBase/`');
219
+ // True whether the starter guide is still there or someone deleted it.
220
+ expect(note).toContain('has no pages yet');
221
+ expect(note).toMatch(/offer to draft/);
222
+ expect(note).toMatch(/answer that first/);
223
+ expect(note).toContain(`\`${FIRST_RUN_SECTION_ID}\``);
224
+ });
225
+
226
+ it("after a starter pack, names the team's pages and says they are placeholders", () => {
227
+ const note = firstRunNote('knowledge-base/KnowledgeBase', { name: 'Sales', suggestedPages: ['About us', 'Customers'] });
228
+ expect(note).toContain('the Sales starter pages');
229
+ expect(note).toMatch(/placeholders/);
230
+ expect(note).toContain('offer to draft its first pages (About us, Customers)');
231
+ expect(note).toMatch(/answer that first/);
232
+ expect(note).toContain(`\`${FIRST_RUN_SECTION_ID}\``);
233
+ });
234
+ });
@@ -189,6 +189,7 @@ const allowAll = {
189
189
  canWriteBatch: async (_w: string, _u: string, paths: string[]) => new Map(paths.map((p) => [p, true])),
190
190
  canWriteBatchAtRef: async (_w: string, _r: string, _u: string, paths: string[]) => new Map(paths.map((p) => [p, true])),
191
191
  canDownload: async () => true,
192
+ canDownloadBatch: async (_w: string, _u: string, paths: string[]) => new Map(paths.map((p) => [p, true])),
192
193
  canOwner: async () => true,
193
194
  eligibleWritersAtRef: async () => [],
194
195
  } as unknown as IAccessControl;
@@ -584,7 +585,7 @@ describe('WorkspaceService refuses the git folder on its own', () => {
584
585
  ['moveEntry (source)', (p) => service.moveEntry(WS, p, `${KB}/Notes/moved`)],
585
586
  ['moveEntry (destination)', (p) => service.moveEntry(WS, `${KB}/Notes/a.md`, p)],
586
587
  ['createDirectory', (p) => service.createDirectory(WS, `${p}/new`)],
587
- ['createFolderZip', (p) => service.createFolderZip(WS, p.replace(/\/config$/, ''))],
588
+ ['createFolderZip', (p) => service.createFolderZip(WS, p.replace(/\/config$/, ''), async (paths) => new Set(paths))],
588
589
  ['unzipFile (archive)', (p) => service.unzipFile(WS, `${p}.zip`)],
589
590
  ['unzipFile (destination)', (p) => service.unzipFile(WS, `${KB}/archive.zip`, p)],
590
591
  ];
@@ -649,7 +650,9 @@ describe('WorkspaceService refuses the git folder on its own', () => {
649
650
  await mkdir(join(workspaceDir, KB, 'Notes', '.git.'), { recursive: true });
650
651
  await writeFile(join(workspaceDir, KB, 'Notes', '.git.', 'HEAD'), 'ref\n');
651
652
 
652
- const names = new AdmZip(await service.createFolderZip(WS, `${KB}/Notes`)).getEntries().map((e) => e.entryName);
653
+ const names = new AdmZip(await service.createFolderZip(WS, `${KB}/Notes`, async (paths) => new Set(paths)))
654
+ .getEntries()
655
+ .map((e) => e.entryName);
653
656
  expect(names).toEqual(['Notes/a.md']);
654
657
  });
655
658
 
@@ -0,0 +1,353 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import {
3
+ htmlLinksAffectedByMove,
4
+ resolveMdLink,
5
+ rewriteMdLinks,
6
+ scanMarkdownHtmlLinks,
7
+ scanMarkdownLinks,
8
+ } from '@bevel-software/platform-shared';
9
+
10
+ /**
11
+ * The link grammar `move_file` rewrites with (platform-shared `md-links`):
12
+ * every link form, kept in its form, with code and every other byte untouched.
13
+ */
14
+
15
+ const KB = 'knowledge-base';
16
+
17
+ /** A move of `src` to `dest`, as the plan hands it to the rewriter. */
18
+ function moveOf(src: string, dest: string) {
19
+ return (p: string): string | null =>
20
+ p === src ? dest : p.startsWith(`${src}/`) ? dest + p.slice(src.length) : null;
21
+ }
22
+
23
+ /** Rewrite `text` sitting at `oldPath` (moving to `newPath`) for a move of `src` to `dest`. */
24
+ function rewrite(text: string, oldPath: string, src: string, dest: string, newPath = oldPath) {
25
+ return rewriteMdLinks(text, { oldPath, newPath, mapPath: moveOf(src, dest), kbDirName: KB, branch: 'main' });
26
+ }
27
+
28
+ const OUTSIDE = `${KB}/Pages/Index.md`;
29
+ const PLAN = `${KB}/Old/Plan.md`;
30
+ const NEW_PLAN = `${KB}/New/Deep/Plan.md`;
31
+
32
+ describe('md-links — the forms a link to a moved file is written in', () => {
33
+ it('a relative link keeps its anchor and title', () => {
34
+ const { text, edits } = rewrite('See [Plan](../Old/Plan.md#risks "Risks").\n', OUTSIDE, PLAN, NEW_PLAN);
35
+ expect(text).toBe('See [Plan](../New/Deep/Plan.md#risks "Risks").\n');
36
+ expect(edits).toEqual([{ from: '../Old/Plan.md#risks', to: '../New/Deep/Plan.md#risks' }]);
37
+ });
38
+
39
+ it('a `./` relative link keeps its `./`', () => {
40
+ const { text } = rewrite('[a](./Old/Plan.md)\n', `${KB}/Index.md`, PLAN, `${KB}/Other/Plan.md`);
41
+ expect(text).toBe('[a](./Other/Plan.md)\n');
42
+ });
43
+
44
+ it('a root-anchored /knowledge-base/ link stays root-anchored', () => {
45
+ const { text } = rewrite(`[p](/${PLAN})\n`, OUTSIDE, PLAN, NEW_PLAN);
46
+ expect(text).toBe(`[p](/${NEW_PLAN})\n`);
47
+ });
48
+
49
+ it('an app URL /workspace/<branch>/… keeps its branch segment, and one naming another branch is left', () => {
50
+ const { text } = rewrite(
51
+ `[p](/workspace/main/${PLAN}#x) [q](/workspace/other/${PLAN})\n`,
52
+ OUTSIDE,
53
+ PLAN,
54
+ NEW_PLAN,
55
+ );
56
+ expect(text).toBe(`[p](/workspace/main/${NEW_PLAN}#x) [q](/workspace/other/${PLAN})\n`);
57
+ });
58
+
59
+ it('an angle-bracket destination stays in angle brackets, spaces unencoded', () => {
60
+ const { text } = rewrite('[p](<../Old Folder/My Plan.md> "t")\n', OUTSIDE, `${KB}/Old Folder`, `${KB}/New Folder`);
61
+ expect(text).toBe('[p](<../New Folder/My Plan.md> "t")\n');
62
+ });
63
+
64
+ it('a percent-encoded destination stays encoded', () => {
65
+ const { text } = rewrite('[p](../Old%20Folder/My%20Plan.md)\n', OUTSIDE, `${KB}/Old Folder`, `${KB}/New Folder`);
66
+ expect(text).toBe('[p](../New%20Folder/My%20Plan.md)\n');
67
+ });
68
+
69
+ it('a bare destination gaining a space has the space encoded, so the link still parses', () => {
70
+ const { text } = rewrite('[p](../Old/Plan.md)\n', OUTSIDE, PLAN, `${KB}/New Folder/Plan.md`);
71
+ expect(text).toBe('[p](../New%20Folder/Plan.md)\n');
72
+ });
73
+
74
+ it('an image to any file type', () => {
75
+ const { text } = rewrite('![shot](../Old/shot.png "Shot")\n', OUTSIDE, `${KB}/Old`, `${KB}/Assets`);
76
+ expect(text).toBe('![shot](../Assets/shot.png "Shot")\n');
77
+ });
78
+
79
+ it('a reference definition, angle and bare, with its title', () => {
80
+ const { text } = rewrite(
81
+ '[x][plan]\n\n[plan]: ../Old/Plan.md "Plan"\n[pdf]: <../Old/Spec v2.pdf>\n',
82
+ OUTSIDE,
83
+ `${KB}/Old`,
84
+ `${KB}/Archive`,
85
+ );
86
+ expect(text).toBe('[x][plan]\n\n[plan]: ../Archive/Plan.md "Plan"\n[pdf]: <../Archive/Spec v2.pdf>\n');
87
+ });
88
+
89
+ it('a link to a moved FOLDER, trailing slash kept', () => {
90
+ const { text } = rewrite('[all](../Old/) [one](../Old)\n', OUTSIDE, `${KB}/Old`, `${KB}/Archive/Old`);
91
+ expect(text).toBe('[all](../Archive/Old/) [one](../Archive/Old)\n');
92
+ });
93
+
94
+ it('a link wrapping an image: both destinations', () => {
95
+ const { text } = rewrite('[![a](../Old/a.png)](../Old/Plan.md)\n', OUTSIDE, `${KB}/Old`, `${KB}/New`);
96
+ expect(text).toBe('[![a](../New/a.png)](../New/Plan.md)\n');
97
+ });
98
+
99
+ it('a destination with balanced parentheses', () => {
100
+ const { text } = rewrite('[p](../Old/Plan(v2).md)\n', OUTSIDE, `${KB}/Old`, `${KB}/New`);
101
+ expect(text).toBe('[p](../New/Plan(v2).md)\n');
102
+ });
103
+ });
104
+
105
+ describe('md-links — what a move never changes', () => {
106
+ it('fenced code and inline code are untouched', () => {
107
+ const input = [
108
+ 'Real [p](../Old/Plan.md).',
109
+ '',
110
+ '```md',
111
+ '[p](../Old/Plan.md)',
112
+ '```',
113
+ '',
114
+ '~~~~',
115
+ '[p](../Old/Plan.md)',
116
+ '```',
117
+ '~~~~',
118
+ '',
119
+ '- item',
120
+ ' ```',
121
+ ' [p](../Old/Plan.md)',
122
+ ' ```',
123
+ '',
124
+ 'Inline `[p](../Old/Plan.md)` and ``a ` [p](../Old/Plan.md) ``.',
125
+ '',
126
+ ].join('\n');
127
+ const { text, edits } = rewrite(input, OUTSIDE, PLAN, NEW_PLAN);
128
+ expect(edits).toHaveLength(1);
129
+ expect(text).toBe(input.replace('Real [p](../Old/Plan.md).', 'Real [p](../New/Deep/Plan.md).'));
130
+ });
131
+
132
+ it('indented code blocks are untouched, at the margin and inside a list item', () => {
133
+ const input = [
134
+ 'Real [p](../Old/Plan.md).',
135
+ '',
136
+ ' [p](../Old/Plan.md)',
137
+ '',
138
+ ' still code [p](../Old/Plan.md)',
139
+ '',
140
+ '- item',
141
+ '',
142
+ ' list paragraph [p](../Old/Plan.md)',
143
+ '',
144
+ ' [p](../Old/Plan.md)',
145
+ '',
146
+ 'para',
147
+ ' lazy [p](../Old/Plan.md)',
148
+ '',
149
+ ].join('\n');
150
+ const { text, edits } = rewrite(input, OUTSIDE, PLAN, NEW_PLAN);
151
+ expect(edits).toHaveLength(3);
152
+ const changed = text.split('\n').filter((l, i) => l !== input.split('\n')[i]);
153
+ expect(changed).toEqual([
154
+ 'Real [p](../New/Deep/Plan.md).',
155
+ ' list paragraph [p](../New/Deep/Plan.md)',
156
+ ' lazy [p](../New/Deep/Plan.md)',
157
+ ]);
158
+ });
159
+
160
+ it('id-links, external URLs, same-page anchors and escaped brackets are left alone', () => {
161
+ const input = '[a](project-hexis) [b](plan#risks) [c](https://x.y/Old/Plan.md) [d](#risks) \\[e](../Old/Plan.md)\n';
162
+ expect(rewrite(input, OUTSIDE, PLAN, NEW_PLAN).text).toBe(input);
163
+ });
164
+
165
+ it('frontmatter: the nodeType link is rewritten and every other line stays byte-identical (CRLF too)', () => {
166
+ const fm = [
167
+ '---',
168
+ 'nodeType: "[Task](../NodeTypes/Task.md)"',
169
+ 'id: task-a',
170
+ 'tags: [a, b] ',
171
+ 'read: "[[Sales]]"',
172
+ '---',
173
+ '',
174
+ '# Name',
175
+ 'A task linking [Task](../NodeTypes/Task.md).',
176
+ '',
177
+ ].join('\r\n');
178
+ const { text } = rewrite(fm, `${KB}/Tasks/A.md`, `${KB}/Tasks/A.md`, `${KB}/Tasks/Deep/A.md`, `${KB}/Tasks/Deep/A.md`);
179
+ expect(text).toBe(fm.split('../NodeTypes/Task.md').join('../../NodeTypes/Task.md'));
180
+ const before = fm.split('\r\n');
181
+ const after = text.split('\r\n');
182
+ expect(after.filter((l, i) => l !== before[i])).toEqual([
183
+ 'nodeType: "[Task](../../NodeTypes/Task.md)"',
184
+ 'A task linking [Task](../../NodeTypes/Task.md).',
185
+ ]);
186
+ });
187
+
188
+ it('a file whose links all still resolve comes back unchanged, as the same string', () => {
189
+ const input = `[p](/${KB}/Elsewhere.md) [q](Sibling.md)\n`;
190
+ const out = rewrite(input, `${KB}/A/B.md`, `${KB}/Unrelated.md`, `${KB}/Other.md`);
191
+ expect(out.edits).toEqual([]);
192
+ expect(out.text).toBe(input);
193
+ });
194
+ });
195
+
196
+ describe('md-links — the four placements of a link and a moved file', () => {
197
+ const src = `${KB}/Projects/A`;
198
+ const dest = `${KB}/Topics/Deep/A`;
199
+
200
+ it('inside the moved set, outbound: a link out of a moved file follows its target', () => {
201
+ const { text } = rewrite('[t](../../NodeTypes/Task.md)\n', `${src}/One.md`, src, dest, `${dest}/One.md`);
202
+ expect(text).toBe('[t](../../../NodeTypes/Task.md)\n');
203
+ });
204
+
205
+ it('between two moved files: the relative link already holds, untouched', () => {
206
+ const out = rewrite('[two](Two.md) [up](../A/Two.md)\n', `${src}/One.md`, src, dest, `${dest}/One.md`);
207
+ expect(out.edits).toEqual([]);
208
+ });
209
+
210
+ it('between two moved files, root-anchored: rewritten to the new place', () => {
211
+ const { text } = rewrite(`[two](/${src}/Two.md)\n`, `${src}/One.md`, src, dest, `${dest}/One.md`);
212
+ expect(text).toBe(`[two](/${dest}/Two.md)\n`);
213
+ });
214
+
215
+ it('inbound from outside: points at the new place', () => {
216
+ const { text } = rewrite('[one](../Projects/A/One.md)\n', `${KB}/Pages/Index.md`, src, dest);
217
+ expect(text).toBe('[one](../Topics/Deep/A/One.md)\n');
218
+ });
219
+ });
220
+
221
+ describe('md-links — scanning', () => {
222
+ it('finds every destination with its offsets and kind', () => {
223
+ const text = '---\nnodeType: "[T](../T.md)"\n---\n[a](a.md) ![b](b.png)\n\n[c]: c.md\n[^1]: not a definition\n';
224
+ const spans = scanMarkdownLinks(text);
225
+ expect(spans.map((s) => [s.kind, s.destination, s.inFrontmatter])).toEqual([
226
+ ['link', '../T.md', true],
227
+ ['link', 'a.md', false],
228
+ ['image', 'b.png', false],
229
+ ['definition', 'c.md', false],
230
+ ]);
231
+ for (const s of spans) expect(text.slice(s.start, s.end)).toBe(s.destination);
232
+ });
233
+
234
+ it('resolves the forms the app resolves', () => {
235
+ const base = `${KB}/A/B.md`;
236
+ expect(resolveMdLink('../C.md#x', { basePath: base, kbDirName: KB })).toEqual({ form: 'relative', branch: null, path: `${KB}/C.md`, hash: '#x' });
237
+ expect(resolveMdLink(`/${KB}/C.md`, { basePath: base, kbDirName: KB })?.path).toBe(`${KB}/C.md`);
238
+ expect(resolveMdLink(`/workspace/main/${KB}/My%20C.md`, { basePath: base, kbDirName: KB })).toEqual({ form: 'workspace', branch: 'main', path: `${KB}/My C.md`, hash: '' });
239
+ expect(resolveMdLink('project-hexis', { basePath: base, kbDirName: KB })).toBeNull();
240
+ expect(resolveMdLink('mailto:a@b', { basePath: base, kbDirName: KB })).toBeNull();
241
+ });
242
+
243
+ it('HTML pages: the links a move would break are reported', () => {
244
+ const html = '<a href="../Old/Plan.md">p</a><img src=\'x.png\'><a href="https://x.y">x</a>';
245
+ expect(htmlLinksAffectedByMove(html, { oldPath: OUTSIDE, newPath: OUTSIDE, mapPath: moveOf(PLAN, NEW_PLAN), kbDirName: KB, branch: 'main' }))
246
+ .toEqual(['../Old/Plan.md']);
247
+ });
248
+
249
+ it('HTML pages: unquoted attribute values are reported too', () => {
250
+ const html = '<a href=../Old/Plan.md>p</a> <a class=x href = ../Old/Plan.md#r>q</a>';
251
+ expect(htmlLinksAffectedByMove(html, { oldPath: OUTSIDE, newPath: OUTSIDE, mapPath: moveOf(PLAN, NEW_PLAN), kbDirName: KB, branch: 'main' }))
252
+ .toEqual(['../Old/Plan.md', '../Old/Plan.md#r']);
253
+ });
254
+
255
+ it('a markdown page: only the raw HTML tags that are live — not in code, not escaped, not a bare href= in prose', () => {
256
+ const page =
257
+ '---\nnodeType: "[T](../NodeTypes/T.md)"\nsrc: in-frontmatter.md\n---\n\n' +
258
+ 'Prose with `<a href="in-span.md">` and an escaped \\<a href="in-escape.md"> tag, and src = in-prose.md.\n\n' +
259
+ '```html\n<a href="in-fence.md">f</a>\n```\n\n' +
260
+ ' <img src="in-indent.md">\n\n' +
261
+ '> [def]: in-def.md\n\nLive <a href="live.md">x</a> and <img src=\'pic.png\' alt="p"/> and <a href=bare.md>b</a>\n' +
262
+ // A `>` inside a quoted attribute does not end the tag; a backslash
263
+ // inside a raw tag is not an escape, so the value keeps it.
264
+ '<a title="a > b" href="quoted.md">q</a> <a href="Plan\\_v2.md">e</a>\n';
265
+ const live = ['live.md', 'pic.png', 'bare.md', 'quoted.md', 'Plan\\_v2.md'];
266
+ expect(scanMarkdownHtmlLinks(page).map((t) => t.destination)).toEqual(live);
267
+ // Which attribute each came from travels with it: a `src` is a picture.
268
+ expect(scanMarkdownHtmlLinks(page).map((t) => t.image)).toEqual([false, true, false, false, false]);
269
+ // Escaped backticks are literal text, not a code span around the tag;
270
+ // `data-href` is not a link; `href=` inside another attribute's value is a value.
271
+ const found = (text: string) => scanMarkdownHtmlLinks(text).map((t) => t.destination);
272
+ expect(found('a \\` b <a href="between.md">x</a> c \\` d\n')).toEqual(['between.md']);
273
+ expect(found('<div data-href="not.md" title="href=nor.md"><a href="yes.md">x</a></div>\n')).toEqual(['yes.md']);
274
+ // A tag inside an HTML comment is not rendered, so it is not a link.
275
+ expect(found('<!-- <a href="hidden.md">x</a> -->\n<a href="shown.md">y</a>\n')).toEqual(['shown.md']);
276
+ expect(htmlLinksAffectedByMove(page, { oldPath: OUTSIDE, newPath: `${KB}/Moved/Index.md`, mapPath: () => null, kbDirName: KB, branch: 'main' }, scanMarkdownHtmlLinks(page)))
277
+ .toEqual(live);
278
+ });
279
+ });
280
+
281
+ describe('md-links — container and frontmatter edges', () => {
282
+ it('a fence-looking line four columns in, inside a paragraph, opens no fence', () => {
283
+ const input = ['para', ' ~~~', ' [p](../Old/Plan.md)', ' ~~~', ''].join('\n');
284
+ expect(rewrite(input, OUTSIDE, PLAN, NEW_PLAN).text).toBe(input.replace('../Old/Plan.md', '../New/Deep/Plan.md'));
285
+ // With backticks the two runs are one inline code span: code, left alone.
286
+ const ticks = input.split('~~~').join('```');
287
+ expect(rewrite(ticks, OUTSIDE, PLAN, NEW_PLAN).text).toBe(ticks);
288
+ });
289
+
290
+ it('a fence-looking line four columns in does not close a fence', () => {
291
+ const input = ['```', ' ```', '[p](../Old/Plan.md)', '```', '[q](../Old/Plan.md)', ''].join('\n');
292
+ expect(rewrite(input, OUTSIDE, PLAN, NEW_PLAN).text).toBe(['```', ' ```', '[p](../Old/Plan.md)', '```', '[q](../New/Deep/Plan.md)', ''].join('\n'));
293
+ });
294
+
295
+ it('a fence inside a list item still opens and closes at the item’s indent', () => {
296
+ const input = ['- item', '', ' ```', ' [p](../Old/Plan.md)', ' ```', '', '[q](../Old/Plan.md)', ''].join('\n');
297
+ expect(rewrite(input, OUTSIDE, PLAN, NEW_PLAN).text).toBe(input.replace('[q](../Old/Plan.md)', '[q](../New/Deep/Plan.md)'));
298
+ });
299
+
300
+ it('a reference definition inside a blockquote is rewritten', () => {
301
+ const input = '> [ref]: ../Old/Plan.md "t"\n> > [deep]: <../Old/Plan.md>\n';
302
+ expect(rewrite(input, OUTSIDE, PLAN, NEW_PLAN).text).toBe('> [ref]: ../New/Deep/Plan.md "t"\n> > [deep]: <../New/Deep/Plan.md>\n');
303
+ });
304
+
305
+ it('an indented code block inside a blockquote is untouched, and the quoted prose beside it is rewritten', () => {
306
+ const input = '> intro\n>\n> [p](../Old/Plan.md)\n>\n> [q](../Old/Plan.md)\n';
307
+ expect(rewrite(input, OUTSIDE, PLAN, NEW_PLAN).text).toBe(
308
+ '> intro\n>\n> [p](../Old/Plan.md)\n>\n> [q](../New/Deep/Plan.md)\n',
309
+ );
310
+ });
311
+
312
+ it('frontmatter: only a value that is one whole link is rewritten; a link in a prose value is left', () => {
313
+ const fm = [
314
+ '---',
315
+ 'nodeType: "[Task](../Old/Plan.md)"',
316
+ "parent: '[P](../Old/Plan.md)'",
317
+ // Not valid YAML (a flow sequence), so the panel shows no link; still a
318
+ // whole-value link to a line-based reader such as the graph parser.
319
+ 'owner: [P](../Old/Plan.md)',
320
+ 'description: "See [P](../Old/Plan.md) for context"',
321
+ 'commented: "[P](../Old/Plan.md)" # YAML drops this [c](../Old/Plan.md)',
322
+ "bare: '[P](../Old/Plan.md)' # so does this",
323
+ 'inside: "[P](../Old/Plan.md) # not a comment"',
324
+ 'two: "[a](../Old/Plan.md) [b](../Old/Plan.md)"',
325
+ '---',
326
+ '',
327
+ ].join('\n');
328
+ const { text } = rewrite(fm, OUTSIDE, PLAN, NEW_PLAN);
329
+ expect(text.split('\n')).toEqual([
330
+ '---',
331
+ 'nodeType: "[Task](../New/Deep/Plan.md)"',
332
+ "parent: '[P](../New/Deep/Plan.md)'",
333
+ 'owner: [P](../New/Deep/Plan.md)',
334
+ 'description: "See [P](../Old/Plan.md) for context"',
335
+ 'commented: "[P](../New/Deep/Plan.md)" # YAML drops this [c](../Old/Plan.md)',
336
+ "bare: '[P](../New/Deep/Plan.md)' # so does this",
337
+ 'inside: "[P](../Old/Plan.md) # not a comment"',
338
+ 'two: "[a](../Old/Plan.md) [b](../Old/Plan.md)"',
339
+ '---',
340
+ '',
341
+ ]);
342
+ });
343
+
344
+ it('an image under another branch’s app URL is rewritten — the app serves it from this branch — while a link there is left', () => {
345
+ const { text } = rewrite(
346
+ `![i](/workspace/other/${PLAN}) [q](/workspace/other/${PLAN})\n`,
347
+ OUTSIDE,
348
+ PLAN,
349
+ NEW_PLAN,
350
+ );
351
+ expect(text).toBe(`![i](/workspace/other/${NEW_PLAN}) [q](/workspace/other/${PLAN})\n`);
352
+ });
353
+ });