@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
@@ -11,9 +11,16 @@ import type { IReviewWorkflowService } from '../review-workflow/review-workflow.
11
11
  import type { WorkspaceService } from '../../workspace/workspace.service.js';
12
12
  import type { IAccessControl } from '../../access/access-control.interface.js';
13
13
  import { FileLockService } from '../file-lock.service.js';
14
- import { PendingCommitsService } from '../pending-commits.service.js';
14
+ import { PendingCommitsService, type PendingCommit } from '../pending-commits.service.js';
15
+ import { PendingCommitsWorker } from '../pending-commits.worker.js';
16
+ import { HttpCommunicationProtocol } from '@utcp/http';
15
17
  import { WorkflowService } from '../workflow.service.js';
16
- import { PullRebaseConflictError, WorkflowDomainError } from '../../../shared/domain-errors.js';
18
+ import {
19
+ PullRebaseConflictError,
20
+ PushNeedsAgentResolutionError,
21
+ WorkflowDomainError,
22
+ } from '../../../shared/domain-errors.js';
23
+ import type { WorkflowEventBus } from '../event-bus.js';
17
24
  import { DEFAULT_BRANCH } from '@bevel-software/platform-shared';
18
25
  import type { Database } from '../../database/connection.js';
19
26
  import { openChangeGate } from '../../../__tests__/open-change-gate.js';
@@ -121,6 +128,7 @@ function makePendingCommits(): PendingCommitsService {
121
128
  markNeedsAttention: vi.fn().mockResolvedValue(undefined),
122
129
  listNeedsAttention: vi.fn().mockResolvedValue([]),
123
130
  countPending: vi.fn().mockResolvedValue(0),
131
+ queuedOnBranch: vi.fn().mockResolvedValue({ queued: 0, stuck: 0, needsAttention: null }),
124
132
  hasAnyForWorkspace: vi.fn().mockResolvedValue(false),
125
133
  startupReconcile: vi.fn().mockResolvedValue(undefined),
126
134
  } as unknown as PendingCommitsService;
@@ -182,7 +190,7 @@ function makeGit(): GitService {
182
190
  listBranches: vi.fn(),
183
191
  createBranch: vi.fn(),
184
192
  switchBranch: vi.fn(),
185
- deleteBranch: vi.fn(),
193
+ deleteBranch: vi.fn(async () => ({ lastCommit: null })),
186
194
  forkCurrentToDraft: vi.fn(),
187
195
  discardChanges: vi.fn(),
188
196
  commit: vi.fn(),
@@ -529,8 +537,8 @@ describe('WorkflowService — file lock delegation', () => {
529
537
  let releaseFirst!: () => void;
530
538
  const gate = new Promise<void>((resolve) => { releaseFirst = resolve; });
531
539
  vi.mocked(git.deleteBranch)
532
- .mockImplementationOnce(async () => { order.push('first:start'); await gate; order.push('first:end'); })
533
- .mockImplementationOnce(async () => { order.push('second'); });
540
+ .mockImplementationOnce(async () => { order.push('first:start'); await gate; order.push('first:end'); return { lastCommit: null }; })
541
+ .mockImplementationOnce(async () => { order.push('second'); return { lastCommit: null }; });
534
542
  const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
535
543
  const first = svc.deleteBranch('w1', 'feat/x', makeUser());
536
544
  const second = svc.deleteBranch('w1', 'feat/x', makeUser());
@@ -581,6 +589,7 @@ describe('WorkflowService — revertChangeRequestFile / closeEmptyChangeRequest'
581
589
  canWriteAtRef?: boolean | null;
582
590
  prState?: string;
583
591
  updateRows?: unknown[];
592
+ events?: WorkflowEventBus;
584
593
  } = {}) {
585
594
  const git = opts.git ?? makeRevertGit();
586
595
  const prs = makePrs();
@@ -607,7 +616,7 @@ describe('WorkflowService — revertChangeRequestFile / closeEmptyChangeRequest'
607
616
  returning: vi.fn(async () => updateRows),
608
617
  });
609
618
  const db = chain as unknown as Database;
610
- const svc = new WorkflowService(db, git, prs, makeReviewWorkflow(), makeWorkspaceService(), access, fileLocks, makePendingCommits(), testKbContext(), openChangeGate());
619
+ const svc = new WorkflowService(db, git, prs, makeReviewWorkflow(), makeWorkspaceService(), access, fileLocks, makePendingCommits(), testKbContext(), openChangeGate(), opts.events);
611
620
  return { svc, git, prs, access, fileLocks, db: chain };
612
621
  }
613
622
 
@@ -744,6 +753,130 @@ describe('WorkflowService — revertChangeRequestFile / closeEmptyChangeRequest'
744
753
  expect(fileLocks.release).toHaveBeenCalledTimes(2);
745
754
  });
746
755
 
756
+ describe('when the repository host refuses the push', () => {
757
+ // What GitHub answered during its 2026-10-07 incident, credential and all.
758
+ const REFUSED = new Error(
759
+ "git push failed: remote: Internal Server Error\nTo https://x-access-token:ghp_abc123@github.com/acme/kb.git\n ! [remote rejected] ali/x -> ali/x (Internal Server Error)",
760
+ );
761
+ const kindsOf = (emit: ReturnType<typeof vi.fn>) =>
762
+ emit.mock.calls
763
+ .map((c) => (c[0] as { kind: string }).kind)
764
+ .filter((k) => k.startsWith('git-sync-'));
765
+
766
+ it('keeps the revert committed locally, answers 409 with the saved-locally sentence, and raises the banner', async () => {
767
+ const emit = vi.fn();
768
+ const git = makeRevertGit({
769
+ push: vi.fn().mockRejectedValue(REFUSED),
770
+ // A refused push is not a divergence — but "rejected" reads like one,
771
+ // so the cooperative pull runs first; it changes nothing here.
772
+ pull: vi.fn().mockResolvedValue({ treeChanged: false }),
773
+ });
774
+ const { svc, fileLocks, prs, db } = makeHarness({ git, events: { emit } as unknown as WorkflowEventBus });
775
+
776
+ const err = await svc.revertChangeRequestFile(7, makeUser(), 'Docs/a.md').catch((e: unknown) => e);
777
+ expect(err).toBeInstanceOf(PushNeedsAgentResolutionError);
778
+ const refusal = err as PushNeedsAgentResolutionError;
779
+ expect(refusal.status).toBe(409);
780
+ expect(refusal.message).toContain('Saved locally on "ali/x"');
781
+ expect(refusal.message).toContain('the repository host refused the push');
782
+ // The browser receives message + payload: neither carries git output.
783
+ const body = JSON.stringify({ ...refusal.payload, error: refusal.message });
784
+ expect(body).not.toMatch(/Internal Server Error|remote rejected|ghp_|github\.com/);
785
+
786
+ // The local result stays: restored, committed, locks dropped, caches fresh.
787
+ expect(git.restorePathFromRef).toHaveBeenCalledWith('ali%2Fx', 'mb-sha', 'Docs/a.md');
788
+ expect(git.commitFile).toHaveBeenCalled();
789
+ expect(fileLocks.release).toHaveBeenCalled();
790
+ expect(prs.invalidateDetailCache).toHaveBeenCalledWith(7);
791
+ // Nothing is closed on the strength of a branch the host never received:
792
+ // the remaining files (read from the published refs) are not even asked.
793
+ expect(git.changedPathsForPr).toHaveBeenCalledTimes(1);
794
+ // Nor is a recorded apply failure erased: the published head it
795
+ // describes did not move.
796
+ expect(db.update).not.toHaveBeenCalled();
797
+
798
+ // The banner, on the request's source branch, in words — not git's.
799
+ const failed = emit.mock.calls.map((c) => c[0] as Record<string, unknown>).find((e) => e.kind === 'git-sync-failed');
800
+ expect(failed).toMatchObject({ workspaceId: 'ali/x', branch: 'ali/x' });
801
+ expect(String(failed?.reason)).not.toMatch(/Internal Server Error|remote|ghp_/);
802
+ });
803
+
804
+ it('clears the banner on the next push of that branch that lands', async () => {
805
+ const emit = vi.fn();
806
+ const push = vi.fn().mockRejectedValueOnce(REFUSED).mockRejectedValueOnce(REFUSED).mockResolvedValue(undefined);
807
+ const git = makeRevertGit({ push, pull: vi.fn().mockResolvedValue({ treeChanged: false }) });
808
+ const { svc } = makeHarness({ git, events: { emit } as unknown as WorkflowEventBus });
809
+
810
+ await expect(svc.revertChangeRequestFile(7, makeUser(), 'Docs/a.md')).rejects.toBeInstanceOf(
811
+ PushNeedsAgentResolutionError,
812
+ );
813
+ // The host is back; the next push of the branch carries the revert.
814
+ await svc.shareCurrentBranch('ali%2Fx', makeUser());
815
+ expect(kindsOf(emit)).toEqual(['git-sync-failed', 'git-sync-recovered']);
816
+ expect(emit).toHaveBeenLastCalledWith(
817
+ expect.objectContaining({ kind: 'git-sync-recovered', workspaceId: 'ali/x' }),
818
+ );
819
+ });
820
+
821
+ it('a divergence whose retry push the host then refuses is answered as a refusal, not a divergence', async () => {
822
+ const push = vi
823
+ .fn()
824
+ .mockRejectedValueOnce(new Error('! [rejected] ali/x -> ali/x (non-fast-forward)'))
825
+ .mockRejectedValueOnce(REFUSED);
826
+ const git = makeRevertGit({ push, pull: vi.fn().mockResolvedValue({ treeChanged: true }) });
827
+ const { svc } = makeHarness({ git });
828
+
829
+ const err = await svc.revertChangeRequestFile(7, makeUser(), 'Docs/a.md').catch((e: unknown) => e);
830
+ expect(err).toBeInstanceOf(PushNeedsAgentResolutionError);
831
+ expect((err as PushNeedsAgentResolutionError).message).toContain('the repository host refused the push');
832
+ expect(push).toHaveBeenCalledTimes(2);
833
+ });
834
+
835
+ it('a recovery whose PULL the host refuses says the credentials cannot reach the repository, not "push"', async () => {
836
+ const emit = vi.fn();
837
+ const push = vi.fn().mockRejectedValue(new Error('! [rejected] ali/x -> ali/x (non-fast-forward)'));
838
+ const pull = vi
839
+ .fn()
840
+ // The freshen pull is best-effort; the recovery pull is the one that counts.
841
+ .mockResolvedValueOnce({ treeChanged: false })
842
+ .mockRejectedValue(
843
+ new Error("fatal: unable to access 'https://github.com/acme/kb.git/': The requested URL returned error: 403"),
844
+ );
845
+ const git = makeRevertGit({ push, pull });
846
+ const { svc } = makeHarness({ git, events: { emit } as unknown as WorkflowEventBus });
847
+
848
+ await expect(svc.revertChangeRequestFile(7, makeUser(), 'Docs/a.md')).rejects.toBeInstanceOf(
849
+ PushNeedsAgentResolutionError,
850
+ );
851
+ const failed = emit.mock.calls.map((c) => c[0] as Record<string, unknown>).find((e) => e.kind === 'git-sync-failed');
852
+ expect(failed?.reason).toBe(
853
+ "The repository host did not give this server's credentials access to this repository.",
854
+ );
855
+ expect(push).toHaveBeenCalledTimes(1);
856
+ });
857
+
858
+ it('a non-fast-forward still takes the cooperative pull-rebase, then lands', async () => {
859
+ const emit = vi.fn();
860
+ const push = vi
861
+ .fn()
862
+ .mockRejectedValueOnce(new Error('! [rejected] ali/x -> ali/x (non-fast-forward)'))
863
+ .mockResolvedValue(undefined);
864
+ const pull = vi.fn().mockResolvedValue({ treeChanged: true });
865
+ const git = makeRevertGit({ push, pull });
866
+ const { svc } = makeHarness({ git, events: { emit } as unknown as WorkflowEventBus });
867
+
868
+ await expect(svc.revertChangeRequestFile(7, makeUser(), 'Docs/a.md')).resolves.toMatchObject({ closed: false });
869
+ expect(push).toHaveBeenCalledTimes(2);
870
+ // Once to freshen the checkout, once as the cooperative recovery —
871
+ // both replay merges as merges, so a merge a refused open or update
872
+ // stranded on the branch is not flattened before this push publishes it.
873
+ expect(pull).toHaveBeenCalledTimes(2);
874
+ expect(pull).toHaveBeenNthCalledWith(1, 'ali%2Fx', { preserveMerges: true });
875
+ expect(pull).toHaveBeenNthCalledWith(2, 'ali%2Fx', { preserveMerges: true });
876
+ expect(kindsOf(emit)).not.toContain('git-sync-failed');
877
+ });
878
+ });
879
+
747
880
  it('never reverts a placeholder when that would leave the folder with nothing', async () => {
748
881
  const git = makeRevertGit({
749
882
  changedPathsForPr: vi
@@ -1019,7 +1152,7 @@ describe('WorkflowService.mergeBranch — an agent merges branches, never an ope
1019
1152
  // being published.
1020
1153
  const TARGET_TIP = 'target-tip-sha';
1021
1154
 
1022
- function harness(opts: { canWrite?: Map<string, boolean> | null } = {}) {
1155
+ function harness(opts: { canWrite?: Map<string, boolean> | null; pending?: PendingCommitsService } = {}) {
1023
1156
  const git = makeGit();
1024
1157
  (git as unknown as Record<string, unknown>).remoteBranchExists = vi.fn().mockResolvedValue(true);
1025
1158
  (git as unknown as Record<string, unknown>).hasUnpushedCommits = vi.fn().mockResolvedValue(false);
@@ -1062,15 +1195,17 @@ describe('WorkflowService.mergeBranch — an agent merges branches, never an ope
1062
1195
  ).changedPathsForPr(workspaceId, target, source, { forAccessCheck: true });
1063
1196
  await mergeOpts.authorize({ sha: TARGET_TIP, changedPaths });
1064
1197
  }
1065
- return { kind: 'merged', sha: 'merge-sha' };
1198
+ // The real contract: `mergeCommit` is the commit this merge made, null when it made none.
1199
+ return { kind: 'merged', sha: 'merge-sha', mergeCommit: 'merge-sha' };
1066
1200
  },
1067
1201
  );
1068
1202
  const access = makeAccessControl();
1069
1203
  (access.canWriteBatchAtRef as ReturnType<typeof vi.fn>).mockResolvedValue(opts.canWrite === undefined ? null : opts.canWrite);
1070
1204
  const workspaceService = makeWorkspaceService();
1071
- const svc = new WorkflowService(makeDb([OPEN_REQUEST]), git, makePrs(), makeReviewWorkflow(), workspaceService, access, makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
1205
+ const pending = opts.pending ?? makePendingCommits();
1206
+ const svc = new WorkflowService(makeDb([OPEN_REQUEST]), git, makePrs(), makeReviewWorkflow(), workspaceService, access, makeFileLockService(), pending, testKbContext(), openChangeGate());
1072
1207
  const merge = (git as unknown as { mergeChangeRequest: ReturnType<typeof vi.fn> }).mergeChangeRequest;
1073
- return { svc, git, access, merge };
1208
+ return { svc, git, access, merge, pending };
1074
1209
  }
1075
1210
 
1076
1211
  it('refuses to merge a source into the target of its open change request, naming the request', async () => {
@@ -1187,3 +1322,326 @@ describe('WorkflowService.mergeBranch — an agent merges branches, never an ope
1187
1322
  expect(merge.mock.calls[0][5]).toMatchObject({ requireCleanTarget: true });
1188
1323
  });
1189
1324
  });
1325
+
1326
+ /**
1327
+ * Opening a request pushes its source after the auto-merge. A push the host
1328
+ * refuses must not undo the open: the merge is committed locally, the request
1329
+ * is a DB row, and the next push of the branch carries the commits.
1330
+ */
1331
+ describe('WorkflowService.openChangeRequest — when the repository host refuses the push', () => {
1332
+ const INPUT = { sourceBranch: 'ali/x', targetBranch: 'main', title: 'Tidy the glossary' };
1333
+
1334
+ function makeOpenHarness(push: ReturnType<typeof vi.fn>) {
1335
+ const emit = vi.fn();
1336
+ const git = Object.assign(makeGit(), {
1337
+ mergeFromOrigin: vi.fn().mockResolvedValue({ kind: 'clean', alreadyUpToDate: false }),
1338
+ push,
1339
+ pull: vi.fn().mockResolvedValue({ treeChanged: false }),
1340
+ }) as unknown as GitService;
1341
+ const prs = makePrs();
1342
+ (prs.listOpenPrs as ReturnType<typeof vi.fn>).mockResolvedValue([]);
1343
+ (prs.getPrDetail as ReturnType<typeof vi.fn>).mockResolvedValue({ number: 12, branch: 'ali/x', base: 'main' });
1344
+ const values = vi.fn(() => ({ returning: vi.fn(async () => [{ number: 12 }]) }));
1345
+ const db = { insert: vi.fn(() => ({ values })) } as unknown as Database;
1346
+ const svc = new WorkflowService(
1347
+ db, git, prs, makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(),
1348
+ makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate(),
1349
+ { emit } as unknown as WorkflowEventBus,
1350
+ );
1351
+ return { svc, git, prs, values, emit };
1352
+ }
1353
+
1354
+ it('creates the request, then answers 409 with the saved-locally sentence and raises the banner', async () => {
1355
+ const refused = new Error(
1356
+ 'git push failed: remote: Internal Server Error\n ! [remote rejected] ali/x -> ali/x (Internal Server Error)',
1357
+ );
1358
+ const h = makeOpenHarness(vi.fn().mockRejectedValue(refused));
1359
+
1360
+ const err = await h.svc.openChangeRequest('ali%2Fx', makeUser(), INPUT).catch((e: unknown) => e);
1361
+ expect(err).toBeInstanceOf(PushNeedsAgentResolutionError);
1362
+ const refusal = err as PushNeedsAgentResolutionError;
1363
+ expect(refusal.status).toBe(409);
1364
+ expect(refusal.message).toContain('Saved locally on "ali/x"');
1365
+ expect(JSON.stringify({ ...refusal.payload, error: refusal.message })).not.toMatch(/Internal Server Error|remote rejected/);
1366
+
1367
+ // The request exists — the row was inserted and announced.
1368
+ expect(h.values).toHaveBeenCalledWith(expect.objectContaining({ sourceBranch: 'ali/x', targetBranch: 'main' }));
1369
+ expect(h.prs.invalidateDetailCache).toHaveBeenCalledWith(12);
1370
+ const kinds = h.emit.mock.calls.map((c) => (c[0] as { kind: string }).kind);
1371
+ expect(kinds).toContain('change-request-opened');
1372
+ expect(h.emit).toHaveBeenCalledWith(
1373
+ expect.objectContaining({ kind: 'git-sync-failed', workspaceId: 'ali/x', branch: 'ali/x' }),
1374
+ );
1375
+ });
1376
+
1377
+ it('a push that lands answers the detail as before, with no banner', async () => {
1378
+ const h = makeOpenHarness(vi.fn().mockResolvedValue(undefined));
1379
+ await expect(h.svc.openChangeRequest('ali%2Fx', makeUser(), INPUT)).resolves.toMatchObject({ number: 12 });
1380
+ expect(h.git.push).toHaveBeenCalledWith('ali%2Fx', expect.objectContaining({ email: 'alice@example.com' }));
1381
+ const kinds = h.emit.mock.calls.map((c) => (c[0] as { kind: string }).kind);
1382
+ expect(kinds).not.toContain('git-sync-failed');
1383
+ });
1384
+
1385
+ it('a non-fast-forward recovers with a merge-preserving pull, and the request opens', async () => {
1386
+ const push = vi
1387
+ .fn()
1388
+ .mockRejectedValueOnce(new Error('! [rejected] ali/x -> ali/x (fetch first)'))
1389
+ .mockResolvedValue(undefined);
1390
+ const h = makeOpenHarness(push);
1391
+ await expect(h.svc.openChangeRequest('ali%2Fx', makeUser(), INPUT)).resolves.toMatchObject({ number: 12 });
1392
+ expect(h.git.pull).toHaveBeenCalledWith('ali%2Fx', { preserveMerges: true });
1393
+ expect(push).toHaveBeenCalledTimes(2);
1394
+ });
1395
+ });
1396
+
1397
+ /**
1398
+ * Writes are committed asynchronously: a write tool answers once the bytes are
1399
+ * on disk, and the pending-commits worker commits and pushes them seconds
1400
+ * later. `mergeBranch` merges what the REMOTE holds of the source, so it waits
1401
+ * for the source's queue first — bounded, outside the lifecycle locks — and
1402
+ * says plainly when there was nothing to merge.
1403
+ */
1404
+ describe('WorkflowService.mergeBranch — waits for the source branch\'s pending commits', () => {
1405
+ const SOURCE = 'alice/other';
1406
+ const TARGET = 'alice/feat';
1407
+
1408
+ function row(over: Partial<PendingCommit> = {}): PendingCommit {
1409
+ return {
1410
+ id: `row-${Math.random()}`,
1411
+ workspaceId: encodeURIComponent(SOURCE),
1412
+ branch: SOURCE,
1413
+ path: 'knowledge-base/Notes/New.md',
1414
+ authorEmail: 'alice@example.com',
1415
+ authorName: 'Alice',
1416
+ queuedAt: new Date(),
1417
+ status: 'pending',
1418
+ attempts: 0,
1419
+ recoveryAgentRuns: 0,
1420
+ lastAttemptedAt: null,
1421
+ lastError: null,
1422
+ ...over,
1423
+ };
1424
+ }
1425
+
1426
+ /**
1427
+ * An in-memory `pending_commits` table with the methods the worker and
1428
+ * `mergeBranch` use — the same rules as the SQL: `markSucceeded` deletes the
1429
+ * row, `queuedOnBranch` counts `pending` + `running` and reports the first
1430
+ * `needs_attention` row's message.
1431
+ */
1432
+ function memoryQueue(rows: PendingCommit[] = []) {
1433
+ const table = [...rows];
1434
+ const service = {
1435
+ enqueue: vi.fn(async (input: { workspaceId: string; branch: string; path: string; authorEmail: string; authorName: string }) => {
1436
+ table.push(row({ ...input }));
1437
+ }),
1438
+ claimNext: vi.fn(async (workspaceId: string) => {
1439
+ const next = table.find((r) => r.workspaceId === workspaceId && r.status === 'pending');
1440
+ if (next) next.status = 'running';
1441
+ return next ?? null;
1442
+ }),
1443
+ hasReadyRow: vi.fn(async (workspaceId: string) => table.some((r) => r.workspaceId === workspaceId && r.status === 'pending')),
1444
+ markSucceeded: vi.fn(async (id: string) => {
1445
+ table.splice(table.findIndex((r) => r.id === id), 1);
1446
+ }),
1447
+ markTransientFailure: vi.fn(async () => undefined),
1448
+ markRecoveryStarted: vi.fn(async () => undefined),
1449
+ markNeedsAttention: vi.fn(async () => undefined),
1450
+ queuedOnBranch: vi.fn(async (branch: string) => {
1451
+ const mine = table.filter((r) => r.branch === branch);
1452
+ const stuck = mine.filter((r) => r.status === 'needs_attention');
1453
+ return {
1454
+ queued: mine.filter((r) => r.status === 'pending' || r.status === 'running').length,
1455
+ stuck: stuck.length,
1456
+ needsAttention: stuck[0] ? stuck[0].lastError : null,
1457
+ };
1458
+ }),
1459
+ };
1460
+ return { service: service as unknown as PendingCommitsService & typeof service, table };
1461
+ }
1462
+
1463
+ function harness(pending: PendingCommitsService, wait = { timeoutMs: 20_000, pollMs: 20 }) {
1464
+ const git = makeGit();
1465
+ (git as unknown as Record<string, unknown>).remoteBranchExists = vi.fn().mockResolvedValue(true);
1466
+ const merge = vi.fn(async (): Promise<unknown> => ({ kind: 'merged', sha: 'merge-sha', mergeCommit: 'merge-sha' }));
1467
+ (git as unknown as Record<string, unknown>).mergeChangeRequest = merge;
1468
+ const svc = new WorkflowService(
1469
+ makeDb([{ number: 12, sourceBranch: 'alice/feat', targetBranch: DEFAULT_BRANCH, state: 'open' }]),
1470
+ git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(),
1471
+ pending, testKbContext(), openChangeGate(),
1472
+ );
1473
+ svc.mergeWaitForPendingCommits = wait;
1474
+ return { svc, git, merge };
1475
+ }
1476
+
1477
+ it('lands a write still queued on the source: the worker commits it while the merge waits, no retry', async () => {
1478
+ // The shared remote, as `mergeChangeRequest` sees it: what each branch has
1479
+ // been PUSHED with. The write below is on disk, not here yet.
1480
+ const remote = new Map<string, Set<string>>([[SOURCE, new Set()], [TARGET, new Set()]]);
1481
+ const { service } = memoryQueue();
1482
+ const { svc, merge } = harness(service);
1483
+ merge.mockImplementation(async () => {
1484
+ const missing = [...remote.get(SOURCE)!].filter((p) => !remote.get(TARGET)!.has(p));
1485
+ if (missing.length === 0) return { kind: 'merged', sha: 'target-tip', mergeCommit: null };
1486
+ missing.forEach((p) => remote.get(TARGET)!.add(p));
1487
+ return { kind: 'merged', sha: 'merge-commit', mergeCommit: 'merge-commit' };
1488
+ });
1489
+
1490
+ // The REAL worker drains the queue; its commit driver pushes to the remote
1491
+ // after a moment, the way a commit + push takes a few seconds.
1492
+ const worker = new PendingCommitsWorker({
1493
+ service,
1494
+ workflow: {
1495
+ runPendingCommit: async (_ws: string, branch: string, path: string) => {
1496
+ await new Promise((r) => setTimeout(r, 150));
1497
+ remote.get(branch)!.add(path);
1498
+ },
1499
+ },
1500
+ recoveryAgent: { run: vi.fn() } as never,
1501
+ feedback: { notify: vi.fn() } as never,
1502
+ workspaces: { knownWorkspaces: () => [{ id: encodeURIComponent(SOURCE), branch: SOURCE }] },
1503
+ recoveryBot: { id: 'bot', email: 'bot@example.com', name: 'Bot' },
1504
+ });
1505
+
1506
+ // The write tool answered: the bytes are on disk and a row is queued.
1507
+ await service.enqueue({
1508
+ workspaceId: encodeURIComponent(SOURCE),
1509
+ branch: SOURCE,
1510
+ path: 'knowledge-base/Notes/New.md',
1511
+ authorEmail: 'alice@example.com',
1512
+ authorName: 'Alice',
1513
+ });
1514
+ worker.start();
1515
+ try {
1516
+ // …and the agent merges in the same breath.
1517
+ const outcome = await svc.mergeBranch(makeUser(), SOURCE, TARGET);
1518
+ expect(outcome).toEqual({ kind: 'merged', sha: 'merge-commit' });
1519
+ expect(remote.get(TARGET)!.has('knowledge-base/Notes/New.md')).toBe(true);
1520
+ // One merge, after the commit landed — not an empty one first.
1521
+ expect(merge).toHaveBeenCalledTimes(1);
1522
+ expect(service.queuedOnBranch.mock.calls.length).toBeGreaterThan(1);
1523
+ } finally {
1524
+ await worker.stop();
1525
+ }
1526
+ });
1527
+
1528
+ it('answers pending-commits after the bound when the source\'s commit cannot land, and merges nothing', async () => {
1529
+ // The worker is stopped: the row stays queued.
1530
+ const { service } = memoryQueue([row()]);
1531
+ const { svc, merge, git } = harness(service, { timeoutMs: 200, pollMs: 20 });
1532
+ const started = Date.now();
1533
+ const outcome = await svc.mergeBranch(makeUser(), SOURCE, TARGET);
1534
+ expect(Date.now() - started).toBeGreaterThanOrEqual(190);
1535
+ expect(outcome).toEqual({
1536
+ kind: 'pending-commits',
1537
+ branch: SOURCE,
1538
+ pending: 1,
1539
+ message: expect.stringMatching(/still being committed.*Nothing was merged.*Retry the merge shortly/),
1540
+ });
1541
+ expect(merge).not.toHaveBeenCalled();
1542
+ expect(git.pull).not.toHaveBeenCalled();
1543
+ });
1544
+
1545
+ it('bounds the wait well inside the timeout an agent\'s call is forwarded under', () => {
1546
+ const svc = new WorkflowService(
1547
+ makeDb(), makeGit(), makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(),
1548
+ makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate(),
1549
+ );
1550
+ // Over `/api/mcp` the call reaches the tool through `@utcp/http`, whose
1551
+ // request timeout cannot be set per template. A wait that ran to that
1552
+ // ceiling answered "timeout of 30000ms exceeded" instead of
1553
+ // `pending-commits` (Local Testing, attempt 1). The wait and the merge after
1554
+ // it must both fit, so the bound leaves ten seconds for the merge.
1555
+ const forwarding = (new HttpCommunicationProtocol() as unknown as { _axiosInstance: { defaults: { timeout: number } } })
1556
+ ._axiosInstance.defaults.timeout;
1557
+ expect(forwarding).toBe(30_000);
1558
+ expect(svc.mergeWaitForPendingCommits.timeoutMs).toBe(20_000);
1559
+ expect(forwarding - svc.mergeWaitForPendingCommits.timeoutMs).toBeGreaterThanOrEqual(10_000);
1560
+ });
1561
+
1562
+ it('answers pending-commits at once, with the worker\'s message, when a queued commit needs attention', async () => {
1563
+ const { service } = memoryQueue([
1564
+ row({ status: 'needs_attention', lastError: 'push rejected: protected ref' }),
1565
+ row(),
1566
+ ]);
1567
+ // The default 20-second bound: an answer well inside it shows no wait.
1568
+ const { svc, merge } = harness(service, { timeoutMs: 20_000, pollMs: 20 });
1569
+ const started = Date.now();
1570
+ const outcome = await svc.mergeBranch(makeUser(), SOURCE, TARGET);
1571
+ expect(Date.now() - started).toBeLessThan(1_000);
1572
+ expect(outcome).toEqual({
1573
+ kind: 'pending-commits',
1574
+ branch: SOURCE,
1575
+ pending: 2,
1576
+ needsAttention: 'push rejected: protected ref',
1577
+ message: expect.stringContaining('push rejected: protected ref'),
1578
+ });
1579
+ expect(service.queuedOnBranch).toHaveBeenCalledTimes(1);
1580
+ expect(merge).not.toHaveBeenCalled();
1581
+ });
1582
+
1583
+ it('answers nothing-to-merge with the target\'s tip when the source has nothing the target lacks', async () => {
1584
+ const { svc, merge } = harness(memoryQueue().service);
1585
+ merge.mockResolvedValue({ kind: 'merged', sha: 'target-tip', mergeCommit: null });
1586
+ expect(await svc.mergeBranch(makeUser(), SOURCE, TARGET)).toEqual({ kind: 'nothing-to-merge', sha: 'target-tip' });
1587
+ expect(merge).toHaveBeenCalledTimes(1);
1588
+ });
1589
+
1590
+ it('answers merged with the merge commit when the source has commits the target lacks and nothing is pending', async () => {
1591
+ const { svc } = harness(memoryQueue().service);
1592
+ expect(await svc.mergeBranch(makeUser(), SOURCE, TARGET)).toEqual({ kind: 'merged', sha: 'merge-sha' });
1593
+ });
1594
+
1595
+ it('answers conflicts-need-resolution with the paths, as before', async () => {
1596
+ const { svc, merge } = harness(memoryQueue().service);
1597
+ merge.mockResolvedValue({ kind: 'conflicts', paths: ['A.md'] });
1598
+ expect(await svc.mergeBranch(makeUser(), SOURCE, TARGET)).toEqual({
1599
+ kind: 'conflicts-need-resolution',
1600
+ conflictedPaths: ['A.md'],
1601
+ });
1602
+ });
1603
+
1604
+ it('refuses a merge an open change request proposes before any waiting', async () => {
1605
+ // A queued commit that would hold the merge for the full bound.
1606
+ const { service } = memoryQueue([row({ branch: 'alice/feat' })]);
1607
+ const { svc, merge } = harness(service, { timeoutMs: 20_000, pollMs: 20 });
1608
+ const started = Date.now();
1609
+ const err = await svc.mergeBranch(makeUser(), 'alice/feat', DEFAULT_BRANCH).catch((e: unknown) => e);
1610
+ expect(Date.now() - started).toBeLessThan(1_000);
1611
+ expect(err).toMatchObject({ status: 409, payload: { kind: 'open-change-request-blocks-merge', number: 12 } });
1612
+ expect(service.queuedOnBranch).not.toHaveBeenCalled();
1613
+ expect(merge).not.toHaveBeenCalled();
1614
+ });
1615
+
1616
+ it('holds neither branch\'s lifecycle lock while it waits', async () => {
1617
+ const { service, table } = memoryQueue([row()]);
1618
+ const { svc, git } = harness(service, { timeoutMs: 5_000, pollMs: 20 });
1619
+ (git.createBranch as ReturnType<typeof vi.fn>).mockResolvedValue({ name: 'x' });
1620
+ const merging = svc.mergeBranch(makeUser(), SOURCE, TARGET);
1621
+ let mergeDone = false;
1622
+ void merging.then(() => (mergeDone = true));
1623
+ await new Promise((r) => setTimeout(r, 50));
1624
+ // Both keys `runOnBranchPair` takes: work under either completes while
1625
+ // the merge is still waiting on the source's queue.
1626
+ await svc.createBranch(encodeURIComponent(TARGET), TARGET);
1627
+ await svc.createBranch(encodeURIComponent(SOURCE), SOURCE);
1628
+ expect(git.createBranch).toHaveBeenCalledTimes(2);
1629
+ expect(mergeDone).toBe(false);
1630
+ // The commit lands; the merge goes on.
1631
+ table.splice(0, table.length);
1632
+ expect(await merging).toEqual({ kind: 'merged', sha: 'merge-sha' });
1633
+ });
1634
+
1635
+ it('leaves the app\'s change-request apply as it was: no wait, same outcome', async () => {
1636
+ const { service } = memoryQueue([row({ branch: 'alice/feat' })]);
1637
+ const prs = makePrs();
1638
+ const reviewWorkflow = makeReviewWorkflow();
1639
+ const mergeResult = { prNumber: 4, sha: 'abc', mergedAt: 't' };
1640
+ (reviewWorkflow.mergePr as ReturnType<typeof vi.fn>).mockResolvedValue(mergeResult);
1641
+ (prs.getPr as ReturnType<typeof vi.fn>).mockResolvedValue({ branch: 'alice/feat', base: 'main' });
1642
+ const svc = new WorkflowService(makeDb(), makeGit(), prs, reviewWorkflow, makeWorkspaceService(), makeAccessControl(), makeFileLockService(), service, testKbContext(), openChangeGate());
1643
+ const outcome = await svc.mergeChangeRequest(4, makeUser(), 'sha', [], 'open', 'PR title', 'main', 'w1', { bypass: true });
1644
+ expect(outcome).toEqual({ kind: 'merged', result: mergeResult });
1645
+ expect(service.queuedOnBranch).not.toHaveBeenCalled();
1646
+ });
1647
+ });
@@ -281,6 +281,10 @@ describe('WorkflowService.removeFolderFromChangeRequests', () => {
281
281
  expect(closed).toEqual([40]);
282
282
  expect([...changed.get(elsewhere.branch)!]).toEqual(['Data/ReportsArchive/old.md']);
283
283
 
284
+ // Each source checkout is brought up to date replaying merges as merges:
285
+ // a merge a refused open or update stranded there must not be flattened.
286
+ expect(git.pull).toHaveBeenCalledWith(aliceWs, { preserveMerges: true });
287
+ expect(git.pull).toHaveBeenCalledWith(bobWs, { preserveMerges: true });
284
288
  // Every checkout goes to git in ONE call, each file reverted to its merge base.
285
289
  expect(git.revertPathsAndPush).toHaveBeenCalledTimes(1);
286
290
  expect(plansOf(git)).toEqual([
@@ -599,7 +599,7 @@ describe('WorkflowService — git-sync visibility events', () => {
599
599
  expect(kinds()).toEqual(['file-changed', 'file-changed']);
600
600
  });
601
601
 
602
- it('carries the branch and a sanitised reason for the banner', async () => {
602
+ it('carries the branch and a reason in words — never the git output — for the banner', async () => {
603
603
  const svc = makeFacade(
604
604
  makeGit({ pushBehavior: 'auth-fail' }),
605
605
  makeFileLocks(USER.id),
@@ -615,9 +615,10 @@ describe('WorkflowService — git-sync visibility events', () => {
615
615
  workspaceId: 'ws-1',
616
616
  branch: 'feat/x',
617
617
  });
618
- expect((emitSpy.mock.calls[0][0] as { reason: string }).reason).toContain(
619
- 'Authentication failed',
620
- );
618
+ // The kind of failure survives; git's own text stays in the server log.
619
+ const { reason } = emitSpy.mock.calls[0][0] as { reason: string };
620
+ expect(reason).toBe("The repository host did not accept this server's credentials.");
621
+ expect(reason).not.toContain('Authentication failed');
621
622
  });
622
623
 
623
624
  it('re-announces on every failure, so a session joining mid-outage still learns of it', async () => {