@bevel-software/platform-core-backend 0.25.2 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (733) hide show
  1. package/agent-guide/access-control.md +251 -0
  2. package/agent-guide/conventions.md +35 -0
  3. package/agent-guide/directory-structure.md +145 -0
  4. package/agent-guide/finding-things.md +7 -0
  5. package/agent-guide/html-views.md +83 -0
  6. package/agent-guide/introduction.md +27 -0
  7. package/agent-guide/new-knowledge-base.md +24 -0
  8. package/agent-guide/skills.md +47 -0
  9. package/agent-guide/tool-manuals.md +227 -0
  10. package/agent-guide/where-a-new-file-goes.md +36 -0
  11. package/dist/assets.d.ts +26 -0
  12. package/dist/assets.d.ts.map +1 -1
  13. package/dist/assets.js +35 -2
  14. package/dist/assets.js.map +1 -1
  15. package/dist/core/catalog-revision.d.ts +19 -1
  16. package/dist/core/catalog-revision.d.ts.map +1 -1
  17. package/dist/core/catalog-revision.js +14 -3
  18. package/dist/core/catalog-revision.js.map +1 -1
  19. package/dist/core/core-ports.d.ts +11 -0
  20. package/dist/core/core-ports.d.ts.map +1 -1
  21. package/dist/core/core-ports.js.map +1 -1
  22. package/dist/core/create-core-server.d.ts +5 -0
  23. package/dist/core/create-core-server.d.ts.map +1 -1
  24. package/dist/core/create-core-server.js +65 -3
  25. package/dist/core/create-core-server.js.map +1 -1
  26. package/dist/core/create-core-services.d.ts +35 -0
  27. package/dist/core/create-core-services.d.ts.map +1 -1
  28. package/dist/core/create-core-services.js +114 -12
  29. package/dist/core/create-core-services.js.map +1 -1
  30. package/dist/core/lifecycle.d.ts +16 -1
  31. package/dist/core/lifecycle.d.ts.map +1 -1
  32. package/dist/core/lifecycle.js +18 -1
  33. package/dist/core/lifecycle.js.map +1 -1
  34. package/dist/core-config.d.ts +21 -0
  35. package/dist/core-config.d.ts.map +1 -1
  36. package/dist/core-config.js +22 -1
  37. package/dist/core-config.js.map +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +2 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/modules/access/access-control.interface.d.ts +17 -0
  43. package/dist/modules/access/access-control.interface.d.ts.map +1 -1
  44. package/dist/modules/access/access-control.service.d.ts +2 -0
  45. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  46. package/dist/modules/access/access-control.service.js +27 -0
  47. package/dist/modules/access/access-control.service.js.map +1 -1
  48. package/dist/modules/access/directory-sync-bot.js +1 -1
  49. package/dist/modules/access/directory-sync-bot.js.map +1 -1
  50. package/dist/modules/agent-guide/agent-guide.d.ts +145 -0
  51. package/dist/modules/agent-guide/agent-guide.d.ts.map +1 -0
  52. package/dist/modules/agent-guide/agent-guide.js +199 -0
  53. package/dist/modules/agent-guide/agent-guide.js.map +1 -0
  54. package/dist/modules/agent-guide/agent-guide.tools.d.ts +24 -0
  55. package/dist/modules/agent-guide/agent-guide.tools.d.ts.map +1 -0
  56. package/dist/modules/agent-guide/agent-guide.tools.js +100 -0
  57. package/dist/modules/agent-guide/agent-guide.tools.js.map +1 -0
  58. package/dist/modules/agent-guide/index.d.ts +4 -0
  59. package/dist/modules/agent-guide/index.d.ts.map +1 -0
  60. package/dist/modules/agent-guide/index.js +4 -0
  61. package/dist/modules/agent-guide/index.js.map +1 -0
  62. package/dist/modules/agent-instructions/agent-instructions.routes.d.ts +3 -2
  63. package/dist/modules/agent-instructions/agent-instructions.routes.d.ts.map +1 -1
  64. package/dist/modules/agent-instructions/agent-instructions.routes.js +3 -2
  65. package/dist/modules/agent-instructions/agent-instructions.routes.js.map +1 -1
  66. package/dist/modules/agent-instructions/compose.d.ts +14 -6
  67. package/dist/modules/agent-instructions/compose.d.ts.map +1 -1
  68. package/dist/modules/agent-instructions/compose.js +28 -8
  69. package/dist/modules/agent-instructions/compose.js.map +1 -1
  70. package/dist/modules/agent-instructions/index.d.ts +1 -1
  71. package/dist/modules/agent-instructions/index.d.ts.map +1 -1
  72. package/dist/modules/agent-instructions/index.js +1 -1
  73. package/dist/modules/agent-instructions/index.js.map +1 -1
  74. package/dist/modules/agent-instructions/shared-file-rules.d.ts +10 -50
  75. package/dist/modules/agent-instructions/shared-file-rules.d.ts.map +1 -1
  76. package/dist/modules/agent-instructions/shared-file-rules.js +51 -104
  77. package/dist/modules/agent-instructions/shared-file-rules.js.map +1 -1
  78. package/dist/modules/audit/agent-audit.service.d.ts +21 -2
  79. package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
  80. package/dist/modules/audit/agent-audit.service.js +43 -2
  81. package/dist/modules/audit/agent-audit.service.js.map +1 -1
  82. package/dist/modules/audit/agent-connection.routes.d.ts +34 -0
  83. package/dist/modules/audit/agent-connection.routes.d.ts.map +1 -0
  84. package/dist/modules/audit/agent-connection.routes.js +38 -0
  85. package/dist/modules/audit/agent-connection.routes.js.map +1 -0
  86. package/dist/modules/audit/audit.contract.d.ts +24 -0
  87. package/dist/modules/audit/audit.contract.d.ts.map +1 -1
  88. package/dist/modules/audit/audit.contract.js.map +1 -1
  89. package/dist/modules/audit/index.d.ts +1 -0
  90. package/dist/modules/audit/index.d.ts.map +1 -1
  91. package/dist/modules/audit/index.js +1 -0
  92. package/dist/modules/audit/index.js.map +1 -1
  93. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  94. package/dist/modules/auth/account.routes.js +10 -3
  95. package/dist/modules/auth/account.routes.js.map +1 -1
  96. package/dist/modules/auth/auth.middleware.d.ts +7 -0
  97. package/dist/modules/auth/auth.middleware.d.ts.map +1 -1
  98. package/dist/modules/auth/auth.middleware.js +1 -1
  99. package/dist/modules/auth/auth.middleware.js.map +1 -1
  100. package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -1
  101. package/dist/modules/code-mode/code-mode.tool.js +11 -3
  102. package/dist/modules/code-mode/code-mode.tool.js.map +1 -1
  103. package/dist/modules/database/core-schema.d.ts +96 -0
  104. package/dist/modules/database/core-schema.d.ts.map +1 -1
  105. package/dist/modules/database/core-schema.js +32 -3
  106. package/dist/modules/database/core-schema.js.map +1 -1
  107. package/dist/modules/embed/account-link.service.d.ts +42 -0
  108. package/dist/modules/embed/account-link.service.d.ts.map +1 -0
  109. package/dist/modules/embed/account-link.service.js +50 -0
  110. package/dist/modules/embed/account-link.service.js.map +1 -0
  111. package/dist/modules/embed/embed-link.d.ts +58 -0
  112. package/dist/modules/embed/embed-link.d.ts.map +1 -0
  113. package/dist/modules/embed/embed-link.js +160 -0
  114. package/dist/modules/embed/embed-link.js.map +1 -0
  115. package/dist/modules/embed/embed.errors.d.ts +30 -0
  116. package/dist/modules/embed/embed.errors.d.ts.map +1 -0
  117. package/dist/modules/embed/embed.errors.js +42 -0
  118. package/dist/modules/embed/embed.errors.js.map +1 -0
  119. package/dist/modules/embed/embed.interface.d.ts +204 -0
  120. package/dist/modules/embed/embed.interface.d.ts.map +1 -0
  121. package/dist/modules/embed/embed.interface.js +2 -0
  122. package/dist/modules/embed/embed.interface.js.map +1 -0
  123. package/dist/modules/embed/embed.routes.d.ts +59 -0
  124. package/dist/modules/embed/embed.routes.d.ts.map +1 -0
  125. package/dist/modules/embed/embed.routes.js +343 -0
  126. package/dist/modules/embed/embed.routes.js.map +1 -0
  127. package/dist/modules/embed/embed.service.d.ts +169 -0
  128. package/dist/modules/embed/embed.service.d.ts.map +1 -0
  129. package/dist/modules/embed/embed.service.js +627 -0
  130. package/dist/modules/embed/embed.service.js.map +1 -0
  131. package/dist/modules/embed/embed.tools.d.ts +51 -0
  132. package/dist/modules/embed/embed.tools.d.ts.map +1 -0
  133. package/dist/modules/embed/embed.tools.js +170 -0
  134. package/dist/modules/embed/embed.tools.js.map +1 -0
  135. package/dist/modules/embed/mcp-app.d.ts +64 -0
  136. package/dist/modules/embed/mcp-app.d.ts.map +1 -0
  137. package/dist/modules/embed/mcp-app.js +147 -0
  138. package/dist/modules/embed/mcp-app.js.map +1 -0
  139. package/dist/modules/embed/mcp-app.routes.d.ts +21 -0
  140. package/dist/modules/embed/mcp-app.routes.d.ts.map +1 -0
  141. package/dist/modules/embed/mcp-app.routes.js +36 -0
  142. package/dist/modules/embed/mcp-app.routes.js.map +1 -0
  143. package/dist/modules/github-app/github-app.connection.d.ts +15 -0
  144. package/dist/modules/github-app/github-app.connection.d.ts.map +1 -1
  145. package/dist/modules/github-app/github-app.connection.js +34 -3
  146. package/dist/modules/github-app/github-app.connection.js.map +1 -1
  147. package/dist/modules/kb-fs/locking-filesystem.d.ts +65 -0
  148. package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
  149. package/dist/modules/kb-fs/locking-filesystem.js +300 -0
  150. package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
  151. package/dist/modules/kb-sync/kb-sync.interface.d.ts +5 -0
  152. package/dist/modules/kb-sync/kb-sync.interface.d.ts.map +1 -1
  153. package/dist/modules/kb-sync/kb-sync.service.d.ts.map +1 -1
  154. package/dist/modules/kb-sync/kb-sync.service.js +6 -0
  155. package/dist/modules/kb-sync/kb-sync.service.js.map +1 -1
  156. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
  157. package/dist/modules/mcp/mcp-auth.middleware.js +2 -1
  158. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
  159. package/dist/modules/mcp/mcp.service.d.ts +57 -3
  160. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  161. package/dist/modules/mcp/mcp.service.js +177 -24
  162. package/dist/modules/mcp/mcp.service.js.map +1 -1
  163. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +24 -0
  164. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  165. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +32 -4
  166. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  167. package/dist/modules/mcp/tool-schema-guard.d.ts +105 -0
  168. package/dist/modules/mcp/tool-schema-guard.d.ts.map +1 -0
  169. package/dist/modules/mcp/tool-schema-guard.js +171 -0
  170. package/dist/modules/mcp/tool-schema-guard.js.map +1 -0
  171. package/dist/modules/onboarding/onboarding.contract.d.ts +80 -0
  172. package/dist/modules/onboarding/onboarding.contract.d.ts.map +1 -0
  173. package/dist/modules/onboarding/onboarding.contract.js +7 -0
  174. package/dist/modules/onboarding/onboarding.contract.js.map +1 -0
  175. package/dist/modules/onboarding/onboarding.routes.d.ts +18 -0
  176. package/dist/modules/onboarding/onboarding.routes.d.ts.map +1 -0
  177. package/dist/modules/onboarding/onboarding.routes.js +81 -0
  178. package/dist/modules/onboarding/onboarding.routes.js.map +1 -0
  179. package/dist/modules/onboarding/starter-pack.service.d.ts +213 -0
  180. package/dist/modules/onboarding/starter-pack.service.d.ts.map +1 -0
  181. package/dist/modules/onboarding/starter-pack.service.js +492 -0
  182. package/dist/modules/onboarding/starter-pack.service.js.map +1 -0
  183. package/dist/modules/onboarding/starter-packs.d.ts +78 -0
  184. package/dist/modules/onboarding/starter-packs.d.ts.map +1 -0
  185. package/dist/modules/onboarding/starter-packs.js +156 -0
  186. package/dist/modules/onboarding/starter-packs.js.map +1 -0
  187. package/dist/modules/plugins/index.d.ts +1 -1
  188. package/dist/modules/plugins/index.d.ts.map +1 -1
  189. package/dist/modules/plugins/index.js +1 -1
  190. package/dist/modules/plugins/index.js.map +1 -1
  191. package/dist/modules/plugins/plugin-provision.service.d.ts +19 -0
  192. package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
  193. package/dist/modules/plugins/plugin-provision.service.js +18 -1
  194. package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
  195. package/dist/modules/plugins/plugins.routes.d.ts +0 -36
  196. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  197. package/dist/modules/plugins/plugins.routes.js +31 -0
  198. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  199. package/dist/modules/plugins/plugins.tools.d.ts +36 -2
  200. package/dist/modules/plugins/plugins.tools.d.ts.map +1 -1
  201. package/dist/modules/plugins/plugins.tools.js +71 -14
  202. package/dist/modules/plugins/plugins.tools.js.map +1 -1
  203. package/dist/modules/settings/deployment-settings.service.d.ts +34 -7
  204. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  205. package/dist/modules/settings/deployment-settings.service.js +148 -54
  206. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  207. package/dist/modules/settings/repository-source.d.ts +1 -0
  208. package/dist/modules/settings/repository-source.d.ts.map +1 -1
  209. package/dist/modules/settings/repository-source.js +3 -3
  210. package/dist/modules/settings/repository-source.js.map +1 -1
  211. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  212. package/dist/modules/settings/setup.routes.js +3 -6
  213. package/dist/modules/settings/setup.routes.js.map +1 -1
  214. package/dist/modules/skills/skills.tools.d.ts.map +1 -1
  215. package/dist/modules/skills/skills.tools.js +103 -43
  216. package/dist/modules/skills/skills.tools.js.map +1 -1
  217. package/dist/modules/tool-auth/connection-key-rejection.d.ts +10 -1
  218. package/dist/modules/tool-auth/connection-key-rejection.d.ts.map +1 -1
  219. package/dist/modules/tool-auth/connection-key-rejection.js +11 -3
  220. package/dist/modules/tool-auth/connection-key-rejection.js.map +1 -1
  221. package/dist/modules/tool-auth/external-api-key.interface.d.ts +8 -0
  222. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
  223. package/dist/modules/tool-auth/external-api-key.service.d.ts +24 -2
  224. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  225. package/dist/modules/tool-auth/external-api-key.service.js +59 -2
  226. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  227. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
  228. package/dist/modules/tool-auth/tool-auth.middleware.js +9 -4
  229. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
  230. package/dist/modules/tool-helpers/index.d.ts +28 -1
  231. package/dist/modules/tool-helpers/index.d.ts.map +1 -1
  232. package/dist/modules/tool-helpers/index.js +28 -1
  233. package/dist/modules/tool-helpers/index.js.map +1 -1
  234. package/dist/modules/tool-helpers/route-argument-check.d.ts +10 -0
  235. package/dist/modules/tool-helpers/route-argument-check.d.ts.map +1 -0
  236. package/dist/modules/tool-helpers/route-argument-check.js +132 -0
  237. package/dist/modules/tool-helpers/route-argument-check.js.map +1 -0
  238. package/dist/modules/tool-helpers/route-tool-schemas.d.ts +89 -0
  239. package/dist/modules/tool-helpers/route-tool-schemas.d.ts.map +1 -0
  240. package/dist/modules/tool-helpers/route-tool-schemas.js +113 -0
  241. package/dist/modules/tool-helpers/route-tool-schemas.js.map +1 -0
  242. package/dist/modules/tool-helpers/tool-def.d.ts +71 -0
  243. package/dist/modules/tool-helpers/tool-def.d.ts.map +1 -1
  244. package/dist/modules/tool-helpers/tool-def.js +70 -6
  245. package/dist/modules/tool-helpers/tool-def.js.map +1 -1
  246. package/dist/modules/tool-helpers/tool-handler.d.ts +46 -6
  247. package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
  248. package/dist/modules/tool-helpers/tool-handler.js +157 -8
  249. package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
  250. package/dist/modules/tool-helpers/tool.contract.d.ts +9 -0
  251. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
  252. package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
  253. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +23 -4
  254. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
  255. package/dist/modules/tool-manuals/tool-manuals.contract.js.map +1 -1
  256. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +4 -0
  257. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  258. package/dist/modules/tool-manuals/tool-manuals.service.js +14 -0
  259. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  260. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +7 -0
  261. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  262. package/dist/modules/tool-manuals/tool-manuals.tools.js +77 -38
  263. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  264. package/dist/modules/tool-registry/description-length.d.ts +20 -16
  265. package/dist/modules/tool-registry/description-length.d.ts.map +1 -1
  266. package/dist/modules/tool-registry/description-length.js +50 -30
  267. package/dist/modules/tool-registry/description-length.js.map +1 -1
  268. package/dist/modules/tool-registry/guide-first.d.ts +27 -0
  269. package/dist/modules/tool-registry/guide-first.d.ts.map +1 -0
  270. package/dist/modules/tool-registry/guide-first.js +40 -0
  271. package/dist/modules/tool-registry/guide-first.js.map +1 -0
  272. package/dist/modules/tool-registry/tool-registry.d.ts +6 -0
  273. package/dist/modules/tool-registry/tool-registry.d.ts.map +1 -1
  274. package/dist/modules/tool-registry/tool-registry.js +9 -2
  275. package/dist/modules/tool-registry/tool-registry.js.map +1 -1
  276. package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts +449 -0
  277. package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts.map +1 -0
  278. package/dist/modules/workflow/agent-tools/change-request-read-shape.js +481 -0
  279. package/dist/modules/workflow/agent-tools/change-request-read-shape.js.map +1 -0
  280. package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts +126 -0
  281. package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts.map +1 -0
  282. package/dist/modules/workflow/agent-tools/change-request-read.tools.js +611 -0
  283. package/dist/modules/workflow/agent-tools/change-request-read.tools.js.map +1 -0
  284. package/dist/modules/workflow/agent-tools/change-request-summary.d.ts +12 -1
  285. package/dist/modules/workflow/agent-tools/change-request-summary.d.ts.map +1 -1
  286. package/dist/modules/workflow/agent-tools/change-request-summary.js +5 -1
  287. package/dist/modules/workflow/agent-tools/change-request-summary.js.map +1 -1
  288. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +8 -1
  289. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  290. package/dist/modules/workflow/agent-tools/workflow.tools.js +133 -37
  291. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  292. package/dist/modules/workflow/file-lock.service.d.ts +29 -5
  293. package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
  294. package/dist/modules/workflow/file-lock.service.js +62 -5
  295. package/dist/modules/workflow/file-lock.service.js.map +1 -1
  296. package/dist/modules/workflow/git/git.service.d.ts +282 -14
  297. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  298. package/dist/modules/workflow/git/git.service.js +627 -126
  299. package/dist/modules/workflow/git/git.service.js.map +1 -1
  300. package/dist/modules/workflow/git/merge-commit.d.ts +73 -0
  301. package/dist/modules/workflow/git/merge-commit.d.ts.map +1 -0
  302. package/dist/modules/workflow/git/merge-commit.js +89 -0
  303. package/dist/modules/workflow/git/merge-commit.js.map +1 -0
  304. package/dist/modules/workflow/git/node-git-runner.d.ts +15 -0
  305. package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
  306. package/dist/modules/workflow/git/node-git-runner.js +78 -6
  307. package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
  308. package/dist/modules/workflow/git/pull-request.service.d.ts +94 -1
  309. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
  310. package/dist/modules/workflow/git/pull-request.service.js +332 -37
  311. package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
  312. package/dist/modules/workflow/pending-commits.service.d.ts +15 -0
  313. package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
  314. package/dist/modules/workflow/pending-commits.service.js +25 -1
  315. package/dist/modules/workflow/pending-commits.service.js.map +1 -1
  316. package/dist/modules/workflow/pending-commits.worker.d.ts +6 -1
  317. package/dist/modules/workflow/pending-commits.worker.d.ts.map +1 -1
  318. package/dist/modules/workflow/pending-commits.worker.js +23 -6
  319. package/dist/modules/workflow/pending-commits.worker.js.map +1 -1
  320. package/dist/modules/workflow/recovery-bot.js +1 -1
  321. package/dist/modules/workflow/recovery-bot.js.map +1 -1
  322. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts +35 -0
  323. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
  324. package/dist/modules/workflow/review-workflow/review-workflow.service.js +180 -13
  325. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
  326. package/dist/modules/workflow/sanitize-error.d.ts +16 -0
  327. package/dist/modules/workflow/sanitize-error.d.ts.map +1 -1
  328. package/dist/modules/workflow/sanitize-error.js +45 -0
  329. package/dist/modules/workflow/sanitize-error.js.map +1 -1
  330. package/dist/modules/workflow/workflow.routes.d.ts +6 -2
  331. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
  332. package/dist/modules/workflow/workflow.routes.js +7 -2
  333. package/dist/modules/workflow/workflow.routes.js.map +1 -1
  334. package/dist/modules/workflow/workflow.service.d.ts +187 -15
  335. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  336. package/dist/modules/workflow/workflow.service.js +808 -106
  337. package/dist/modules/workflow/workflow.service.js.map +1 -1
  338. package/dist/modules/workspace/agent-download.builder.d.ts +105 -0
  339. package/dist/modules/workspace/agent-download.builder.d.ts.map +1 -0
  340. package/dist/modules/workspace/agent-download.builder.js +238 -0
  341. package/dist/modules/workspace/agent-download.builder.js.map +1 -0
  342. package/dist/modules/workspace/agent-download.routes.d.ts +77 -0
  343. package/dist/modules/workspace/agent-download.routes.d.ts.map +1 -0
  344. package/dist/modules/workspace/agent-download.routes.js +156 -0
  345. package/dist/modules/workspace/agent-download.routes.js.map +1 -0
  346. package/dist/modules/workspace/agent-download.store.d.ts +225 -0
  347. package/dist/modules/workspace/agent-download.store.d.ts.map +1 -0
  348. package/dist/modules/workspace/agent-download.store.js +423 -0
  349. package/dist/modules/workspace/agent-download.store.js.map +1 -0
  350. package/dist/modules/workspace/agent-upload.store.d.ts +10 -1
  351. package/dist/modules/workspace/agent-upload.store.d.ts.map +1 -1
  352. package/dist/modules/workspace/agent-upload.store.js +16 -6
  353. package/dist/modules/workspace/agent-upload.store.js.map +1 -1
  354. package/dist/modules/workspace/file-readers/raw-mime.d.ts +6 -0
  355. package/dist/modules/workspace/file-readers/raw-mime.d.ts.map +1 -0
  356. package/dist/modules/workspace/file-readers/raw-mime.js +38 -0
  357. package/dist/modules/workspace/file-readers/raw-mime.js.map +1 -0
  358. package/dist/modules/workspace/file-readers/text-reader.d.ts +5 -5
  359. package/dist/modules/workspace/file-readers/text-reader.d.ts.map +1 -1
  360. package/dist/modules/workspace/file-readers/text-reader.js +5 -8
  361. package/dist/modules/workspace/file-readers/text-reader.js.map +1 -1
  362. package/dist/modules/workspace/first-run.d.ts +111 -0
  363. package/dist/modules/workspace/first-run.d.ts.map +1 -0
  364. package/dist/modules/workspace/first-run.js +181 -0
  365. package/dist/modules/workspace/first-run.js.map +1 -0
  366. package/dist/modules/workspace/move-links.d.ts +92 -0
  367. package/dist/modules/workspace/move-links.d.ts.map +1 -0
  368. package/dist/modules/workspace/move-links.js +173 -0
  369. package/dist/modules/workspace/move-links.js.map +1 -0
  370. package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
  371. package/dist/modules/workspace/startup/steps/seed-tree.js +24 -39
  372. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  373. package/dist/modules/workspace/startup/steps/template-files.step.d.ts +58 -52
  374. package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
  375. package/dist/modules/workspace/startup/steps/template-files.step.js +209 -223
  376. package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
  377. package/dist/modules/workspace/startup/steps/template-source.d.ts +5 -3
  378. package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -1
  379. package/dist/modules/workspace/startup/steps/template-source.js +5 -3
  380. package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
  381. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  382. package/dist/modules/workspace/workspace.routes.js +63 -22
  383. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  384. package/dist/modules/workspace/workspace.service.d.ts +75 -2
  385. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  386. package/dist/modules/workspace/workspace.service.js +197 -24
  387. package/dist/modules/workspace/workspace.service.js.map +1 -1
  388. package/dist/modules/workspace/workspace.tools.d.ts +68 -1
  389. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  390. package/dist/modules/workspace/workspace.tools.js +642 -71
  391. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  392. package/dist/modules/write-access/write-access.d.ts.map +1 -1
  393. package/dist/modules/write-access/write-access.js +9 -0
  394. package/dist/modules/write-access/write-access.js.map +1 -1
  395. package/dist/shared/domain-errors.d.ts +84 -1
  396. package/dist/shared/domain-errors.d.ts.map +1 -1
  397. package/dist/shared/domain-errors.js +100 -12
  398. package/dist/shared/domain-errors.js.map +1 -1
  399. package/dist/shared/git.contract.d.ts +10 -1
  400. package/dist/shared/git.contract.d.ts.map +1 -1
  401. package/dist/shared/git.contract.js.map +1 -1
  402. package/dist/shared/hidden-tools.d.ts +44 -0
  403. package/dist/shared/hidden-tools.d.ts.map +1 -0
  404. package/dist/shared/hidden-tools.js +13 -0
  405. package/dist/shared/hidden-tools.js.map +1 -0
  406. package/dist/shared/utf8-text.d.ts +15 -0
  407. package/dist/shared/utf8-text.d.ts.map +1 -0
  408. package/dist/shared/utf8-text.js +20 -0
  409. package/dist/shared/utf8-text.js.map +1 -0
  410. package/dist/tenancy/static-tenant-source.d.ts +2 -1
  411. package/dist/tenancy/static-tenant-source.d.ts.map +1 -1
  412. package/dist/tenancy/static-tenant-source.js +9 -2
  413. package/dist/tenancy/static-tenant-source.js.map +1 -1
  414. package/kb-template/.bevelignore +0 -5
  415. package/mcp-app/page.html +349 -0
  416. package/migrations/0017_atlassian_account_links.sql +37 -0
  417. package/migrations/meta/0017_snapshot.json +2396 -0
  418. package/migrations/meta/_journal.json +8 -1
  419. package/package.json +6 -3
  420. package/src/__tests__/kb-layout-config.test.ts +10 -100
  421. package/src/__tests__/packaged-assets-ship.test.ts +66 -0
  422. package/src/assets.ts +38 -2
  423. package/src/core/__tests__/catalog-revision.test.ts +40 -0
  424. package/src/core/__tests__/gated-boot.test.ts +1 -0
  425. package/src/core/__tests__/lifecycle.test.ts +14 -0
  426. package/src/core/catalog-revision.ts +15 -2
  427. package/src/core/core-ports.ts +11 -0
  428. package/src/core/create-core-server.ts +78 -3
  429. package/src/core/create-core-services.ts +168 -10
  430. package/src/core/lifecycle.ts +28 -2
  431. package/src/core-config.ts +24 -1
  432. package/src/index.ts +2 -2
  433. package/src/modules/access/__tests__/access-control.atref-batch.test.ts +58 -0
  434. package/src/modules/access/__tests__/access-control.platform-restore.test.ts +8 -7
  435. package/src/modules/access/__tests__/access-control.service.test.ts +19 -0
  436. package/src/modules/access/__tests__/access-personal-plugin.test.ts +1 -18
  437. package/src/modules/access/access-control.interface.ts +28 -0
  438. package/src/modules/access/access-control.service.ts +37 -0
  439. package/src/modules/access/directory-sync-bot.ts +1 -1
  440. package/src/modules/agent-guide/__tests__/agent-guide.test.ts +386 -0
  441. package/src/modules/agent-guide/__tests__/agent-guide.tools.test.ts +207 -0
  442. package/src/modules/agent-guide/agent-guide.tools.ts +122 -0
  443. package/src/modules/agent-guide/agent-guide.ts +300 -0
  444. package/src/modules/agent-guide/index.ts +22 -0
  445. package/src/modules/agent-instructions/__tests__/shared-file-rules.test.ts +39 -118
  446. package/src/modules/agent-instructions/agent-instructions.routes.ts +3 -2
  447. package/src/modules/agent-instructions/compose.ts +26 -8
  448. package/src/modules/agent-instructions/index.ts +0 -3
  449. package/src/modules/agent-instructions/shared-file-rules.ts +50 -112
  450. package/src/modules/audit/__tests__/agent-audit.service.test.ts +64 -4
  451. package/src/modules/audit/__tests__/agent-connection.routes.test.ts +102 -0
  452. package/src/modules/audit/agent-audit.service.ts +58 -3
  453. package/src/modules/audit/agent-connection.routes.ts +56 -0
  454. package/src/modules/audit/audit.contract.ts +26 -0
  455. package/src/modules/audit/index.ts +1 -0
  456. package/src/modules/auth/__tests__/account.routes.test.ts +5 -3
  457. package/src/modules/auth/account.routes.ts +10 -3
  458. package/src/modules/auth/auth.middleware.ts +1 -1
  459. package/src/modules/code-mode/__tests__/code-mode.tool.test.ts +18 -2
  460. package/src/modules/code-mode/code-mode.tool.ts +13 -2
  461. package/src/modules/database/core-schema.ts +33 -3
  462. package/src/modules/embed/__tests__/account-links.migration.test.ts +98 -0
  463. package/src/modules/embed/__tests__/embed-link.test.ts +122 -0
  464. package/src/modules/embed/__tests__/embed.routes.test.ts +362 -0
  465. package/src/modules/embed/__tests__/embed.service.lock.test.ts +193 -0
  466. package/src/modules/embed/__tests__/embed.service.test.ts +805 -0
  467. package/src/modules/embed/__tests__/embed.tools.test.ts +304 -0
  468. package/src/modules/embed/__tests__/mcp-app.test.ts +207 -0
  469. package/src/modules/embed/account-link.service.ts +76 -0
  470. package/src/modules/embed/embed-link.ts +180 -0
  471. package/src/modules/embed/embed.errors.ts +43 -0
  472. package/src/modules/embed/embed.interface.ts +203 -0
  473. package/src/modules/embed/embed.routes.ts +363 -0
  474. package/src/modules/embed/embed.service.ts +705 -0
  475. package/src/modules/embed/embed.tools.ts +206 -0
  476. package/src/modules/embed/mcp-app.routes.ts +41 -0
  477. package/src/modules/embed/mcp-app.ts +173 -0
  478. package/src/modules/github-app/__tests__/github-app.test.ts +76 -0
  479. package/src/modules/github-app/github-app.connection.ts +38 -4
  480. package/src/modules/kb-fs/__tests__/move-with-edits.test.ts +304 -0
  481. package/src/modules/kb-fs/locking-filesystem.ts +287 -0
  482. package/src/modules/kb-sync/__tests__/kb-sync.service.test.ts +35 -0
  483. package/src/modules/kb-sync/kb-sync.interface.ts +2 -0
  484. package/src/modules/kb-sync/kb-sync.service.ts +6 -0
  485. package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +68 -11
  486. package/src/modules/mcp/__tests__/fake-downstream-mcp-server.ts +14 -3
  487. package/src/modules/mcp/__tests__/mcp-proxy-helpers.test.ts +37 -2
  488. package/src/modules/mcp/__tests__/mcp.app.e2e.test.ts +200 -0
  489. package/src/modules/mcp/__tests__/mcp.e2e.test.ts +252 -0
  490. package/src/modules/mcp/__tests__/mcp.service.test.ts +42 -24
  491. package/src/modules/mcp/__tests__/tool-call-interface.e2e.test.ts +499 -0
  492. package/src/modules/mcp/__tests__/tool-schema-guard.test.ts +266 -0
  493. package/src/modules/mcp/mcp-auth.middleware.ts +2 -1
  494. package/src/modules/mcp/mcp.service.ts +218 -31
  495. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +42 -4
  496. package/src/modules/mcp/tool-schema-guard.ts +196 -0
  497. package/src/modules/onboarding/__tests__/onboarding.routes.test.ts +163 -0
  498. package/src/modules/onboarding/__tests__/starter-pack.service.test.ts +635 -0
  499. package/src/modules/onboarding/__tests__/starter-packs.test.ts +169 -0
  500. package/src/modules/onboarding/onboarding.contract.ts +85 -0
  501. package/src/modules/onboarding/onboarding.routes.ts +85 -0
  502. package/src/modules/onboarding/starter-pack.service.ts +580 -0
  503. package/src/modules/onboarding/starter-packs.ts +182 -0
  504. package/src/modules/plugins/__tests__/plugins.tools.test.ts +177 -4
  505. package/src/modules/plugins/index.ts +1 -0
  506. package/src/modules/plugins/plugin-provision.service.ts +22 -1
  507. package/src/modules/plugins/plugins.routes.ts +29 -0
  508. package/src/modules/plugins/plugins.tools.ts +75 -15
  509. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +176 -56
  510. package/src/modules/settings/__tests__/repository-source.test.ts +9 -0
  511. package/src/modules/settings/deployment-settings.service.ts +144 -55
  512. package/src/modules/settings/repository-source.ts +4 -4
  513. package/src/modules/settings/setup.routes.ts +3 -6
  514. package/src/modules/skills/__tests__/skills.tools.description.test.ts +95 -0
  515. package/src/modules/skills/skills.tools.ts +112 -46
  516. package/src/modules/tool-auth/__tests__/connection-key-rejection.test.ts +32 -0
  517. package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +65 -0
  518. package/src/modules/tool-auth/connection-key-rejection.ts +13 -3
  519. package/src/modules/tool-auth/external-api-key.interface.ts +9 -0
  520. package/src/modules/tool-auth/external-api-key.service.ts +61 -4
  521. package/src/modules/tool-auth/tool-auth.middleware.ts +13 -4
  522. package/src/modules/tool-helpers/__tests__/branch-declaration.test.ts +502 -0
  523. package/src/modules/tool-helpers/__tests__/route-argument-check.test.ts +337 -0
  524. package/src/modules/tool-helpers/index.ts +34 -1
  525. package/src/modules/tool-helpers/route-argument-check.ts +149 -0
  526. package/src/modules/tool-helpers/route-tool-schemas.ts +171 -0
  527. package/src/modules/tool-helpers/tool-def.ts +132 -7
  528. package/src/modules/tool-helpers/tool-handler.ts +196 -8
  529. package/src/modules/tool-helpers/tool.contract.ts +9 -0
  530. package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +57 -0
  531. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +73 -4
  532. package/src/modules/tool-manuals/tool-manuals.contract.ts +24 -4
  533. package/src/modules/tool-manuals/tool-manuals.service.ts +17 -0
  534. package/src/modules/tool-manuals/tool-manuals.tools.ts +86 -38
  535. package/src/modules/tool-registry/__tests__/own-tool-schemas.test.ts +173 -0
  536. package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +81 -66
  537. package/src/modules/tool-registry/description-length.ts +57 -32
  538. package/src/modules/tool-registry/guide-first.ts +41 -0
  539. package/src/modules/tool-registry/tool-registry.ts +9 -2
  540. package/src/modules/workflow/__tests__/apply-failure.test.ts +6 -1
  541. package/src/modules/workflow/__tests__/file-lock.service.deletion-gate.test.ts +104 -0
  542. package/src/modules/workflow/__tests__/pending-commits.repository-replaced.test.ts +66 -0
  543. package/src/modules/workflow/__tests__/pending-commits.worker.test.ts +31 -2
  544. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +110 -6
  545. package/src/modules/workflow/__tests__/sanitize-error.test.ts +89 -1
  546. package/src/modules/workflow/__tests__/workflow.routes.push-refused.test.ts +202 -0
  547. package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +6 -6
  548. package/src/modules/workflow/__tests__/workflow.service.delete-branch.test.ts +1026 -0
  549. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +468 -10
  550. package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +4 -0
  551. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +5 -4
  552. package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +54 -2
  553. package/src/modules/workflow/agent-tools/__tests__/change-request-read-shape.test.ts +705 -0
  554. package/src/modules/workflow/agent-tools/__tests__/change-request-read.tools.test.ts +1554 -0
  555. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +150 -4
  556. package/src/modules/workflow/agent-tools/change-request-read-shape.ts +712 -0
  557. package/src/modules/workflow/agent-tools/change-request-read.tools.ts +759 -0
  558. package/src/modules/workflow/agent-tools/change-request-summary.ts +5 -1
  559. package/src/modules/workflow/agent-tools/workflow.tools.ts +137 -35
  560. package/src/modules/workflow/file-lock.service.ts +67 -5
  561. package/src/modules/workflow/git/__tests__/git.service.appliedChange.test.ts +285 -0
  562. package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +124 -0
  563. package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +164 -0
  564. package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +334 -0
  565. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +48 -1
  566. package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +231 -2
  567. package/src/modules/workflow/git/__tests__/pull-request.service.list-fetch.test.ts +72 -2
  568. package/src/modules/workflow/git/__tests__/pull-request.service.placeholder.test.ts +24 -2
  569. package/src/modules/workflow/git/__tests__/pull-request.service.test.ts +620 -1
  570. package/src/modules/workflow/git/git.service.ts +714 -133
  571. package/src/modules/workflow/git/merge-commit.ts +88 -0
  572. package/src/modules/workflow/git/node-git-runner.ts +82 -7
  573. package/src/modules/workflow/git/pull-request.service.ts +380 -54
  574. package/src/modules/workflow/pending-commits.service.ts +29 -1
  575. package/src/modules/workflow/pending-commits.worker.ts +24 -6
  576. package/src/modules/workflow/recovery-bot.ts +1 -1
  577. package/src/modules/workflow/review-workflow/__tests__/approval-states.test.ts +7 -1
  578. package/src/modules/workflow/review-workflow/__tests__/merge-records-own-commit.test.ts +407 -0
  579. package/src/modules/workflow/review-workflow/review-workflow.service.ts +191 -12
  580. package/src/modules/workflow/sanitize-error.ts +50 -0
  581. package/src/modules/workflow/workflow.routes.ts +7 -2
  582. package/src/modules/workflow/workflow.service.ts +886 -112
  583. package/src/modules/workspace/__tests__/agent-downloads.test.ts +823 -0
  584. package/src/modules/workspace/__tests__/escape-sequences.routes.test.ts +4 -3
  585. package/src/modules/workspace/__tests__/first-run.test.ts +234 -0
  586. package/src/modules/workspace/__tests__/git-internals.security.test.ts +5 -2
  587. package/src/modules/workspace/__tests__/md-links.test.ts +353 -0
  588. package/src/modules/workspace/__tests__/move-links.test.ts +261 -0
  589. package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +219 -0
  590. package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -0
  591. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +102 -0
  592. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +52 -5
  593. package/src/modules/workspace/__tests__/workspace.routes.folder-zip-access.test.ts +190 -0
  594. package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +21 -10
  595. package/src/modules/workspace/__tests__/workspace.service.forget-clone-races.test.ts +8 -4
  596. package/src/modules/workspace/__tests__/workspace.service.test.ts +50 -8
  597. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +33 -55
  598. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +44 -1
  599. package/src/modules/workspace/__tests__/workspace.tools.test.ts +664 -34
  600. package/src/modules/workspace/agent-download.builder.ts +308 -0
  601. package/src/modules/workspace/agent-download.routes.ts +183 -0
  602. package/src/modules/workspace/agent-download.store.ts +533 -0
  603. package/src/modules/workspace/agent-upload.store.ts +23 -7
  604. package/src/modules/workspace/file-readers/raw-mime.ts +40 -0
  605. package/src/modules/workspace/file-readers/text-reader.ts +5 -8
  606. package/src/modules/workspace/first-run.ts +222 -0
  607. package/src/modules/workspace/move-links.ts +237 -0
  608. package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +191 -489
  609. package/src/modules/workspace/startup/steps/seed-tree.ts +23 -38
  610. package/src/modules/workspace/startup/steps/template-files.step.ts +217 -249
  611. package/src/modules/workspace/startup/steps/template-source.ts +5 -3
  612. package/src/modules/workspace/workspace.routes.ts +64 -22
  613. package/src/modules/workspace/workspace.service.ts +202 -25
  614. package/src/modules/workspace/workspace.tools.ts +707 -68
  615. package/src/modules/write-access/__tests__/write-access.test.ts +13 -0
  616. package/src/modules/write-access/write-access.ts +9 -0
  617. package/src/shared/domain-errors.ts +123 -11
  618. package/src/shared/git.contract.ts +8 -1
  619. package/src/shared/hidden-tools.ts +45 -0
  620. package/src/shared/utf8-text.ts +21 -0
  621. package/src/tenancy/__tests__/static-tenant-source.test.ts +1 -0
  622. package/src/tenancy/static-tenant-source.ts +10 -2
  623. package/starter-packs/README.md +103 -0
  624. package/starter-packs/engineering/KnowledgeBase/About us.md +9 -0
  625. package/starter-packs/engineering/KnowledgeBase/Architecture.md +9 -0
  626. package/starter-packs/engineering/KnowledgeBase/Glossary.md +9 -0
  627. package/starter-packs/engineering/KnowledgeBase/How we ship.md +9 -0
  628. package/starter-packs/engineering/Plugins/engineering-starter/LICENSE +21 -0
  629. package/starter-packs/engineering/Plugins/engineering-starter/SOURCE.md +20 -0
  630. package/starter-packs/engineering/Plugins/engineering-starter/access.md +19 -0
  631. package/starter-packs/engineering/Plugins/engineering-starter/plugin.json +10 -0
  632. package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/SKILL.md +171 -0
  633. package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/sections/phase-2a-startup-diagnostic.md +157 -0
  634. package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/sections/phase-2b-builder-brainstorm.md +39 -0
  635. package/starter-packs/engineering/Plugins/engineering-starter/skills/plan-ceo-review/SKILL.md +144 -0
  636. package/starter-packs/engineering/Plugins/engineering-starter/skills/plan-eng-review/SKILL.md +144 -0
  637. package/starter-packs/engineering/Plugins/engineering-starter/skills/review/SKILL.md +80 -0
  638. package/starter-packs/engineering/Plugins/engineering-starter/skills/review/checklist.md +184 -0
  639. package/starter-packs/engineering/pack.yaml +11 -0
  640. package/starter-packs/general/KnowledgeBase/About us.md +9 -0
  641. package/starter-packs/general/KnowledgeBase/Glossary.md +9 -0
  642. package/starter-packs/general/KnowledgeBase/How we work.md +9 -0
  643. package/starter-packs/general/Plugins/general-starter/LICENSE +202 -0
  644. package/starter-packs/general/Plugins/general-starter/SOURCE.md +10 -0
  645. package/starter-packs/general/Plugins/general-starter/access.md +19 -0
  646. package/starter-packs/general/Plugins/general-starter/plugin.json +10 -0
  647. package/starter-packs/general/Plugins/general-starter/skills/memory-management/SKILL.md +332 -0
  648. package/starter-packs/general/Plugins/general-starter/skills/productivity-start/SKILL.md +163 -0
  649. package/starter-packs/general/Plugins/general-starter/skills/productivity-update/SKILL.md +167 -0
  650. package/starter-packs/general/Plugins/general-starter/skills/task-management/SKILL.md +83 -0
  651. package/starter-packs/general/pack.yaml +10 -0
  652. package/starter-packs/operations/KnowledgeBase/Glossary.md +9 -0
  653. package/starter-packs/operations/KnowledgeBase/How we work.md +9 -0
  654. package/starter-packs/operations/KnowledgeBase/Processes.md +9 -0
  655. package/starter-packs/operations/KnowledgeBase/Tools we use.md +9 -0
  656. package/starter-packs/operations/KnowledgeBase/Vendors.md +9 -0
  657. package/starter-packs/operations/Plugins/operations-starter/LICENSE +202 -0
  658. package/starter-packs/operations/Plugins/operations-starter/SOURCE.md +10 -0
  659. package/starter-packs/operations/Plugins/operations-starter/access.md +19 -0
  660. package/starter-packs/operations/Plugins/operations-starter/plugin.json +10 -0
  661. package/starter-packs/operations/Plugins/operations-starter/skills/capacity-plan/SKILL.md +111 -0
  662. package/starter-packs/operations/Plugins/operations-starter/skills/change-request/SKILL.md +119 -0
  663. package/starter-packs/operations/Plugins/operations-starter/skills/compliance-tracking/SKILL.md +44 -0
  664. package/starter-packs/operations/Plugins/operations-starter/skills/process-doc/SKILL.md +80 -0
  665. package/starter-packs/operations/Plugins/operations-starter/skills/process-optimization/SKILL.md +39 -0
  666. package/starter-packs/operations/Plugins/operations-starter/skills/risk-assessment/SKILL.md +40 -0
  667. package/starter-packs/operations/Plugins/operations-starter/skills/runbook/SKILL.md +85 -0
  668. package/starter-packs/operations/Plugins/operations-starter/skills/status-report/SKILL.md +75 -0
  669. package/starter-packs/operations/Plugins/operations-starter/skills/vendor-review/SKILL.md +102 -0
  670. package/starter-packs/operations/pack.yaml +12 -0
  671. package/starter-packs/sales/KnowledgeBase/About us.md +9 -0
  672. package/starter-packs/sales/KnowledgeBase/Customers.md +9 -0
  673. package/starter-packs/sales/KnowledgeBase/Glossary.md +9 -0
  674. package/starter-packs/sales/KnowledgeBase/How we sell.md +9 -0
  675. package/starter-packs/sales/KnowledgeBase/Objections.md +9 -0
  676. package/starter-packs/sales/KnowledgeBase/Pricing.md +9 -0
  677. package/starter-packs/sales/Plugins/sales-starter/LICENSE +202 -0
  678. package/starter-packs/sales/Plugins/sales-starter/SOURCE.md +10 -0
  679. package/starter-packs/sales/Plugins/sales-starter/access.md +19 -0
  680. package/starter-packs/sales/Plugins/sales-starter/plugin.json +10 -0
  681. package/starter-packs/sales/Plugins/sales-starter/skills/account-context/SKILL.md +94 -0
  682. package/starter-packs/sales/Plugins/sales-starter/skills/account-plan/SKILL.md +95 -0
  683. package/starter-packs/sales/Plugins/sales-starter/skills/account-research/SKILL.md +99 -0
  684. package/starter-packs/sales/Plugins/sales-starter/skills/account-tiering/SKILL.md +101 -0
  685. package/starter-packs/sales/Plugins/sales-starter/skills/call-prep/SKILL.md +111 -0
  686. package/starter-packs/sales/Plugins/sales-starter/skills/call-summary/SKILL.md +111 -0
  687. package/starter-packs/sales/Plugins/sales-starter/skills/close-plan/SKILL.md +106 -0
  688. package/starter-packs/sales/Plugins/sales-starter/skills/competitive-intelligence/SKILL.md +102 -0
  689. package/starter-packs/sales/Plugins/sales-starter/skills/create-an-asset/SKILL.md +105 -0
  690. package/starter-packs/sales/Plugins/sales-starter/skills/crm-hygiene-check/SKILL.md +103 -0
  691. package/starter-packs/sales/Plugins/sales-starter/skills/customer-health/SKILL.md +108 -0
  692. package/starter-packs/sales/Plugins/sales-starter/skills/customer-voice/SKILL.md +94 -0
  693. package/starter-packs/sales/Plugins/sales-starter/skills/daily-briefing/SKILL.md +61 -0
  694. package/starter-packs/sales/Plugins/sales-starter/skills/deal-advance-gap/SKILL.md +102 -0
  695. package/starter-packs/sales/Plugins/sales-starter/skills/deal-review/SKILL.md +105 -0
  696. package/starter-packs/sales/Plugins/sales-starter/skills/deal-signals/SKILL.md +96 -0
  697. package/starter-packs/sales/Plugins/sales-starter/skills/deal-slip-scenario/SKILL.md +104 -0
  698. package/starter-packs/sales/Plugins/sales-starter/skills/draft-outreach/SKILL.md +116 -0
  699. package/starter-packs/sales/Plugins/sales-starter/skills/end-of-day/SKILL.md +114 -0
  700. package/starter-packs/sales/Plugins/sales-starter/skills/expansion-whitespace/SKILL.md +97 -0
  701. package/starter-packs/sales/Plugins/sales-starter/skills/forecast/SKILL.md +100 -0
  702. package/starter-packs/sales/Plugins/sales-starter/skills/handle-objection/SKILL.md +93 -0
  703. package/starter-packs/sales/Plugins/sales-starter/skills/inbox-sweep/SKILL.md +114 -0
  704. package/starter-packs/sales/Plugins/sales-starter/skills/lead-triage/SKILL.md +106 -0
  705. package/starter-packs/sales/Plugins/sales-starter/skills/log-activity/SKILL.md +111 -0
  706. package/starter-packs/sales/Plugins/sales-starter/skills/pipeline-review/SKILL.md +97 -0
  707. package/starter-packs/sales/Plugins/sales-starter/skills/renewal-radar/SKILL.md +95 -0
  708. package/starter-packs/sales/Plugins/sales-starter/skills/rep-context/SKILL.md +90 -0
  709. package/starter-packs/sales/Plugins/sales-starter/skills/route-lead/SKILL.md +111 -0
  710. package/starter-packs/sales/Plugins/sales-starter/skills/sales-setup/SKILL.md +200 -0
  711. package/starter-packs/sales/Plugins/sales-starter/skills/schedule-meeting/SKILL.md +99 -0
  712. package/starter-packs/sales/Plugins/sales-starter/skills/stakeholder-map/SKILL.md +107 -0
  713. package/starter-packs/sales/Plugins/sales-starter/skills/team-pipeline/SKILL.md +105 -0
  714. package/starter-packs/sales/Plugins/sales-starter/skills/update-opportunity/SKILL.md +112 -0
  715. package/starter-packs/sales/Plugins/sales-starter/skills/weekly-wrap/SKILL.md +90 -0
  716. package/starter-packs/sales/Plugins/sales-starter/skills/win-loss-review/SKILL.md +88 -0
  717. package/starter-packs/sales/pack.yaml +13 -0
  718. package/starter-packs/support/KnowledgeBase/Escalations.md +9 -0
  719. package/starter-packs/support/KnowledgeBase/Glossary.md +9 -0
  720. package/starter-packs/support/KnowledgeBase/Known issues.md +9 -0
  721. package/starter-packs/support/KnowledgeBase/Products.md +9 -0
  722. package/starter-packs/support/KnowledgeBase/Tone of voice.md +9 -0
  723. package/starter-packs/support/Plugins/support-starter/LICENSE +202 -0
  724. package/starter-packs/support/Plugins/support-starter/SOURCE.md +10 -0
  725. package/starter-packs/support/Plugins/support-starter/access.md +19 -0
  726. package/starter-packs/support/Plugins/support-starter/plugin.json +10 -0
  727. package/starter-packs/support/Plugins/support-starter/skills/customer-escalation/SKILL.md +246 -0
  728. package/starter-packs/support/Plugins/support-starter/skills/customer-research/SKILL.md +250 -0
  729. package/starter-packs/support/Plugins/support-starter/skills/draft-response/SKILL.md +416 -0
  730. package/starter-packs/support/Plugins/support-starter/skills/kb-article/SKILL.md +350 -0
  731. package/starter-packs/support/Plugins/support-starter/skills/ticket-triage/SKILL.md +273 -0
  732. package/starter-packs/support/pack.yaml +12 -0
  733. package/kb-template/AGENTS.md +0 -730
@@ -0,0 +1,261 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { MOVE_LINK_EDIT_CAP, UNSEARCHED_SENTENCE, planMoveLinks, type MoveLinksInput } from '../move-links.js';
3
+
4
+ /**
5
+ * The plan `move_file` builds for its links: which pages it edits, which it
6
+ * names and leaves, and what it never discloses.
7
+ */
8
+
9
+ const KB = 'knowledge-base';
10
+
11
+ function inputOf(
12
+ files: Record<string, string>,
13
+ over: Partial<MoveLinksInput> = {},
14
+ ): MoveLinksInput & { reads: string[] } {
15
+ const reads: string[] = [];
16
+ return {
17
+ src: `${KB}/Old`,
18
+ dest: `${KB}/New/Old`,
19
+ branch: 'main',
20
+ kbDirName: KB,
21
+ allFiles: Object.keys(files),
22
+ canRead: async (paths) => new Map(paths.map((p) => [p, true])),
23
+ writeBlocked: async () => [],
24
+ readText: async (p) => {
25
+ reads.push(p);
26
+ return files[p];
27
+ },
28
+ readRefused: async () => false,
29
+ writeRefusal: async () => null,
30
+ reads,
31
+ ...over,
32
+ };
33
+ }
34
+
35
+ describe('planMoveLinks', () => {
36
+ it('edits inbound pages and moved pages, reporting each edit at the file’s new path', async () => {
37
+ const files = {
38
+ [`${KB}/Old/One.md`]: '---\nnodeType: "[T](../NodeTypes/Task.md)"\n---\n[two](Two.md)\n',
39
+ [`${KB}/Old/Two.md`]: 'no links\n',
40
+ [`${KB}/Index.md`]: '[one](Old/One.md) and [elsewhere](Other.md)\n',
41
+ [`${KB}/Unrelated.md`]: '[x](Other.md)\n',
42
+ [`${KB}/Old/pic.png`]: 'binary',
43
+ };
44
+ const input = inputOf(files);
45
+ const plan = await planMoveLinks(input);
46
+ expect(plan.report).toEqual({
47
+ filesEdited: 2,
48
+ linksRewritten: 2,
49
+ edits: [
50
+ { path: `${KB}/Index.md`, from: 'Old/One.md', to: 'New/Old/One.md' },
51
+ { path: `${KB}/New/Old/One.md`, from: '../NodeTypes/Task.md', to: '../../NodeTypes/Task.md' },
52
+ ],
53
+ notRewritten: [],
54
+ });
55
+ expect(plan.edits.map((e) => [e.lockAt, e.path])).toEqual([
56
+ [`${KB}/Index.md`, `${KB}/Index.md`],
57
+ [`${KB}/Old/One.md`, `${KB}/New/Old/One.md`],
58
+ ]);
59
+ // Binary files are never read.
60
+ expect(input.reads).not.toContain(`${KB}/Old/pic.png`);
61
+ });
62
+
63
+ it('a readable page the caller may not change is named with its links, and not edited', async () => {
64
+ const files = {
65
+ [`${KB}/Old/One.md`]: 'x\n',
66
+ [`${KB}/Locked/Page.md`]: '[one](../Old/One.md)\n',
67
+ };
68
+ const plan = await planMoveLinks(inputOf(files, { writeBlocked: async (paths) => paths.filter((p) => p.includes('Locked')) }));
69
+ expect(plan.edits).toEqual([]);
70
+ expect(plan.report.notRewritten).toEqual([
71
+ { path: `${KB}/Locked/Page.md`, reason: 'no write access', links: ['../Old/One.md'] },
72
+ ]);
73
+ });
74
+
75
+ it('a page the caller cannot read is never opened, named or counted — one sentence instead', async () => {
76
+ const files = {
77
+ [`${KB}/Old/One.md`]: 'x\n',
78
+ [`${KB}/Secret/A.md`]: '[one](../Old/One.md)\n',
79
+ [`${KB}/Secret/B.md`]: '[one](../Old/One.md)\n',
80
+ };
81
+ const input = inputOf(files, {
82
+ canRead: async (paths) => new Map(paths.map((p) => [p, !p.includes('Secret')])),
83
+ });
84
+ const plan = await planMoveLinks(input);
85
+ expect(input.reads.some((p) => p.includes('Secret'))).toBe(false);
86
+ expect(plan.report.unsearched).toBe(UNSEARCHED_SENTENCE);
87
+ expect(JSON.stringify(plan.report)).not.toMatch(/Secret|\b2\b/);
88
+ expect(plan.report.filesEdited).toBe(0);
89
+ });
90
+
91
+ it('transcripts/ and probes/ folders are never searched', async () => {
92
+ const files = {
93
+ [`${KB}/Old/One.md`]: 'x\n',
94
+ [`${KB}/T/transcripts/01.md`]: '[one](../../Old/One.md)\n',
95
+ [`${KB}/T/probes/p.md`]: '[one](../../Old/One.md)\n',
96
+ };
97
+ const input = inputOf(files);
98
+ const plan = await planMoveLinks(input);
99
+ expect(plan.report.filesEdited).toBe(0);
100
+ expect(input.reads.filter((p) => /transcripts|probes/.test(p))).toEqual([]);
101
+ });
102
+
103
+ it('an HTML page is reported, not rewritten', async () => {
104
+ const files = {
105
+ [`${KB}/Old/One.md`]: 'x\n',
106
+ [`${KB}/Board.html`]: '<a href="Old/One.md">one</a>',
107
+ };
108
+ const plan = await planMoveLinks(inputOf(files));
109
+ expect(plan.edits).toEqual([]);
110
+ expect(plan.report.notRewritten).toEqual([{ path: `${KB}/Board.html`, reason: 'html page', links: ['Old/One.md'] }]);
111
+ });
112
+
113
+ it('raw HTML inside a markdown page is reported, not rewritten — beside the markdown links that are', async () => {
114
+ const files = {
115
+ [`${KB}/Old/One.md`]: 'x\n',
116
+ [`${KB}/Old/pic.png`]: '',
117
+ // One markdown link, which is rewritten, and one raw `<img>`, which is not.
118
+ [`${KB}/Gallery.md`]: '[one](Old/One.md)\n\n<img src="Old/pic.png" alt="pic">\n',
119
+ // A page whose raw HTML points elsewhere is not named.
120
+ [`${KB}/Other.md`]: '<a href="Elsewhere.md">x</a> mentions Old in prose\n',
121
+ };
122
+ const plan = await planMoveLinks(inputOf(files));
123
+ expect(plan.edits.map((e) => e.path)).toEqual([`${KB}/Gallery.md`]);
124
+ expect(plan.edits[0].content).toBe('[one](New/Old/One.md)\n\n<img src="Old/pic.png" alt="pic">\n');
125
+ expect(plan.report.notRewritten).toEqual([
126
+ { path: `${KB}/Gallery.md`, reason: 'html in markdown', links: ['Old/pic.png'] },
127
+ ]);
128
+ });
129
+
130
+ it('raw HTML inside code or escaped — a fence, an indented block, a code span, a `\\<` — is an example, not reported', async () => {
131
+ const files = {
132
+ [`${KB}/Old/One.md`]: 'x\n',
133
+ [`${KB}/Howto.md`]:
134
+ 'Write it like `<a href="Old/One.md">` or \\<a href="Old/One.md"> or:\n\n```html\n<a href="Old/One.md">one</a>\n```\n\n' +
135
+ ' <img src="Old/One.md">\n\nAnd a live one: <a href="Old/One.md">one</a>\n',
136
+ };
137
+ const plan = await planMoveLinks(inputOf(files));
138
+ expect(plan.edits).toEqual([]);
139
+ expect(plan.report.notRewritten).toEqual([
140
+ { path: `${KB}/Howto.md`, reason: 'html in markdown', links: ['Old/One.md'] },
141
+ ]);
142
+ });
143
+
144
+ it(`more than ${MOVE_LINK_EDIT_CAP} edited files is refused, saying how to split or switch off`, async () => {
145
+ const files: Record<string, string> = { [`${KB}/Old/One.md`]: 'x\n' };
146
+ for (let i = 0; i <= MOVE_LINK_EDIT_CAP; i++) files[`${KB}/Pages/P${i}.md`] = '[one](../Old/One.md)\n';
147
+ const writeRefusal = vi.fn(async () => null);
148
+ const plan = await planMoveLinks(inputOf(files, { writeRefusal }));
149
+ expect(plan.overCap).toMatch(/201 files.*rewriteLinks: false/s);
150
+ expect(plan.overCap).toMatch(/subfolder/);
151
+ expect(plan.edits).toEqual([]);
152
+ // Nothing is edited, so the write hook hears of nothing.
153
+ expect(writeRefusal).not.toHaveBeenCalled();
154
+ // Exactly at the cap is allowed.
155
+ delete files[`${KB}/Pages/P0.md`];
156
+ expect((await planMoveLinks(inputOf(files))).overCap).toBeUndefined();
157
+ });
158
+
159
+ it('only edited files reach the hooks; a refusal leaves that file named and unedited', async () => {
160
+ const files = {
161
+ [`${KB}/Old/One.md`]: '[t](../T.md)\n',
162
+ [`${KB}/A.md`]: '[one](Old/One.md)\n',
163
+ [`${KB}/B.md`]: '[one](Old/One.md)\n',
164
+ [`${KB}/Searched.md`]: 'mentions Old but links nowhere\n',
165
+ };
166
+ const readRefused = vi.fn(async () => false);
167
+ const writeRefusal = vi.fn(async (_lockAt: string, path: string) =>
168
+ path.endsWith('B.md') ? 'refused: not in this session' : null);
169
+ const plan = await planMoveLinks(inputOf(files, { readRefused, writeRefusal }));
170
+ // The pages the answer names, and not the one merely searched.
171
+ expect(readRefused.mock.calls.map((c) => c[0]).sort()).toEqual([`${KB}/A.md`, `${KB}/B.md`, `${KB}/Old/One.md`]);
172
+ expect(writeRefusal.mock.calls.map((c) => c[0]).sort()).toEqual([`${KB}/A.md`, `${KB}/B.md`, `${KB}/Old/One.md`]);
173
+ expect(plan.edits.map((e) => e.path)).toEqual([`${KB}/A.md`, `${KB}/New/Old/One.md`]);
174
+ expect(plan.report.notRewritten).toEqual([{ path: `${KB}/B.md`, reason: 'refused: not in this session', links: ['Old/One.md'] }]);
175
+ });
176
+
177
+ it('a page the read hook refuses is treated as unreadable: never named, one sentence instead', async () => {
178
+ const files = {
179
+ [`${KB}/Old/One.md`]: 'x\n',
180
+ [`${KB}/Hidden.md`]: '[one](Old/One.md) [secret](Secret/Target.md)\n',
181
+ };
182
+ const plan = await planMoveLinks(inputOf(files, { readRefused: async () => true }));
183
+ expect(plan.edits).toEqual([]);
184
+ expect(plan.report.notRewritten).toEqual([]);
185
+ expect(plan.report.unsearched).toBe(UNSEARCHED_SENTENCE);
186
+ expect(JSON.stringify(plan.report)).not.toMatch(/Hidden|Secret|read denied/);
187
+ });
188
+
189
+ it('a page the read hook refuses is not named for its raw HTML, nor as one the caller may not change', async () => {
190
+ // Every way a page gets NAMED passes the same gate: an HTML page, raw
191
+ // HTML in a markdown page, and a page left unedited for want of write
192
+ // access are all pages the answer would quote links from.
193
+ const files = {
194
+ [`${KB}/Old/One.md`]: 'x\n',
195
+ [`${KB}/Board.html`]: '<a href="Old/One.md">one</a>',
196
+ [`${KB}/Gallery.md`]: '<img src="Old/One.md">\n',
197
+ [`${KB}/Locked.md`]: '[one](Old/One.md)\n',
198
+ [`${KB}/Shown.md`]: '[one](Old/One.md)\n',
199
+ };
200
+ const readRefused = vi.fn(async (path: string) => path !== `${KB}/Shown.md`);
201
+ const plan = await planMoveLinks(
202
+ inputOf(files, { readRefused, writeBlocked: async (paths) => paths.filter((p) => p.endsWith('Locked.md')) }),
203
+ );
204
+ expect(plan.edits.map((e) => e.path)).toEqual([`${KB}/Shown.md`]);
205
+ expect(plan.report.notRewritten).toEqual([]);
206
+ expect(plan.report.unsearched).toBe(UNSEARCHED_SENTENCE);
207
+ expect(JSON.stringify(plan.report)).not.toMatch(/Board|Gallery|Locked/);
208
+ // Asked once per page named, never for one merely searched — the moved
209
+ // file itself links nowhere, so it is not named and not asked about.
210
+ expect(readRefused.mock.calls.map((c) => c[0]).sort()).toEqual([
211
+ `${KB}/Board.html`,
212
+ `${KB}/Gallery.md`,
213
+ `${KB}/Locked.md`,
214
+ `${KB}/Shown.md`,
215
+ ]);
216
+ });
217
+
218
+ it('a link spelling the moved name with percent-encoding or escapes is still found', async () => {
219
+ const files = {
220
+ [`${KB}/My Old (1)/One.md`]: 'x\n',
221
+ [`${KB}/Lower.md`]: '[one](My%20Old%20%281%29/One.md)\n',
222
+ [`${KB}/Partial.md`]: '[one](My%20Old%20(1)/One.md)\n',
223
+ [`${KB}/Escaped.md`]: '[one](My%20Old%20\\(1\\)/One.md)\n',
224
+ [`${KB}/Mixed.md`]: '[one](%4dy%20Old%20%281%29/One.md)\n',
225
+ };
226
+ const plan = await planMoveLinks(inputOf(files, { src: `${KB}/My Old (1)`, dest: `${KB}/New/My Old (1)` }));
227
+ expect(plan.edits.map((e) => e.path).sort()).toEqual([`${KB}/Escaped.md`, `${KB}/Lower.md`, `${KB}/Mixed.md`, `${KB}/Partial.md`]);
228
+ });
229
+
230
+ it('a page gone between the listing and its read is skipped; one that cannot be opened marks the search incomplete', async () => {
231
+ const files = {
232
+ [`${KB}/Old/One.md`]: 'x\n',
233
+ [`${KB}/Gone.md`]: '[one](Old/One.md)\n',
234
+ [`${KB}/Index.md`]: '[one](Old/One.md)\n',
235
+ };
236
+ const failWith = (code: string) => async (p: string) => {
237
+ if (p.endsWith('Gone.md')) throw Object.assign(new Error(code), { code });
238
+ return files[p as keyof typeof files];
239
+ };
240
+ const gone = await planMoveLinks(inputOf(files, { readText: failWith('ENOENT') }));
241
+ expect(gone.edits.map((e) => e.path)).toEqual([`${KB}/Index.md`]);
242
+ expect(gone.report.unsearched).toBeUndefined();
243
+ // Its folder became a file: gone all the same.
244
+ const folderGone = await planMoveLinks(inputOf(files, { readText: failWith('ENOTDIR') }));
245
+ expect(folderGone.edits.map((e) => e.path)).toEqual([`${KB}/Index.md`]);
246
+ expect(folderGone.report.unsearched).toBeUndefined();
247
+ const denied = await planMoveLinks(inputOf(files, { readText: failWith('EACCES') }));
248
+ expect(denied.edits.map((e) => e.path)).toEqual([`${KB}/Index.md`]);
249
+ expect(denied.report.unsearched).toBe(UNSEARCHED_SENTENCE);
250
+ expect(JSON.stringify(denied.report)).not.toMatch(/Gone/);
251
+ });
252
+
253
+ it('lists at most 100 edits while counting all of them', async () => {
254
+ const files: Record<string, string> = { [`${KB}/Old/One.md`]: 'x\n' };
255
+ for (let i = 0; i < 60; i++) files[`${KB}/Pages/P${i}.md`] = '[a](../Old/One.md) [b](../Old/One.md#x)\n';
256
+ const plan = await planMoveLinks(inputOf(files));
257
+ expect(plan.report.filesEdited).toBe(60);
258
+ expect(plan.report.linksRewritten).toBe(120);
259
+ expect(plan.report.edits).toHaveLength(100);
260
+ });
261
+ });
@@ -0,0 +1,219 @@
1
+ import type { Server as HttpServer } from 'node:http';
2
+ import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { dirname, join } from 'node:path';
5
+ import express from 'express';
6
+ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
7
+ import { LocalFilesystem } from '@mastra/core/workspace';
8
+ import { testKbContext } from '../../../__tests__/kb-context.js';
9
+ import { ToolRegistry } from '../../tool-registry/tool-registry.js';
10
+ import { createToolHandlerFactory } from '../../tool-helpers/tool-handler.js';
11
+ import { routeToolSchemas } from '../../tool-helpers/route-tool-schemas.js';
12
+ import type { ToolContext } from '../../tool-helpers/tool.contract.js';
13
+ import type { ToolAuth } from '../../tool-auth/tool-auth.middleware.js';
14
+ import { registerWorkspaceTools } from '../workspace.tools.js';
15
+ import { RoutineWritePolicyService } from '../routine-write-policy.js';
16
+ import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
17
+ import { ToolDescriptionNotes } from '../agent-access.gate.js';
18
+ import { SpillStore } from '../spill-store.js';
19
+ import { DocExtractService } from '../file-readers/doc-extract.service.js';
20
+ import { AccessControlService } from '../../access/access-control.service.js';
21
+ import { NodeFs } from '../../kb-fs/node-fs.js';
22
+ import { BRANCH_REQUIRED_MESSAGE } from '../../../shared/domain-errors.js';
23
+ import { callLine, compileCheck, exampleArguments } from '@bevel-software/platform-mcp-core';
24
+
25
+ /**
26
+ * The REST route a script, a runner or a CI job calls with a connection key —
27
+ * `POST /api/agent/tools/<name>` — driven against the REAL workspace tools.
28
+ *
29
+ * This is the surface the first implementation left unprotected: `write_file`
30
+ * without `content` answered a 500 `TypeError`, `move_file` without `dest` the
31
+ * same, and `grep` without `pattern` answered 200 having matched every file in
32
+ * the knowledge base. The three calls the ticket names are here, with their own
33
+ * schemas and their own route handlers, so the refusal under test is the one a
34
+ * caller really gets.
35
+ */
36
+
37
+ const KB = 'knowledge-base';
38
+ const BRANCH = 'main';
39
+
40
+ const TREE: Record<string, string> = {
41
+ 'roles.yaml': 'roles:\n Admin:\n - author@x.io\n',
42
+ 'access.md': '---\nread:\n - everyone\nwrite:\n - everyone\n---\n',
43
+ 'KnowledgeBase/Note.md': '# Note\n\nthe needle is here\n',
44
+ 'KnowledgeBase/Other.md': '# Other\n\nthe needle is here too\n',
45
+ };
46
+
47
+ let root = '';
48
+ let docCache = '';
49
+ let base = '';
50
+ let server: HttpServer;
51
+
52
+ beforeAll(async () => {
53
+ root = await mkdtemp(join(tmpdir(), 'rest-tool-arguments-'));
54
+ for (const [rel, text] of Object.entries(TREE)) {
55
+ const abs = join(root, KB, rel);
56
+ await mkdir(dirname(abs), { recursive: true });
57
+ await writeFile(abs, text);
58
+ }
59
+ const workspaceService = {
60
+ getWorkspacePath: async () => root,
61
+ ensureRemotesFetched: async () => undefined,
62
+ } as unknown as Parameters<typeof AccessControlService.prototype.constructor>[0];
63
+ const access = new AccessControlService(workspaceService as never, KB, new NodeFs());
64
+ const fs = new LocalFilesystem({ basePath: root, contained: true });
65
+ const resolve = async (auth: ToolAuth, signal: AbortSignal): Promise<ToolContext> =>
66
+ ({
67
+ user: { id: 'u', email: 'author@x.io', name: 'Author' },
68
+ scope: auth.scope,
69
+ source: auth.source,
70
+ abortSignal: signal,
71
+ workspaceService: workspaceService as never,
72
+ workflowService: {} as never,
73
+ events: {} as never,
74
+ getFilesystem: async () => fs,
75
+ }) as unknown as ToolContext;
76
+ const app = express();
77
+ app.use(express.json());
78
+ const router = express.Router();
79
+ docCache = await mkdtemp(join(tmpdir(), 'rest-tool-arguments-doc-'));
80
+ registerWorkspaceTools(
81
+ new ToolRegistry(),
82
+ router,
83
+ (req, _res, next) => {
84
+ req.toolAuth = { source: 'external', userId: 'u', scope: 'write' };
85
+ next();
86
+ },
87
+ createToolHandlerFactory(resolve),
88
+ new SpillStore(join(tmpdir(), 'bevel-test-spills')),
89
+ new DocExtractService(docCache),
90
+ access,
91
+ testKbContext({ kbDirName: KB }),
92
+ { recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks(), notes: new ToolDescriptionNotes() },
93
+ new RoutineWritePolicyService(),
94
+ {} as never,
95
+ );
96
+ app.use('/api', router);
97
+ server = await new Promise<HttpServer>((r) => {
98
+ const s = app.listen(0, () => r(s));
99
+ });
100
+ base = `http://127.0.0.1:${(server.address() as { port: number }).port}`;
101
+ });
102
+
103
+ afterAll(async () => {
104
+ await new Promise<void>((r) => server.close(() => r()));
105
+ await rm(root, { recursive: true, force: true });
106
+ await rm(docCache, { recursive: true, force: true });
107
+ });
108
+
109
+ interface Answered {
110
+ status: number;
111
+ body: { error?: string; kind?: string; matches?: unknown[]; truncated?: boolean };
112
+ }
113
+
114
+ /** One call on the REST route, exactly as a script with a connection key makes it. */
115
+ async function callTool(tool: string, body: unknown): Promise<Answered> {
116
+ const res = await fetch(`${base}/api/agent/tools/${tool}`, {
117
+ method: 'POST',
118
+ headers: { 'content-type': 'application/json', authorization: 'Bearer connection-key' },
119
+ body: JSON.stringify(body),
120
+ });
121
+ return { status: res.status, body: (await res.json()) as Answered['body'] };
122
+ }
123
+
124
+ const exists = (rel: string) =>
125
+ stat(join(root, rel))
126
+ .then(() => true)
127
+ .catch(() => false);
128
+
129
+ describe('POST /api/agent/tools/<name> checks the arguments against the tool', () => {
130
+ it('refuses write_file without `content` — the 400 with the interface, not a 500, and writes nothing', async () => {
131
+ const { status, body } = await callTool('write_file', {
132
+ branch: BRANCH,
133
+ path: `${KB}/KnowledgeBase/New.md`,
134
+ sessionId: 's-1',
135
+ });
136
+ expect(status).toBe(400);
137
+ expect(body.kind).toBe('arguments-do-not-match');
138
+ expect(body.error).toContain('The arguments do not match the "write_file" tool.');
139
+ expect(body.error).toContain('"content" is required, and was not given.');
140
+ expect(body.error).toContain('Interface of "write_file":');
141
+ expect(body.error).toContain('content (string, required)');
142
+ expect(body.error).toContain('path (string, required)');
143
+ expect(body.error?.split('\n').pop()).toBe(
144
+ callLine('KNOWLEDGE_BASE.write_file', routeToolSchemas('write_file')!.wire),
145
+ );
146
+ // The call ran nothing: no file was created.
147
+ expect(await exists(`${KB}/KnowledgeBase/New.md`)).toBe(false);
148
+ });
149
+
150
+ it('refuses move_file without `dest`, and moves nothing', async () => {
151
+ const { status, body } = await callTool('move_file', {
152
+ branch: BRANCH,
153
+ src: `${KB}/KnowledgeBase/Note.md`,
154
+ });
155
+ expect(status).toBe(400);
156
+ expect(body.kind).toBe('arguments-do-not-match');
157
+ expect(body.error).toContain('"dest" is required, and was not given.');
158
+ expect(body.error).toContain('dest (string, required)');
159
+ expect(await readFile(join(root, KB, 'KnowledgeBase/Note.md'), 'utf8')).toContain('the needle is here');
160
+ });
161
+
162
+ it('refuses grep without `pattern`, and searches nothing', async () => {
163
+ const { status, body } = await callTool('grep', { branch: BRANCH });
164
+ expect(status).toBe(400);
165
+ expect(body.kind).toBe('arguments-do-not-match');
166
+ expect(body.error).toContain('"pattern" is required, and was not given.');
167
+ expect(body.error).toContain('pattern (string, required) — JavaScript regular expression.');
168
+ // Not a 200 that matched every file, which is what this surface answered
169
+ // before the check lived in the route.
170
+ expect(body.matches).toBeUndefined();
171
+ });
172
+
173
+ it('names an argument of the wrong type, and one the tool does not have', async () => {
174
+ const wrongType = await callTool('grep', { branch: BRANCH, pattern: 'needle', max_results: 'ten' });
175
+ expect(wrongType.status).toBe(400);
176
+ expect(wrongType.body.error).toContain('"max_results" must be integer, but string was given.');
177
+ const unknown = await callTool('grep', { branch: BRANCH, pattern: 'needle', recursive: true });
178
+ expect(unknown.status).toBe(400);
179
+ expect(unknown.body.error).toContain('"recursive" is not an argument of this tool.');
180
+ });
181
+
182
+ it('keeps the refusal that names a missing branch, word for word', async () => {
183
+ const { status, body } = await callTool('read_file', { path: `${KB}/KnowledgeBase/Note.md` });
184
+ expect(status).toBe(400);
185
+ expect(body.kind).toBe('branch-required');
186
+ expect(body.error).toBe(BRANCH_REQUIRED_MESSAGE);
187
+ });
188
+
189
+ it('passes a matching call on with exactly the arguments that were sent', async () => {
190
+ const { status, body } = await callTool('grep', {
191
+ branch: BRANCH,
192
+ pattern: 'needle',
193
+ path: `${KB}/KnowledgeBase`,
194
+ max_results: 1,
195
+ });
196
+ expect(status).toBe(200);
197
+ // `max_results: 1` was honoured, so the argument reached the tool as sent —
198
+ // the check neither dropped it nor rewrote it.
199
+ expect(body.matches).toHaveLength(1);
200
+ expect(body.truncated).toBe(true);
201
+ });
202
+
203
+ it('every mounted tool can be called with its own generated example', async () => {
204
+ const names = ['read_file', 'write_file', 'move_file', 'grep', 'list_files'];
205
+ for (const name of names) {
206
+ const schemas = routeToolSchemas(name);
207
+ expect(schemas, name).toBeDefined();
208
+ // The example an agent is told to copy is generated from the WIRE schema;
209
+ // what its route checks is the FLAT one. Both must accept it, or the
210
+ // platform publishes an example its own check refuses.
211
+ const flat = compileCheck(schemas!.flat);
212
+ expect(flat.checkable, name).toBe(true);
213
+ if (flat.checkable) expect(flat.check(exampleArguments(schemas!.flat)), name).toEqual([]);
214
+ const wire = compileCheck(schemas!.wire);
215
+ expect(wire.checkable, name).toBe(true);
216
+ if (wire.checkable) expect(wire.check(exampleArguments(schemas!.wire)), name).toEqual([]);
217
+ }
218
+ });
219
+ });
@@ -70,6 +70,9 @@ async function makeHarness(): Promise<Harness> {
70
70
  asked.push(p);
71
71
  return true;
72
72
  },
73
+ // Each file of a zipped folder is judged too; this suite is about where
74
+ // the FOLDER is placed, so the files all pass.
75
+ canDownloadBatch: async (_w: string, _e: string, paths: string[]) => new Map(paths.map((p) => [p, true])),
73
76
  } as unknown as IAccessControl;
74
77
 
75
78
  const locked: string[] = [];
@@ -15,6 +15,7 @@ import type { IAdminAccessService } from '../../admin/admin.interface.js';
15
15
  import { createWorkspaceRoutes } from '../workspace.routes.js';
16
16
  import type { ICreatorAccess } from '../../access-model/creator.js';
17
17
  import type { WorkspaceService } from '../workspace.service.js';
18
+ import { AccessDeniedError } from '../../access-model/access-errors.js';
18
19
 
19
20
  const stubCreatorAccess: ICreatorAccess = {
20
21
  planForCreate: async () => null,
@@ -46,6 +47,8 @@ interface Harness {
46
47
  repoDir: string;
47
48
  /** Exposed so a test can assert the PATH the route handed the service. */
48
49
  deleteFileMock: ReturnType<typeof vi.fn>;
50
+ /** Exposed so a test can make the write gate inside it refuse. */
51
+ acquireLockMock: ReturnType<typeof vi.fn>;
49
52
  }
50
53
 
51
54
  async function makeHarness(): Promise<Harness> {
@@ -125,6 +128,7 @@ async function makeHarness(): Promise<Harness> {
125
128
  workspaceDir,
126
129
  repoDir: path.join(workspaceDir, KB),
127
130
  deleteFileMock: workspaceServiceMock.deleteFile as unknown as ReturnType<typeof vi.fn>,
131
+ acquireLockMock: workflowServiceMock.acquireLock as unknown as ReturnType<typeof vi.fn>,
128
132
  };
129
133
  }
130
134
 
@@ -218,3 +222,101 @@ describe('DELETE /workspace/:id/file — one file identity', () => {
218
222
  }
219
223
  });
220
224
  });
225
+
226
+ /**
227
+ * The root's `access.md` and `roles.yaml` govern the whole repository, so the
228
+ * app's delete route refuses them — with the sentence `delete_file` and the
229
+ * explorer use — before a lock is taken. A nested `access.md` is a file like
230
+ * any other here: the lock gate decides whether the caller may write it.
231
+ */
232
+ describe('DELETE /workspace/:id/file — the repository\'s own files', () => {
233
+ let h: Harness | null = null;
234
+ afterEach(async () => {
235
+ if (h) {
236
+ await closeServer(h.server);
237
+ await fs.rm(h.workspaceDir, { recursive: true, force: true });
238
+ }
239
+ h = null;
240
+ });
241
+
242
+ const del = (base: string, p: string) =>
243
+ fetch(`${base}/api/workspace/${WORKSPACE_ID}/file?path=${encodeURIComponent(p)}`, { method: 'DELETE' });
244
+
245
+ it.each(['access.md', 'roles.yaml'])('refuses the root %s with one sentence and leaves it', async (name) => {
246
+ h = await makeHarness();
247
+ await fs.mkdir(h.repoDir, { recursive: true });
248
+ await fs.writeFile(path.join(h.repoDir, name), 'x', 'utf-8');
249
+
250
+ const res = await del(h.baseUrl, name);
251
+
252
+ expect(res.status).toBe(409);
253
+ expect(await res.json()).toEqual({ error: `${name} is the repository's own file and cannot be deleted.` });
254
+ expect(h.deleteFileMock).not.toHaveBeenCalled();
255
+ expect(await exists(path.join(h.repoDir, name))).toBe(true);
256
+ });
257
+
258
+ it('deletes a nested access.md like any file, and a nested roles.yaml too', async () => {
259
+ h = await makeHarness();
260
+ await fs.mkdir(path.join(h.repoDir, 'Team'), { recursive: true });
261
+ await fs.writeFile(path.join(h.repoDir, 'Team/access.md'), '---\nread: Admin\n---\n', 'utf-8');
262
+ await fs.writeFile(path.join(h.repoDir, 'Team/roles.yaml'), 'content', 'utf-8');
263
+ // Not emptied by these deletes, so no placeholder needs keeping.
264
+ await fs.writeFile(path.join(h.repoDir, 'Team/notes.md'), 'n', 'utf-8');
265
+
266
+ for (const p of ['Team/access.md', 'Team/roles.yaml']) {
267
+ const res = await del(h.baseUrl, p);
268
+ expect(res.status).toBe(200);
269
+ expect(h.deleteFileMock).toHaveBeenCalledWith(WORKSPACE_ID, `${KB}/${p}`);
270
+ expect(await exists(path.join(h.repoDir, p))).toBe(false);
271
+ }
272
+ });
273
+
274
+ it('refuses a nested access.md with the ordinary write refusal when the caller may not write it', async () => {
275
+ h = await makeHarness();
276
+ await fs.mkdir(path.join(h.repoDir, 'Team'), { recursive: true });
277
+ await fs.writeFile(path.join(h.repoDir, 'Team/access.md'), '---\nwrite: Admin\n---\n', 'utf-8');
278
+ // The write gate lives inside `acquireLock`; it refuses as it does for any file.
279
+ const refusal = new AccessDeniedError({ path: 'Team/access.md', eligibleRoles: ['Admin'], eligibleUsers: [] });
280
+ h.acquireLockMock.mockRejectedValueOnce(refusal);
281
+
282
+ const res = await del(h.baseUrl, 'Team/access.md');
283
+
284
+ expect(res.status).toBe(403);
285
+ const body = (await res.json()) as { error: string };
286
+ expect(body.error).toBe(refusal.message);
287
+ expect(body.error).not.toContain('platform file');
288
+ expect(body.error).not.toContain("repository's own file");
289
+ expect(h.deleteFileMock).not.toHaveBeenCalled();
290
+ expect(await exists(path.join(h.repoDir, 'Team/access.md'))).toBe(true);
291
+ });
292
+
293
+ it('refuses a reserved top-level folder as delete_folder does, and leaves what it holds', async () => {
294
+ h = await makeHarness();
295
+ await fs.mkdir(path.join(h.repoDir, 'KnowledgeBase/Product'), { recursive: true });
296
+ await fs.writeFile(path.join(h.repoDir, 'KnowledgeBase/Product/Plan.md'), 'p', 'utf-8');
297
+
298
+ const res = await del(h.baseUrl, `${KB}/KnowledgeBase`);
299
+
300
+ expect(res.status).toBe(409);
301
+ expect(await res.json()).toEqual({ error: 'KnowledgeBase/ is a platform folder and cannot be moved or deleted.' });
302
+ expect(h.deleteFileMock).not.toHaveBeenCalled();
303
+ expect(await exists(path.join(h.repoDir, 'KnowledgeBase/Product/Plan.md'))).toBe(true);
304
+ });
305
+
306
+ it.each([KB, `${KB}/`])('refuses the repository root as a folder (%j) and leaves its own files', async (p) => {
307
+ h = await makeHarness();
308
+ await fs.mkdir(path.join(h.repoDir, 'Team'), { recursive: true });
309
+ await fs.writeFile(path.join(h.repoDir, 'access.md'), 'x', 'utf-8');
310
+ await fs.writeFile(path.join(h.repoDir, 'roles.yaml'), 'x', 'utf-8');
311
+ await fs.writeFile(path.join(h.repoDir, 'Team/notes.md'), 'n', 'utf-8');
312
+
313
+ const res = await del(h.baseUrl, p);
314
+
315
+ expect(res.status).toBe(409);
316
+ expect(await res.json()).toEqual({ error: 'The repository root is a platform folder and cannot be moved or deleted.' });
317
+ expect(h.deleteFileMock).not.toHaveBeenCalled();
318
+ for (const f of ['access.md', 'roles.yaml', 'Team/notes.md']) {
319
+ expect(await exists(path.join(h.repoDir, f))).toBe(true);
320
+ }
321
+ });
322
+ });