@bevel-software/platform-core-backend 0.14.0 → 0.19.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 (1307) hide show
  1. package/THIRD-PARTY-NOTICES.md +8 -8
  2. package/dist/core/catalog-cache-invalidation.d.ts +45 -0
  3. package/dist/core/catalog-cache-invalidation.d.ts.map +1 -0
  4. package/dist/core/catalog-cache-invalidation.js +76 -0
  5. package/dist/core/catalog-cache-invalidation.js.map +1 -0
  6. package/dist/core/catalog-revision.d.ts +39 -0
  7. package/dist/core/catalog-revision.d.ts.map +1 -0
  8. package/dist/core/catalog-revision.js +94 -0
  9. package/dist/core/catalog-revision.js.map +1 -0
  10. package/dist/core/create-core-server.d.ts +7 -0
  11. package/dist/core/create-core-server.d.ts.map +1 -1
  12. package/dist/core/create-core-server.js +279 -64
  13. package/dist/core/create-core-server.js.map +1 -1
  14. package/dist/core/create-core-services.d.ts +66 -2
  15. package/dist/core/create-core-services.d.ts.map +1 -1
  16. package/dist/core/create-core-services.js +290 -111
  17. package/dist/core/create-core-services.js.map +1 -1
  18. package/dist/core/lifecycle.d.ts +138 -0
  19. package/dist/core/lifecycle.d.ts.map +1 -0
  20. package/dist/core/lifecycle.js +218 -0
  21. package/dist/core/lifecycle.js.map +1 -0
  22. package/dist/core/public-config.d.ts +82 -0
  23. package/dist/core/public-config.d.ts.map +1 -0
  24. package/dist/core/public-config.js +78 -0
  25. package/dist/core/public-config.js.map +1 -0
  26. package/dist/core/readiness.d.ts +86 -0
  27. package/dist/core/readiness.d.ts.map +1 -0
  28. package/dist/core/readiness.js +56 -0
  29. package/dist/core/readiness.js.map +1 -0
  30. package/dist/core-config.d.ts +30 -0
  31. package/dist/core-config.d.ts.map +1 -1
  32. package/dist/core-config.js +64 -2
  33. package/dist/core-config.js.map +1 -1
  34. package/dist/index.d.ts +4 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +6 -0
  37. package/dist/index.js.map +1 -1
  38. package/dist/modules/access/access-control.interface.d.ts +231 -15
  39. package/dist/modules/access/access-control.interface.d.ts.map +1 -1
  40. package/dist/modules/access/access-control.service.d.ts +83 -12
  41. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  42. package/dist/modules/access/access-control.service.js +815 -212
  43. package/dist/modules/access/access-control.service.js.map +1 -1
  44. package/dist/modules/access/access-mutation.service.d.ts +71 -5
  45. package/dist/modules/access/access-mutation.service.d.ts.map +1 -1
  46. package/dist/modules/access/access-mutation.service.js +161 -13
  47. package/dist/modules/access/access-mutation.service.js.map +1 -1
  48. package/dist/modules/access/access-view.d.ts +147 -0
  49. package/dist/modules/access/access-view.d.ts.map +1 -0
  50. package/dist/modules/access/access-view.js +211 -0
  51. package/dist/modules/access/access-view.js.map +1 -0
  52. package/dist/modules/access/access.routes.d.ts.map +1 -1
  53. package/dist/modules/access/access.routes.js +312 -84
  54. package/dist/modules/access/access.routes.js.map +1 -1
  55. package/dist/modules/access/admin-locked-commit.d.ts +2 -3
  56. package/dist/modules/access/admin-locked-commit.d.ts.map +1 -1
  57. package/dist/modules/access/admin-locked-commit.js +9 -8
  58. package/dist/modules/access/admin-locked-commit.js.map +1 -1
  59. package/dist/modules/access/admin-route-helpers.d.ts.map +1 -1
  60. package/dist/modules/access/admin-route-helpers.js +4 -4
  61. package/dist/modules/access/admin-route-helpers.js.map +1 -1
  62. package/dist/modules/access/change-read-gate.d.ts +53 -0
  63. package/dist/modules/access/change-read-gate.d.ts.map +1 -0
  64. package/dist/modules/access/change-read-gate.js +134 -0
  65. package/dist/modules/access/change-read-gate.js.map +1 -0
  66. package/dist/modules/access/creator-access.d.ts +33 -39
  67. package/dist/modules/access/creator-access.d.ts.map +1 -1
  68. package/dist/modules/access/creator-access.js +92 -119
  69. package/dist/modules/access/creator-access.js.map +1 -1
  70. package/dist/modules/access/directory-sync-bot.d.ts.map +1 -1
  71. package/dist/modules/access/directory-sync-bot.js +3 -1
  72. package/dist/modules/access/directory-sync-bot.js.map +1 -1
  73. package/dist/modules/access/groups-admin.service.d.ts +3 -3
  74. package/dist/modules/access/groups-admin.service.js +2 -2
  75. package/dist/modules/access/reference-scan.d.ts +1 -1
  76. package/dist/modules/access/reference-scan.d.ts.map +1 -1
  77. package/dist/modules/access/reference-scan.js +5 -4
  78. package/dist/modules/access/reference-scan.js.map +1 -1
  79. package/dist/modules/access/roles-admin.service.d.ts +72 -13
  80. package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
  81. package/dist/modules/access/roles-admin.service.js +71 -13
  82. package/dist/modules/access/roles-admin.service.js.map +1 -1
  83. package/dist/modules/access/synced-groups-committer.d.ts.map +1 -1
  84. package/dist/modules/access/synced-groups-committer.js +8 -6
  85. package/dist/modules/access/synced-groups-committer.js.map +1 -1
  86. package/dist/modules/access/synced-groups-writer.d.ts.map +1 -1
  87. package/dist/modules/access/synced-groups-writer.js +3 -8
  88. package/dist/modules/access/synced-groups-writer.js.map +1 -1
  89. package/dist/modules/access/user-access-removal.service.d.ts +209 -0
  90. package/dist/modules/access/user-access-removal.service.d.ts.map +1 -0
  91. package/dist/modules/access/user-access-removal.service.js +662 -0
  92. package/dist/modules/access/user-access-removal.service.js.map +1 -0
  93. package/dist/modules/access-model/access-errors.d.ts +32 -1
  94. package/dist/modules/access-model/access-errors.d.ts.map +1 -1
  95. package/dist/modules/access-model/access-errors.js +38 -11
  96. package/dist/modules/access-model/access-errors.js.map +1 -1
  97. package/dist/modules/access-model/access-grammar.d.ts +100 -25
  98. package/dist/modules/access-model/access-grammar.d.ts.map +1 -1
  99. package/dist/modules/access-model/access-grammar.js +162 -48
  100. package/dist/modules/access-model/access-grammar.js.map +1 -1
  101. package/dist/modules/access-model/access-splice.d.ts.map +1 -1
  102. package/dist/modules/access-model/access-splice.js +18 -18
  103. package/dist/modules/access-model/access-splice.js.map +1 -1
  104. package/dist/modules/access-model/access-template.d.ts +22 -0
  105. package/dist/modules/access-model/access-template.d.ts.map +1 -0
  106. package/dist/modules/access-model/access-template.js +42 -0
  107. package/dist/modules/access-model/access-template.js.map +1 -0
  108. package/dist/modules/access-model/change-gate.d.ts +65 -0
  109. package/dist/modules/access-model/change-gate.d.ts.map +1 -0
  110. package/dist/modules/access-model/change-gate.js +25 -0
  111. package/dist/modules/access-model/change-gate.js.map +1 -0
  112. package/dist/modules/access-model/creator.d.ts +13 -16
  113. package/dist/modules/access-model/creator.d.ts.map +1 -1
  114. package/dist/modules/access-model/creator.js.map +1 -1
  115. package/dist/modules/access-model/frontmatter-lines.d.ts +27 -0
  116. package/dist/modules/access-model/frontmatter-lines.d.ts.map +1 -0
  117. package/dist/modules/access-model/frontmatter-lines.js +74 -0
  118. package/dist/modules/access-model/frontmatter-lines.js.map +1 -0
  119. package/dist/modules/access-model/group-files.d.ts.map +1 -1
  120. package/dist/modules/access-model/group-files.js +4 -1
  121. package/dist/modules/access-model/group-files.js.map +1 -1
  122. package/dist/modules/access-model/plugin-principals.d.ts +51 -0
  123. package/dist/modules/access-model/plugin-principals.d.ts.map +1 -0
  124. package/dist/modules/access-model/plugin-principals.js +119 -0
  125. package/dist/modules/access-model/plugin-principals.js.map +1 -0
  126. package/dist/modules/access-model/roles-yaml-guard.d.ts +73 -2
  127. package/dist/modules/access-model/roles-yaml-guard.d.ts.map +1 -1
  128. package/dist/modules/access-model/roles-yaml-guard.js +153 -3
  129. package/dist/modules/access-model/roles-yaml-guard.js.map +1 -1
  130. package/dist/modules/admin/admin-access.service.d.ts.map +1 -1
  131. package/dist/modules/admin/admin-access.service.js +5 -2
  132. package/dist/modules/admin/admin-access.service.js.map +1 -1
  133. package/dist/modules/agent-instructions/agent-instructions.routes.d.ts +21 -0
  134. package/dist/modules/agent-instructions/agent-instructions.routes.d.ts.map +1 -0
  135. package/dist/modules/agent-instructions/agent-instructions.routes.js +38 -0
  136. package/dist/modules/agent-instructions/agent-instructions.routes.js.map +1 -0
  137. package/dist/modules/agent-instructions/compose.d.ts +71 -0
  138. package/dist/modules/agent-instructions/compose.d.ts.map +1 -0
  139. package/dist/modules/agent-instructions/compose.js +234 -0
  140. package/dist/modules/agent-instructions/compose.js.map +1 -0
  141. package/dist/modules/agent-instructions/index.d.ts +4 -0
  142. package/dist/modules/agent-instructions/index.d.ts.map +1 -0
  143. package/dist/modules/agent-instructions/index.js +4 -0
  144. package/dist/modules/agent-instructions/index.js.map +1 -0
  145. package/dist/modules/agent-instructions/read-preamble.d.ts +37 -0
  146. package/dist/modules/agent-instructions/read-preamble.d.ts.map +1 -0
  147. package/dist/modules/agent-instructions/read-preamble.js +81 -0
  148. package/dist/modules/agent-instructions/read-preamble.js.map +1 -0
  149. package/dist/modules/auth/account-erasure.service.d.ts +30 -4
  150. package/dist/modules/auth/account-erasure.service.d.ts.map +1 -1
  151. package/dist/modules/auth/account-erasure.service.js +96 -10
  152. package/dist/modules/auth/account-erasure.service.js.map +1 -1
  153. package/dist/modules/auth/account.routes.d.ts +6 -3
  154. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  155. package/dist/modules/auth/account.routes.js +109 -10
  156. package/dist/modules/auth/account.routes.js.map +1 -1
  157. package/dist/modules/auth/auth.routes.d.ts +10 -3
  158. package/dist/modules/auth/auth.routes.d.ts.map +1 -1
  159. package/dist/modules/auth/auth.routes.js +9 -4
  160. package/dist/modules/auth/auth.routes.js.map +1 -1
  161. package/dist/modules/auth/auth.service.d.ts +89 -5
  162. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  163. package/dist/modules/auth/auth.service.js +160 -25
  164. package/dist/modules/auth/auth.service.js.map +1 -1
  165. package/dist/modules/auth/oidc-auth-provider.d.ts +46 -3
  166. package/dist/modules/auth/oidc-auth-provider.d.ts.map +1 -1
  167. package/dist/modules/auth/oidc-auth-provider.js +99 -21
  168. package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
  169. package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -1
  170. package/dist/modules/code-mode/code-mode.tool.js +14 -2
  171. package/dist/modules/code-mode/code-mode.tool.js.map +1 -1
  172. package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
  173. package/dist/modules/connection-probe/connection-probe.service.js +56 -7
  174. package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
  175. package/dist/modules/database/advisory-lock.d.ts +103 -0
  176. package/dist/modules/database/advisory-lock.d.ts.map +1 -0
  177. package/dist/modules/database/advisory-lock.js +320 -0
  178. package/dist/modules/database/advisory-lock.js.map +1 -0
  179. package/dist/modules/database/connection.d.ts.map +1 -1
  180. package/dist/modules/database/connection.js +9 -1
  181. package/dist/modules/database/connection.js.map +1 -1
  182. package/dist/modules/database/core-schema.d.ts +672 -0
  183. package/dist/modules/database/core-schema.d.ts.map +1 -1
  184. package/dist/modules/database/core-schema.js +171 -0
  185. package/dist/modules/database/core-schema.js.map +1 -1
  186. package/dist/modules/database/migrate.d.ts.map +1 -1
  187. package/dist/modules/database/migrate.js +26 -6
  188. package/dist/modules/database/migrate.js.map +1 -1
  189. package/dist/modules/declared-variables/declared-variables.routes.d.ts.map +1 -1
  190. package/dist/modules/declared-variables/declared-variables.routes.js +4 -2
  191. package/dist/modules/declared-variables/declared-variables.routes.js.map +1 -1
  192. package/dist/modules/diff/diff.routes.d.ts.map +1 -1
  193. package/dist/modules/diff/diff.routes.js +2 -4
  194. package/dist/modules/diff/diff.routes.js.map +1 -1
  195. package/dist/modules/diff/diff.service.d.ts +4 -1
  196. package/dist/modules/diff/diff.service.d.ts.map +1 -1
  197. package/dist/modules/diff/diff.service.js +79 -81
  198. package/dist/modules/diff/diff.service.js.map +1 -1
  199. package/dist/modules/kb-fs/bevel-ignore.d.ts +35 -0
  200. package/dist/modules/kb-fs/bevel-ignore.d.ts.map +1 -0
  201. package/dist/modules/kb-fs/bevel-ignore.js +71 -0
  202. package/dist/modules/kb-fs/bevel-ignore.js.map +1 -0
  203. package/dist/modules/kb-fs/file-change-notifier.d.ts.map +1 -1
  204. package/dist/modules/kb-fs/file-change-notifier.js +3 -1
  205. package/dist/modules/kb-fs/file-change-notifier.js.map +1 -1
  206. package/dist/modules/kb-fs/git-guarded-filesystem.d.ts +37 -0
  207. package/dist/modules/kb-fs/git-guarded-filesystem.d.ts.map +1 -0
  208. package/dist/modules/kb-fs/git-guarded-filesystem.js +104 -0
  209. package/dist/modules/kb-fs/git-guarded-filesystem.js.map +1 -0
  210. package/dist/modules/kb-fs/locking-filesystem.d.ts +113 -18
  211. package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
  212. package/dist/modules/kb-fs/locking-filesystem.js +353 -76
  213. package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
  214. package/dist/modules/kb-fs/node-fs.d.ts +23 -0
  215. package/dist/modules/kb-fs/node-fs.d.ts.map +1 -0
  216. package/dist/modules/kb-fs/node-fs.js +158 -0
  217. package/dist/modules/kb-fs/node-fs.js.map +1 -0
  218. package/dist/modules/kb-fs/read-only-filesystem.d.ts +10 -9
  219. package/dist/modules/kb-fs/read-only-filesystem.d.ts.map +1 -1
  220. package/dist/modules/kb-fs/read-only-filesystem.js +18 -9
  221. package/dist/modules/kb-fs/read-only-filesystem.js.map +1 -1
  222. package/dist/modules/kb-fs/repo-path.d.ts +100 -3
  223. package/dist/modules/kb-fs/repo-path.d.ts.map +1 -1
  224. package/dist/modules/kb-fs/repo-path.js +195 -3
  225. package/dist/modules/kb-fs/repo-path.js.map +1 -1
  226. package/dist/modules/kb-sync/index.d.ts +6 -0
  227. package/dist/modules/kb-sync/index.d.ts.map +1 -0
  228. package/dist/modules/kb-sync/index.js +5 -0
  229. package/dist/modules/kb-sync/index.js.map +1 -0
  230. package/dist/modules/kb-sync/kb-sync.interface.d.ts +77 -0
  231. package/dist/modules/kb-sync/kb-sync.interface.d.ts.map +1 -0
  232. package/dist/modules/kb-sync/kb-sync.interface.js +2 -0
  233. package/dist/modules/kb-sync/kb-sync.interface.js.map +1 -0
  234. package/dist/modules/kb-sync/kb-sync.routes.d.ts +70 -0
  235. package/dist/modules/kb-sync/kb-sync.routes.d.ts.map +1 -0
  236. package/dist/modules/kb-sync/kb-sync.routes.js +137 -0
  237. package/dist/modules/kb-sync/kb-sync.routes.js.map +1 -0
  238. package/dist/modules/kb-sync/kb-sync.service.d.ts +45 -0
  239. package/dist/modules/kb-sync/kb-sync.service.d.ts.map +1 -0
  240. package/dist/modules/kb-sync/kb-sync.service.js +185 -0
  241. package/dist/modules/kb-sync/kb-sync.service.js.map +1 -0
  242. package/dist/modules/kb-sync/sync-auth.d.ts +59 -0
  243. package/dist/modules/kb-sync/sync-auth.d.ts.map +1 -0
  244. package/dist/modules/kb-sync/sync-auth.js +62 -0
  245. package/dist/modules/kb-sync/sync-auth.js.map +1 -0
  246. package/dist/modules/kb-sync/sync-payload.d.ts +32 -0
  247. package/dist/modules/kb-sync/sync-payload.d.ts.map +1 -0
  248. package/dist/modules/kb-sync/sync-payload.js +105 -0
  249. package/dist/modules/kb-sync/sync-payload.js.map +1 -0
  250. package/dist/modules/marketplace/git-http.routes.d.ts +42 -0
  251. package/dist/modules/marketplace/git-http.routes.d.ts.map +1 -0
  252. package/dist/modules/marketplace/git-http.routes.js +192 -0
  253. package/dist/modules/marketplace/git-http.routes.js.map +1 -0
  254. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.d.ts +33 -0
  255. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.d.ts.map +1 -0
  256. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.js +88 -0
  257. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.js.map +1 -0
  258. package/dist/modules/marketplace/github-facade/github-facade-codes.store.d.ts +59 -0
  259. package/dist/modules/marketplace/github-facade/github-facade-codes.store.d.ts.map +1 -0
  260. package/dist/modules/marketplace/github-facade/github-facade-codes.store.js +96 -0
  261. package/dist/modules/marketplace/github-facade/github-facade-codes.store.js.map +1 -0
  262. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.d.ts +126 -0
  263. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.d.ts.map +1 -0
  264. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.js +192 -0
  265. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.js.map +1 -0
  266. package/dist/modules/marketplace/github-facade/github-facade.routes.d.ts +47 -0
  267. package/dist/modules/marketplace/github-facade/github-facade.routes.d.ts.map +1 -0
  268. package/dist/modules/marketplace/github-facade/github-facade.routes.js +252 -0
  269. package/dist/modules/marketplace/github-facade/github-facade.routes.js.map +1 -0
  270. package/dist/modules/marketplace/github-facade/github-facade.service.d.ts +121 -0
  271. package/dist/modules/marketplace/github-facade/github-facade.service.d.ts.map +1 -0
  272. package/dist/modules/marketplace/github-facade/github-facade.service.js +213 -0
  273. package/dist/modules/marketplace/github-facade/github-facade.service.js.map +1 -0
  274. package/dist/modules/marketplace/github-facade/index.d.ts +6 -0
  275. package/dist/modules/marketplace/github-facade/index.d.ts.map +1 -0
  276. package/dist/modules/marketplace/github-facade/index.js +6 -0
  277. package/dist/modules/marketplace/github-facade/index.js.map +1 -0
  278. package/dist/modules/marketplace/index.d.ts +4 -0
  279. package/dist/modules/marketplace/index.d.ts.map +1 -0
  280. package/dist/modules/marketplace/index.js +4 -0
  281. package/dist/modules/marketplace/index.js.map +1 -0
  282. package/dist/modules/marketplace/marketplace-repo.service.d.ts +135 -0
  283. package/dist/modules/marketplace/marketplace-repo.service.d.ts.map +1 -0
  284. package/dist/modules/marketplace/marketplace-repo.service.js +318 -0
  285. package/dist/modules/marketplace/marketplace-repo.service.js.map +1 -0
  286. package/dist/modules/mcp/downstream-pool.d.ts +107 -0
  287. package/dist/modules/mcp/downstream-pool.d.ts.map +1 -0
  288. package/dist/modules/mcp/downstream-pool.js +221 -0
  289. package/dist/modules/mcp/downstream-pool.js.map +1 -0
  290. package/dist/modules/mcp/downstream-token-refresh.d.ts +77 -0
  291. package/dist/modules/mcp/downstream-token-refresh.d.ts.map +1 -0
  292. package/dist/modules/mcp/downstream-token-refresh.js +166 -0
  293. package/dist/modules/mcp/downstream-token-refresh.js.map +1 -0
  294. package/dist/modules/mcp/first-call-probe.cli-args.d.ts +78 -0
  295. package/dist/modules/mcp/first-call-probe.cli-args.d.ts.map +1 -0
  296. package/dist/modules/mcp/first-call-probe.cli-args.js +151 -0
  297. package/dist/modules/mcp/first-call-probe.cli-args.js.map +1 -0
  298. package/dist/modules/mcp/first-call-probe.cli.d.ts +2 -0
  299. package/dist/modules/mcp/first-call-probe.cli.d.ts.map +1 -0
  300. package/dist/modules/mcp/first-call-probe.cli.js +62 -0
  301. package/dist/modules/mcp/first-call-probe.cli.js.map +1 -0
  302. package/dist/modules/mcp/first-call-probe.d.ts +165 -0
  303. package/dist/modules/mcp/first-call-probe.d.ts.map +1 -0
  304. package/dist/modules/mcp/first-call-probe.js +298 -0
  305. package/dist/modules/mcp/first-call-probe.js.map +1 -0
  306. package/dist/modules/mcp/manual-failure-memo.d.ts +42 -17
  307. package/dist/modules/mcp/manual-failure-memo.d.ts.map +1 -1
  308. package/dist/modules/mcp/manual-failure-memo.js +79 -23
  309. package/dist/modules/mcp/manual-failure-memo.js.map +1 -1
  310. package/dist/modules/mcp/mcp-auth.middleware.d.ts +9 -5
  311. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
  312. package/dist/modules/mcp/mcp-auth.middleware.js +24 -16
  313. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
  314. package/dist/modules/mcp/mcp.routes.d.ts +4 -4
  315. package/dist/modules/mcp/mcp.routes.d.ts.map +1 -1
  316. package/dist/modules/mcp/mcp.routes.js +83 -179
  317. package/dist/modules/mcp/mcp.routes.js.map +1 -1
  318. package/dist/modules/mcp/mcp.service.d.ts +218 -61
  319. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  320. package/dist/modules/mcp/mcp.service.js +713 -159
  321. package/dist/modules/mcp/mcp.service.js.map +1 -1
  322. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  323. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +8 -2
  324. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  325. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +14 -8
  326. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -1
  327. package/dist/modules/mcp/oauth/oauth-consent.routes.js +16 -2
  328. package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -1
  329. package/dist/modules/mcp/oauth/oauth-state.d.ts +13 -2
  330. package/dist/modules/mcp/oauth/oauth-state.d.ts.map +1 -1
  331. package/dist/modules/mcp/oauth/oauth-state.js +3 -1
  332. package/dist/modules/mcp/oauth/oauth-state.js.map +1 -1
  333. package/dist/modules/mcp/surface-log-throttle.d.ts +59 -0
  334. package/dist/modules/mcp/surface-log-throttle.d.ts.map +1 -0
  335. package/dist/modules/mcp/surface-log-throttle.js +94 -0
  336. package/dist/modules/mcp/surface-log-throttle.js.map +1 -0
  337. package/dist/modules/plugins/compile/compile-marketplace.d.ts +104 -0
  338. package/dist/modules/plugins/compile/compile-marketplace.d.ts.map +1 -0
  339. package/dist/modules/plugins/compile/compile-marketplace.js +323 -0
  340. package/dist/modules/plugins/compile/compile-marketplace.js.map +1 -0
  341. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts +73 -0
  342. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts.map +1 -0
  343. package/dist/modules/plugins/compile/marketplace-compiler.service.js +135 -0
  344. package/dist/modules/plugins/compile/marketplace-compiler.service.js.map +1 -0
  345. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts +37 -0
  346. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts.map +1 -0
  347. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js +158 -0
  348. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js.map +1 -0
  349. package/dist/modules/plugins/discovery/bundle-dialect/registry.d.ts +65 -0
  350. package/dist/modules/plugins/discovery/bundle-dialect/registry.d.ts.map +1 -0
  351. package/dist/modules/plugins/discovery/bundle-dialect/registry.js +204 -0
  352. package/dist/modules/plugins/discovery/bundle-dialect/registry.js.map +1 -0
  353. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts +39 -0
  354. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts.map +1 -0
  355. package/dist/modules/plugins/discovery/kb-plugin-source.js +110 -0
  356. package/dist/modules/plugins/discovery/kb-plugin-source.js.map +1 -0
  357. package/dist/modules/plugins/discovery/native.source.d.ts +16 -0
  358. package/dist/modules/plugins/discovery/native.source.d.ts.map +1 -0
  359. package/dist/modules/plugins/discovery/native.source.js +120 -0
  360. package/dist/modules/plugins/discovery/native.source.js.map +1 -0
  361. package/dist/modules/plugins/discovery/plugin-source.d.ts +110 -0
  362. package/dist/modules/plugins/discovery/plugin-source.d.ts.map +1 -0
  363. package/dist/modules/plugins/discovery/plugin-source.js +2 -0
  364. package/dist/modules/plugins/discovery/plugin-source.js.map +1 -0
  365. package/dist/modules/plugins/index.d.ts +15 -3
  366. package/dist/modules/plugins/index.d.ts.map +1 -1
  367. package/dist/modules/plugins/index.js +13 -2
  368. package/dist/modules/plugins/index.js.map +1 -1
  369. package/dist/modules/plugins/join-request-jobs.service.d.ts +250 -0
  370. package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -0
  371. package/dist/modules/plugins/join-request-jobs.service.js +602 -0
  372. package/dist/modules/plugins/join-request-jobs.service.js.map +1 -0
  373. package/dist/modules/plugins/join-request-records.store.d.ts +161 -0
  374. package/dist/modules/plugins/join-request-records.store.d.ts.map +1 -0
  375. package/dist/modules/plugins/join-request-records.store.js +179 -0
  376. package/dist/modules/plugins/join-request-records.store.js.map +1 -0
  377. package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
  378. package/dist/modules/plugins/join-requests.service.js +4 -2
  379. package/dist/modules/plugins/join-requests.service.js.map +1 -1
  380. package/dist/modules/plugins/plugin-links.d.ts +69 -0
  381. package/dist/modules/plugins/plugin-links.d.ts.map +1 -0
  382. package/dist/modules/plugins/plugin-links.js +163 -0
  383. package/dist/modules/plugins/plugin-links.js.map +1 -0
  384. package/dist/modules/plugins/plugin-links.service.d.ts +111 -0
  385. package/dist/modules/plugins/plugin-links.service.d.ts.map +1 -0
  386. package/dist/modules/plugins/plugin-links.service.js +295 -0
  387. package/dist/modules/plugins/plugin-links.service.js.map +1 -0
  388. package/dist/modules/plugins/plugin-provision.service.d.ts +129 -21
  389. package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
  390. package/dist/modules/plugins/plugin-provision.service.js +320 -75
  391. package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
  392. package/dist/modules/plugins/plugin-rename.service.d.ts +71 -0
  393. package/dist/modules/plugins/plugin-rename.service.d.ts.map +1 -0
  394. package/dist/modules/plugins/plugin-rename.service.js +254 -0
  395. package/dist/modules/plugins/plugin-rename.service.js.map +1 -0
  396. package/dist/modules/plugins/plugins.contract.d.ts +78 -4
  397. package/dist/modules/plugins/plugins.contract.d.ts.map +1 -1
  398. package/dist/modules/plugins/plugins.routes.d.ts +44 -5
  399. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  400. package/dist/modules/plugins/plugins.routes.js +297 -115
  401. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  402. package/dist/modules/plugins/plugins.service.d.ts +82 -3
  403. package/dist/modules/plugins/plugins.service.d.ts.map +1 -1
  404. package/dist/modules/plugins/plugins.service.js +178 -48
  405. package/dist/modules/plugins/plugins.service.js.map +1 -1
  406. package/dist/modules/plugins/plugins.tools.d.ts +25 -0
  407. package/dist/modules/plugins/plugins.tools.d.ts.map +1 -0
  408. package/dist/modules/plugins/plugins.tools.js +82 -0
  409. package/dist/modules/plugins/plugins.tools.js.map +1 -0
  410. package/dist/modules/plugins/teams.routes.d.ts +42 -0
  411. package/dist/modules/plugins/teams.routes.d.ts.map +1 -0
  412. package/dist/modules/plugins/teams.routes.js +79 -0
  413. package/dist/modules/plugins/teams.routes.js.map +1 -0
  414. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts +40 -1
  415. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts.map +1 -1
  416. package/dist/modules/secrets-vault/db-secrets-vault.service.js +202 -37
  417. package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -1
  418. package/dist/modules/secrets-vault/index.d.ts +1 -1
  419. package/dist/modules/secrets-vault/index.d.ts.map +1 -1
  420. package/dist/modules/secrets-vault/index.js.map +1 -1
  421. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.d.ts.map +1 -1
  422. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.js +5 -3
  423. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.js.map +1 -1
  424. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts.map +1 -1
  425. package/dist/modules/secrets-vault/secrets-variable-loader.js +3 -1
  426. package/dist/modules/secrets-vault/secrets-variable-loader.js.map +1 -1
  427. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts +78 -0
  428. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts.map +1 -1
  429. package/dist/modules/secrets-vault/secrets-vault.contract.js +40 -0
  430. package/dist/modules/secrets-vault/secrets-vault.contract.js.map +1 -1
  431. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  432. package/dist/modules/secrets-vault/secrets-vault.routes.js +106 -52
  433. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  434. package/dist/modules/settings/connection-check.d.ts +118 -0
  435. package/dist/modules/settings/connection-check.d.ts.map +1 -0
  436. package/dist/modules/settings/connection-check.js +287 -0
  437. package/dist/modules/settings/connection-check.js.map +1 -0
  438. package/dist/modules/settings/deployment-settings.service.d.ts +157 -2
  439. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  440. package/dist/modules/settings/deployment-settings.service.js +412 -35
  441. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  442. package/dist/modules/settings/git-root-folders.d.ts +54 -0
  443. package/dist/modules/settings/git-root-folders.d.ts.map +1 -0
  444. package/dist/modules/settings/git-root-folders.js +130 -0
  445. package/dist/modules/settings/git-root-folders.js.map +1 -0
  446. package/dist/modules/settings/oidc-check.d.ts +85 -0
  447. package/dist/modules/settings/oidc-check.d.ts.map +1 -0
  448. package/dist/modules/settings/oidc-check.js +172 -0
  449. package/dist/modules/settings/oidc-check.js.map +1 -0
  450. package/dist/modules/settings/setup.routes.d.ts +57 -1
  451. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  452. package/dist/modules/settings/setup.routes.js +408 -108
  453. package/dist/modules/settings/setup.routes.js.map +1 -1
  454. package/dist/modules/skills/allowed-tools-check.d.ts +132 -0
  455. package/dist/modules/skills/allowed-tools-check.d.ts.map +1 -0
  456. package/dist/modules/skills/allowed-tools-check.js +260 -0
  457. package/dist/modules/skills/allowed-tools-check.js.map +1 -0
  458. package/dist/modules/skills/index.d.ts +4 -1
  459. package/dist/modules/skills/index.d.ts.map +1 -1
  460. package/dist/modules/skills/index.js +2 -0
  461. package/dist/modules/skills/index.js.map +1 -1
  462. package/dist/modules/skills/pending-skills.service.d.ts +6 -11
  463. package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
  464. package/dist/modules/skills/pending-skills.service.js +24 -71
  465. package/dist/modules/skills/pending-skills.service.js.map +1 -1
  466. package/dist/modules/skills/skill-access-requests.routes.d.ts +38 -0
  467. package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -0
  468. package/dist/modules/skills/skill-access-requests.routes.js +171 -0
  469. package/dist/modules/skills/skill-access-requests.routes.js.map +1 -0
  470. package/dist/modules/skills/skills.contract.d.ts +67 -2
  471. package/dist/modules/skills/skills.contract.d.ts.map +1 -1
  472. package/dist/modules/skills/skills.routes.d.ts +35 -3
  473. package/dist/modules/skills/skills.routes.d.ts.map +1 -1
  474. package/dist/modules/skills/skills.routes.js +57 -4
  475. package/dist/modules/skills/skills.routes.js.map +1 -1
  476. package/dist/modules/skills/skills.service.d.ts +31 -3
  477. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  478. package/dist/modules/skills/skills.service.js +236 -65
  479. package/dist/modules/skills/skills.service.js.map +1 -1
  480. package/dist/modules/skills/skills.tools.d.ts +4 -1
  481. package/dist/modules/skills/skills.tools.d.ts.map +1 -1
  482. package/dist/modules/skills/skills.tools.js +41 -6
  483. package/dist/modules/skills/skills.tools.js.map +1 -1
  484. package/dist/modules/tool-auth/connection-key-rejection.d.ts +18 -0
  485. package/dist/modules/tool-auth/connection-key-rejection.d.ts.map +1 -0
  486. package/dist/modules/tool-auth/connection-key-rejection.js +20 -0
  487. package/dist/modules/tool-auth/connection-key-rejection.js.map +1 -0
  488. package/dist/modules/tool-auth/connection-keys-admin.routes.d.ts +14 -0
  489. package/dist/modules/tool-auth/connection-keys-admin.routes.d.ts.map +1 -0
  490. package/dist/modules/tool-auth/connection-keys-admin.routes.js +67 -0
  491. package/dist/modules/tool-auth/connection-keys-admin.routes.js.map +1 -0
  492. package/dist/modules/tool-auth/external-api-key.interface.d.ts +66 -1
  493. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
  494. package/dist/modules/tool-auth/external-api-key.interface.js +2 -1
  495. package/dist/modules/tool-auth/external-api-key.interface.js.map +1 -1
  496. package/dist/modules/tool-auth/external-api-key.service.d.ts +23 -4
  497. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  498. package/dist/modules/tool-auth/external-api-key.service.js +79 -19
  499. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  500. package/dist/modules/tool-auth/internal-token.service.d.ts +5 -2
  501. package/dist/modules/tool-auth/internal-token.service.d.ts.map +1 -1
  502. package/dist/modules/tool-auth/internal-token.service.js +5 -2
  503. package/dist/modules/tool-auth/internal-token.service.js.map +1 -1
  504. package/dist/modules/tool-auth/key-or-session.middleware.d.ts +23 -0
  505. package/dist/modules/tool-auth/key-or-session.middleware.d.ts.map +1 -0
  506. package/dist/modules/tool-auth/key-or-session.middleware.js +39 -0
  507. package/dist/modules/tool-auth/key-or-session.middleware.js.map +1 -0
  508. package/dist/modules/tool-auth/tool-auth.middleware.d.ts +7 -1
  509. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
  510. package/dist/modules/tool-auth/tool-auth.middleware.js +8 -5
  511. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
  512. package/dist/modules/tool-helpers/tool-context.d.ts +14 -0
  513. package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
  514. package/dist/modules/tool-helpers/tool-context.js +28 -6
  515. package/dist/modules/tool-helpers/tool-context.js.map +1 -1
  516. package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
  517. package/dist/modules/tool-helpers/tool-handler.js +22 -5
  518. package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
  519. package/dist/modules/tool-helpers/tool.contract.d.ts +6 -1
  520. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
  521. package/dist/modules/tool-helpers/tool.contract.js +7 -1
  522. package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
  523. package/dist/modules/tool-manuals/index.d.ts +2 -1
  524. package/dist/modules/tool-manuals/index.d.ts.map +1 -1
  525. package/dist/modules/tool-manuals/index.js +1 -0
  526. package/dist/modules/tool-manuals/index.js.map +1 -1
  527. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +36 -0
  528. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
  529. package/dist/modules/tool-manuals/mcp-json-discovery.js +136 -96
  530. package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
  531. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts +10 -2
  532. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -1
  533. package/dist/modules/tool-manuals/mcp-server-edit.service.js +12 -15
  534. package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -1
  535. package/dist/modules/tool-manuals/pending-tools.service.d.ts +50 -0
  536. package/dist/modules/tool-manuals/pending-tools.service.d.ts.map +1 -0
  537. package/dist/modules/tool-manuals/pending-tools.service.js +149 -0
  538. package/dist/modules/tool-manuals/pending-tools.service.js.map +1 -0
  539. package/dist/modules/tool-manuals/tool-delete.service.d.ts +135 -0
  540. package/dist/modules/tool-manuals/tool-delete.service.d.ts.map +1 -0
  541. package/dist/modules/tool-manuals/tool-delete.service.js +303 -0
  542. package/dist/modules/tool-manuals/tool-delete.service.js.map +1 -0
  543. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +161 -0
  544. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
  545. package/dist/modules/tool-manuals/tool-manuals.contract.js +9 -0
  546. package/dist/modules/tool-manuals/tool-manuals.contract.js.map +1 -1
  547. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +19 -2
  548. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
  549. package/dist/modules/tool-manuals/tool-manuals.routes.js +127 -57
  550. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
  551. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +121 -2
  552. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  553. package/dist/modules/tool-manuals/tool-manuals.service.js +415 -92
  554. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  555. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  556. package/dist/modules/tool-manuals/tool-manuals.tools.js +78 -6
  557. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  558. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  559. package/dist/modules/workflow/agent-tools/workflow.tools.js +88 -54
  560. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  561. package/dist/modules/workflow/event-bus.d.ts +10 -4
  562. package/dist/modules/workflow/event-bus.d.ts.map +1 -1
  563. package/dist/modules/workflow/event-bus.js +14 -11
  564. package/dist/modules/workflow/event-bus.js.map +1 -1
  565. package/dist/modules/workflow/events.routes.d.ts +17 -2
  566. package/dist/modules/workflow/events.routes.d.ts.map +1 -1
  567. package/dist/modules/workflow/events.routes.js +31 -12
  568. package/dist/modules/workflow/events.routes.js.map +1 -1
  569. package/dist/modules/workflow/file-lock.service.d.ts +22 -4
  570. package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
  571. package/dist/modules/workflow/file-lock.service.js +27 -4
  572. package/dist/modules/workflow/file-lock.service.js.map +1 -1
  573. package/dist/modules/workflow/git/change-request-link.d.ts +20 -0
  574. package/dist/modules/workflow/git/change-request-link.d.ts.map +1 -0
  575. package/dist/modules/workflow/git/change-request-link.js +34 -0
  576. package/dist/modules/workflow/git/change-request-link.js.map +1 -0
  577. package/dist/modules/workflow/git/git-version.d.ts.map +1 -1
  578. package/dist/modules/workflow/git/git-version.js +3 -1
  579. package/dist/modules/workflow/git/git-version.js.map +1 -1
  580. package/dist/modules/workflow/git/git.service.d.ts +303 -6
  581. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  582. package/dist/modules/workflow/git/git.service.js +753 -170
  583. package/dist/modules/workflow/git/git.service.js.map +1 -1
  584. package/dist/modules/workflow/git/node-git-runner.d.ts +36 -0
  585. package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -0
  586. package/dist/modules/workflow/git/node-git-runner.js +273 -0
  587. package/dist/modules/workflow/git/node-git-runner.js.map +1 -0
  588. package/dist/modules/workflow/git/pull-request.service.d.ts +57 -2
  589. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
  590. package/dist/modules/workflow/git/pull-request.service.js +165 -25
  591. package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
  592. package/dist/modules/workflow/pending-commits.service.d.ts +11 -0
  593. package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
  594. package/dist/modules/workflow/pending-commits.service.js +24 -4
  595. package/dist/modules/workflow/pending-commits.service.js.map +1 -1
  596. package/dist/modules/workflow/pending-commits.worker.d.ts +15 -8
  597. package/dist/modules/workflow/pending-commits.worker.d.ts.map +1 -1
  598. package/dist/modules/workflow/pending-commits.worker.js +107 -58
  599. package/dist/modules/workflow/pending-commits.worker.js.map +1 -1
  600. package/dist/modules/workflow/recovery-bot.d.ts.map +1 -1
  601. package/dist/modules/workflow/recovery-bot.js +3 -1
  602. package/dist/modules/workflow/recovery-bot.js.map +1 -1
  603. package/dist/modules/workflow/review-workflow/approval-lock.d.ts +60 -0
  604. package/dist/modules/workflow/review-workflow/approval-lock.d.ts.map +1 -0
  605. package/dist/modules/workflow/review-workflow/approval-lock.js +116 -0
  606. package/dist/modules/workflow/review-workflow/approval-lock.js.map +1 -0
  607. package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts +54 -7
  608. package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts.map +1 -1
  609. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts +64 -0
  610. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
  611. package/dist/modules/workflow/review-workflow/review-workflow.service.js +269 -90
  612. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
  613. package/dist/modules/workflow/sanitize-error.d.ts +5 -2
  614. package/dist/modules/workflow/sanitize-error.d.ts.map +1 -1
  615. package/dist/modules/workflow/sanitize-error.js +8 -4
  616. package/dist/modules/workflow/sanitize-error.js.map +1 -1
  617. package/dist/modules/workflow/workflow.routes.d.ts +2 -0
  618. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
  619. package/dist/modules/workflow/workflow.routes.js +259 -29
  620. package/dist/modules/workflow/workflow.routes.js.map +1 -1
  621. package/dist/modules/workflow/workflow.service.d.ts +217 -14
  622. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  623. package/dist/modules/workflow/workflow.service.js +1142 -109
  624. package/dist/modules/workflow/workflow.service.js.map +1 -1
  625. package/dist/modules/workspace/empty-dirs.d.ts +15 -0
  626. package/dist/modules/workspace/empty-dirs.d.ts.map +1 -0
  627. package/dist/modules/workspace/empty-dirs.js +90 -0
  628. package/dist/modules/workspace/empty-dirs.js.map +1 -0
  629. package/dist/modules/workspace/file-readers/content-mode.d.ts +50 -0
  630. package/dist/modules/workspace/file-readers/content-mode.d.ts.map +1 -0
  631. package/dist/modules/workspace/file-readers/content-mode.js +55 -0
  632. package/dist/modules/workspace/file-readers/content-mode.js.map +1 -0
  633. package/dist/modules/workspace/file-readers/doc-extract.service.d.ts +4 -1
  634. package/dist/modules/workspace/file-readers/doc-extract.service.d.ts.map +1 -1
  635. package/dist/modules/workspace/file-readers/doc-extract.service.js +4 -1
  636. package/dist/modules/workspace/file-readers/doc-extract.service.js.map +1 -1
  637. package/dist/modules/workspace/file-readers/doc-extract.types.d.ts +5 -2
  638. package/dist/modules/workspace/file-readers/doc-extract.types.d.ts.map +1 -1
  639. package/dist/modules/workspace/file-readers/doc-extract.types.js +7 -4
  640. package/dist/modules/workspace/file-readers/doc-extract.types.js.map +1 -1
  641. package/dist/modules/workspace/file-readers/document-reader.d.ts +2 -0
  642. package/dist/modules/workspace/file-readers/document-reader.d.ts.map +1 -1
  643. package/dist/modules/workspace/file-readers/document-reader.js +5 -0
  644. package/dist/modules/workspace/file-readers/document-reader.js.map +1 -1
  645. package/dist/modules/workspace/file-readers/extract-docx.d.ts +6 -0
  646. package/dist/modules/workspace/file-readers/extract-docx.d.ts.map +1 -1
  647. package/dist/modules/workspace/file-readers/extract-docx.js +6 -0
  648. package/dist/modules/workspace/file-readers/extract-docx.js.map +1 -1
  649. package/dist/modules/workspace/file-readers/file-reader.d.ts +24 -5
  650. package/dist/modules/workspace/file-readers/file-reader.d.ts.map +1 -1
  651. package/dist/modules/workspace/file-readers/file-reader.js +11 -6
  652. package/dist/modules/workspace/file-readers/file-reader.js.map +1 -1
  653. package/dist/modules/workspace/file-readers/file-reader.registry.d.ts.map +1 -1
  654. package/dist/modules/workspace/file-readers/file-reader.registry.js +6 -1
  655. package/dist/modules/workspace/file-readers/file-reader.registry.js.map +1 -1
  656. package/dist/modules/workspace/file-readers/image-reader.d.ts +7 -5
  657. package/dist/modules/workspace/file-readers/image-reader.d.ts.map +1 -1
  658. package/dist/modules/workspace/file-readers/image-reader.js +9 -5
  659. package/dist/modules/workspace/file-readers/image-reader.js.map +1 -1
  660. package/dist/modules/workspace/file-readers/ooxml-text.d.ts +3 -0
  661. package/dist/modules/workspace/file-readers/ooxml-text.d.ts.map +1 -1
  662. package/dist/modules/workspace/file-readers/ooxml-text.js +39 -2
  663. package/dist/modules/workspace/file-readers/ooxml-text.js.map +1 -1
  664. package/dist/modules/workspace/file-readers/text-reader.d.ts +29 -1
  665. package/dist/modules/workspace/file-readers/text-reader.d.ts.map +1 -1
  666. package/dist/modules/workspace/file-readers/text-reader.js +57 -3
  667. package/dist/modules/workspace/file-readers/text-reader.js.map +1 -1
  668. package/dist/modules/workspace/git-internals.middleware.d.ts +28 -0
  669. package/dist/modules/workspace/git-internals.middleware.d.ts.map +1 -0
  670. package/dist/modules/workspace/git-internals.middleware.js +93 -0
  671. package/dist/modules/workspace/git-internals.middleware.js.map +1 -0
  672. package/dist/modules/workspace/not-found.d.ts +80 -0
  673. package/dist/modules/workspace/not-found.d.ts.map +1 -0
  674. package/dist/modules/workspace/not-found.js +112 -0
  675. package/dist/modules/workspace/not-found.js.map +1 -0
  676. package/dist/modules/workspace/session-ontology.gate.d.ts +1 -1
  677. package/dist/modules/workspace/session-ontology.gate.d.ts.map +1 -1
  678. package/dist/modules/workspace/session-ontology.gate.js +1 -1
  679. package/dist/modules/workspace/session-ontology.gate.js.map +1 -1
  680. package/dist/modules/workspace/startup/beside-checkout.d.ts +42 -0
  681. package/dist/modules/workspace/startup/beside-checkout.d.ts.map +1 -0
  682. package/dist/modules/workspace/startup/beside-checkout.js +110 -0
  683. package/dist/modules/workspace/startup/beside-checkout.js.map +1 -0
  684. package/dist/modules/workspace/startup/kb-git.d.ts +7 -12
  685. package/dist/modules/workspace/startup/kb-git.d.ts.map +1 -1
  686. package/dist/modules/workspace/startup/kb-git.js +34 -35
  687. package/dist/modules/workspace/startup/kb-git.js.map +1 -1
  688. package/dist/modules/workspace/startup/kb-startup-runner.d.ts +95 -0
  689. package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
  690. package/dist/modules/workspace/startup/kb-startup-runner.js +257 -55
  691. package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
  692. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts +45 -0
  693. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts.map +1 -1
  694. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js +417 -385
  695. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js.map +1 -1
  696. package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts +48 -0
  697. package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts.map +1 -0
  698. package/dist/modules/workspace/startup/steps/personal-spaces.step.js +183 -0
  699. package/dist/modules/workspace/startup/steps/personal-spaces.step.js.map +1 -0
  700. package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts +51 -0
  701. package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts.map +1 -0
  702. package/dist/modules/workspace/startup/steps/plugin-display-names.step.js +158 -0
  703. package/dist/modules/workspace/startup/steps/plugin-display-names.step.js.map +1 -0
  704. package/dist/modules/workspace/startup/steps/plugin-layout.d.ts +64 -0
  705. package/dist/modules/workspace/startup/steps/plugin-layout.d.ts.map +1 -0
  706. package/dist/modules/workspace/startup/steps/plugin-layout.js +97 -0
  707. package/dist/modules/workspace/startup/steps/plugin-layout.js.map +1 -0
  708. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts +41 -0
  709. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts.map +1 -0
  710. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js +85 -0
  711. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js.map +1 -0
  712. package/dist/modules/workspace/startup/steps/roles-yaml.step.d.ts +3 -1
  713. package/dist/modules/workspace/startup/steps/roles-yaml.step.d.ts.map +1 -1
  714. package/dist/modules/workspace/startup/steps/roles-yaml.step.js +4 -12
  715. package/dist/modules/workspace/startup/steps/roles-yaml.step.js.map +1 -1
  716. package/dist/modules/workspace/startup/steps/seed-tree.d.ts +6 -1
  717. package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
  718. package/dist/modules/workspace/startup/steps/seed-tree.js +174 -54
  719. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  720. package/dist/modules/workspace/startup/steps/template-files.step.d.ts +96 -24
  721. package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
  722. package/dist/modules/workspace/startup/steps/template-files.step.js +521 -126
  723. package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
  724. package/dist/modules/workspace/startup/steps/template-source.d.ts +94 -0
  725. package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -0
  726. package/dist/modules/workspace/startup/steps/template-source.js +160 -0
  727. package/dist/modules/workspace/startup/steps/template-source.js.map +1 -0
  728. package/dist/modules/workspace/workspace.routes.d.ts +14 -2
  729. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  730. package/dist/modules/workspace/workspace.routes.js +657 -246
  731. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  732. package/dist/modules/workspace/workspace.service.d.ts +323 -12
  733. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  734. package/dist/modules/workspace/workspace.service.js +1006 -257
  735. package/dist/modules/workspace/workspace.service.js.map +1 -1
  736. package/dist/modules/workspace/workspace.tools.d.ts +42 -1
  737. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  738. package/dist/modules/workspace/workspace.tools.js +1590 -146
  739. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  740. package/dist/modules/workspace/write-denial.d.ts +76 -0
  741. package/dist/modules/workspace/write-denial.d.ts.map +1 -0
  742. package/dist/modules/workspace/write-denial.js +138 -0
  743. package/dist/modules/workspace/write-denial.js.map +1 -0
  744. package/dist/shared/canonical-file-identity.d.ts +64 -0
  745. package/dist/shared/canonical-file-identity.d.ts.map +1 -0
  746. package/dist/shared/canonical-file-identity.js +92 -0
  747. package/dist/shared/canonical-file-identity.js.map +1 -0
  748. package/dist/shared/domain-errors.d.ts +128 -0
  749. package/dist/shared/domain-errors.d.ts.map +1 -1
  750. package/dist/shared/domain-errors.js +166 -0
  751. package/dist/shared/domain-errors.js.map +1 -1
  752. package/dist/shared/email-identity.d.ts +32 -0
  753. package/dist/shared/email-identity.d.ts.map +1 -0
  754. package/dist/shared/email-identity.js +37 -0
  755. package/dist/shared/email-identity.js.map +1 -0
  756. package/dist/shared/fs-errors.d.ts +8 -0
  757. package/dist/shared/fs-errors.d.ts.map +1 -0
  758. package/dist/shared/fs-errors.js +11 -0
  759. package/dist/shared/fs-errors.js.map +1 -0
  760. package/dist/shared/fs-walk.d.ts +20 -6
  761. package/dist/shared/fs-walk.d.ts.map +1 -1
  762. package/dist/shared/fs-walk.js +35 -27
  763. package/dist/shared/fs-walk.js.map +1 -1
  764. package/dist/shared/fs.contract.d.ts +206 -0
  765. package/dist/shared/fs.contract.d.ts.map +1 -0
  766. package/dist/shared/fs.contract.js +79 -0
  767. package/dist/shared/fs.contract.js.map +1 -0
  768. package/dist/shared/git-failure.d.ts +80 -0
  769. package/dist/shared/git-failure.d.ts.map +1 -0
  770. package/dist/shared/git-failure.js +139 -0
  771. package/dist/shared/git-failure.js.map +1 -0
  772. package/dist/shared/git-internals.d.ts +17 -0
  773. package/dist/shared/git-internals.d.ts.map +1 -0
  774. package/dist/shared/git-internals.js +123 -0
  775. package/dist/shared/git-internals.js.map +1 -0
  776. package/dist/shared/git.contract.d.ts +157 -0
  777. package/dist/shared/git.contract.d.ts.map +1 -0
  778. package/dist/shared/git.contract.js +103 -0
  779. package/dist/shared/git.contract.js.map +1 -0
  780. package/dist/shared/http-errors.d.ts +33 -0
  781. package/dist/shared/http-errors.d.ts.map +1 -0
  782. package/dist/shared/http-errors.js +35 -0
  783. package/dist/shared/http-errors.js.map +1 -0
  784. package/dist/shared/kb-walk.d.ts +52 -0
  785. package/dist/shared/kb-walk.d.ts.map +1 -0
  786. package/dist/shared/kb-walk.js +76 -0
  787. package/dist/shared/kb-walk.js.map +1 -0
  788. package/dist/shared/logger.contract.d.ts +63 -0
  789. package/dist/shared/logger.contract.d.ts.map +1 -0
  790. package/dist/shared/logger.contract.js +126 -0
  791. package/dist/shared/logger.contract.js.map +1 -0
  792. package/dist/shared/logging.d.ts +31 -0
  793. package/dist/shared/logging.d.ts.map +1 -0
  794. package/dist/shared/logging.js +92 -0
  795. package/dist/shared/logging.js.map +1 -0
  796. package/dist/shared/path-containment.d.ts +21 -0
  797. package/dist/shared/path-containment.d.ts.map +1 -0
  798. package/dist/shared/path-containment.js +34 -0
  799. package/dist/shared/path-containment.js.map +1 -0
  800. package/dist/shared/path-order.d.ts +18 -0
  801. package/dist/shared/path-order.d.ts.map +1 -0
  802. package/dist/shared/path-order.js +35 -0
  803. package/dist/shared/path-order.js.map +1 -0
  804. package/dist/shared/pending-proposals.d.ts +71 -0
  805. package/dist/shared/pending-proposals.d.ts.map +1 -0
  806. package/dist/shared/pending-proposals.js +98 -0
  807. package/dist/shared/pending-proposals.js.map +1 -0
  808. package/dist/shared/printable.d.ts +22 -0
  809. package/dist/shared/printable.d.ts.map +1 -0
  810. package/dist/shared/printable.js +65 -0
  811. package/dist/shared/printable.js.map +1 -0
  812. package/dist/shared/redact-secret.d.ts +30 -0
  813. package/dist/shared/redact-secret.d.ts.map +1 -0
  814. package/dist/shared/redact-secret.js +114 -0
  815. package/dist/shared/redact-secret.js.map +1 -0
  816. package/dist/shared/rename-no-replace.d.ts +119 -0
  817. package/dist/shared/rename-no-replace.d.ts.map +1 -0
  818. package/dist/shared/rename-no-replace.js +323 -0
  819. package/dist/shared/rename-no-replace.js.map +1 -0
  820. package/dist/shared/ssrf.d.ts.map +1 -1
  821. package/dist/shared/ssrf.js +49 -18
  822. package/dist/shared/ssrf.js.map +1 -1
  823. package/dist/shared/ttl-cache.d.ts +28 -1
  824. package/dist/shared/ttl-cache.d.ts.map +1 -1
  825. package/dist/shared/ttl-cache.js +33 -1
  826. package/dist/shared/ttl-cache.js.map +1 -1
  827. package/dist/version.d.ts +10 -6
  828. package/dist/version.d.ts.map +1 -1
  829. package/dist/version.js +10 -6
  830. package/dist/version.js.map +1 -1
  831. package/kb-template/.bevelignore +4 -3
  832. package/kb-template/AGENTS.md +364 -54
  833. package/kb-template/KnowledgeBase/How to get started.md +1 -1
  834. package/kb-template/Skills/.gitkeep +0 -0
  835. package/kb-template/access.md +5 -3
  836. package/kb-template/mcp-description.md +27 -0
  837. package/migrations/0005_github_facade.sql +25 -0
  838. package/migrations/0006_api_tokens_revoked_by.sql +1 -0
  839. package/migrations/0007_github_facade_registered.sql +1 -0
  840. package/migrations/0008_change_request_apply_failure.sql +4 -0
  841. package/migrations/0009_change_request_apply_failure_kind.sql +13 -0
  842. package/migrations/0010_plugin_join_requests.sql +15 -0
  843. package/migrations/0011_plugin_join_request_claim.sql +11 -0
  844. package/migrations/meta/0005_snapshot.json +1717 -0
  845. package/migrations/meta/0006_snapshot.json +1723 -0
  846. package/migrations/meta/0007_snapshot.json +1729 -0
  847. package/migrations/meta/0008_snapshot.json +1753 -0
  848. package/migrations/meta/0009_snapshot.json +1759 -0
  849. package/migrations/meta/0010_snapshot.json +1872 -0
  850. package/migrations/meta/0011_snapshot.json +1884 -0
  851. package/migrations/meta/_journal.json +49 -0
  852. package/package.json +8 -7
  853. package/src/__tests__/core-config.domain.test.ts +67 -2
  854. package/src/__tests__/kb-layout-config.test.ts +295 -0
  855. package/src/__tests__/open-change-gate.ts +15 -0
  856. package/src/core/__tests__/catalog-cache-invalidation.test.ts +226 -0
  857. package/src/core/__tests__/catalog-revision.test.ts +190 -0
  858. package/src/core/__tests__/lifecycle.test.ts +369 -0
  859. package/src/core/__tests__/public-config.test.ts +30 -0
  860. package/src/core/__tests__/readiness.test.ts +109 -0
  861. package/src/core/catalog-cache-invalidation.ts +111 -0
  862. package/src/core/catalog-revision.ts +110 -0
  863. package/src/core/create-core-server.ts +358 -63
  864. package/src/core/create-core-services.ts +449 -107
  865. package/src/core/lifecycle.ts +312 -0
  866. package/src/core/public-config.ts +86 -0
  867. package/src/core/readiness.ts +123 -0
  868. package/src/core-config.ts +70 -4
  869. package/src/index.ts +15 -0
  870. package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +362 -0
  871. package/src/modules/access/__tests__/access-control.atref-batch.test.ts +2 -1
  872. package/src/modules/access/__tests__/access-control.atref-cache.test.ts +46 -22
  873. package/src/modules/access/__tests__/access-control.deny-dependents.test.ts +215 -0
  874. package/src/modules/access/__tests__/access-control.download-read.test.ts +268 -0
  875. package/src/modules/access/__tests__/access-control.everyone-read.test.ts +145 -0
  876. package/src/modules/access/__tests__/access-control.group-read.test.ts +163 -0
  877. package/src/modules/access/__tests__/access-control.invalidate-race.test.ts +88 -0
  878. package/src/modules/access/__tests__/access-control.platform-restore.test.ts +152 -0
  879. package/src/modules/access/__tests__/access-control.prospective.test.ts +189 -0
  880. package/src/modules/access/__tests__/access-control.read-batch.test.ts +2 -1
  881. package/src/modules/access/__tests__/access-control.service.test.ts +142 -81
  882. package/src/modules/access/__tests__/access-groups.test.ts +47 -14
  883. package/src/modules/access/__tests__/access-md-format.test.ts +2 -1
  884. package/src/modules/access/__tests__/access-mutation.service.test.ts +52 -4
  885. package/src/modules/access/__tests__/access-own-read-grant.test.ts +2 -0
  886. package/src/modules/access/__tests__/access-personal-plugin.test.ts +153 -0
  887. package/src/modules/access/__tests__/access-plugin-principals.test.ts +385 -0
  888. package/src/modules/access/__tests__/access-restrict-here.test.ts +450 -0
  889. package/src/modules/access/__tests__/access.routes.batch.test.ts +139 -0
  890. package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +394 -0
  891. package/src/modules/access/__tests__/access.routes.group-grant.test.ts +6 -2
  892. package/src/modules/access/__tests__/access.routes.overrides.test.ts +3 -2
  893. package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +234 -0
  894. package/src/modules/access/__tests__/access.routes.prospective.test.ts +216 -0
  895. package/src/modules/access/__tests__/access.routes.revoke.test.ts +7 -2
  896. package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +360 -0
  897. package/src/modules/access/__tests__/change-read-gate.test.ts +272 -0
  898. package/src/modules/access/__tests__/creator-access.test.ts +81 -83
  899. package/src/modules/access/__tests__/grant-sources.test.ts +3 -2
  900. package/src/modules/access/__tests__/groups-admin.service.test.ts +14 -5
  901. package/src/modules/access/__tests__/roles-admin.security.test.ts +196 -0
  902. package/src/modules/access/__tests__/roles-admin.service.test.ts +127 -2
  903. package/src/modules/access/__tests__/roles-capabilities.test.ts +5 -4
  904. package/src/modules/access/__tests__/roles.routes.test.ts +5 -2
  905. package/src/modules/access/__tests__/user-access-removal.service.test.ts +402 -0
  906. package/src/modules/access/__tests__/users-db-double.ts +63 -0
  907. package/src/modules/access/access-control.interface.ts +269 -18
  908. package/src/modules/access/access-control.service.ts +943 -226
  909. package/src/modules/access/access-mutation.service.ts +182 -13
  910. package/src/modules/access/access-view.ts +316 -0
  911. package/src/modules/access/access.routes.ts +385 -105
  912. package/src/modules/access/admin-locked-commit.ts +12 -14
  913. package/src/modules/access/admin-route-helpers.ts +4 -4
  914. package/src/modules/access/change-read-gate.ts +148 -0
  915. package/src/modules/access/creator-access.ts +89 -124
  916. package/src/modules/access/directory-sync-bot.ts +4 -1
  917. package/src/modules/access/groups-admin.service.ts +3 -3
  918. package/src/modules/access/reference-scan.ts +5 -5
  919. package/src/modules/access/roles-admin.service.ts +94 -15
  920. package/src/modules/access/synced-groups-committer.ts +10 -15
  921. package/src/modules/access/synced-groups-writer.ts +3 -12
  922. package/src/modules/access/user-access-removal.service.ts +711 -0
  923. package/src/modules/access-model/__tests__/access-grammar.test.ts +18 -0
  924. package/src/modules/access-model/__tests__/access-splice.test.ts +63 -1
  925. package/src/modules/access-model/__tests__/frontmatter-fences.test.ts +71 -0
  926. package/src/modules/access-model/__tests__/plugin-token-canonical.test.ts +40 -0
  927. package/src/modules/access-model/__tests__/roles-yaml-guard.test.ts +131 -0
  928. package/src/modules/access-model/access-errors.ts +56 -15
  929. package/src/modules/access-model/access-grammar.ts +198 -49
  930. package/src/modules/access-model/access-splice.ts +18 -18
  931. package/src/modules/access-model/access-template.ts +44 -0
  932. package/src/modules/access-model/change-gate.ts +80 -0
  933. package/src/modules/access-model/creator.ts +18 -21
  934. package/src/modules/access-model/frontmatter-lines.ts +98 -0
  935. package/src/modules/access-model/group-files.ts +4 -0
  936. package/src/modules/access-model/plugin-principals.ts +130 -0
  937. package/src/modules/access-model/roles-yaml-guard.ts +182 -4
  938. package/src/modules/admin/admin-access.service.ts +6 -2
  939. package/src/modules/agent-instructions/__tests__/agent-instructions.route.test.ts +100 -0
  940. package/src/modules/agent-instructions/__tests__/compose.test.ts +256 -0
  941. package/src/modules/agent-instructions/__tests__/read-preamble.test.ts +135 -0
  942. package/src/modules/agent-instructions/agent-instructions.routes.ts +41 -0
  943. package/src/modules/agent-instructions/compose.ts +271 -0
  944. package/src/modules/agent-instructions/index.ts +14 -0
  945. package/src/modules/agent-instructions/read-preamble.ts +88 -0
  946. package/src/modules/auth/__tests__/account-erasure.approval-gate.test.ts +209 -0
  947. package/src/modules/auth/__tests__/account.routes.test.ts +178 -2
  948. package/src/modules/auth/__tests__/auth.middleware.test.ts +78 -0
  949. package/src/modules/auth/__tests__/auth.service.test.ts +338 -5
  950. package/src/modules/auth/__tests__/oidc-auth-provider.test.ts +352 -12
  951. package/src/modules/auth/__tests__/onboarding-done.route.test.ts +3 -1
  952. package/src/modules/auth/account-erasure.service.ts +117 -10
  953. package/src/modules/auth/account.routes.ts +115 -14
  954. package/src/modules/auth/auth.routes.ts +20 -7
  955. package/src/modules/auth/auth.service.ts +187 -28
  956. package/src/modules/auth/oidc-auth-provider.ts +120 -22
  957. package/src/modules/code-mode/__tests__/code-mode.tool.test.ts +109 -1
  958. package/src/modules/code-mode/code-mode.tool.ts +13 -2
  959. package/src/modules/connection-probe/__tests__/connection-probe.service.test.ts +78 -0
  960. package/src/modules/connection-probe/connection-probe.service.ts +59 -7
  961. package/src/modules/database/__tests__/advisory-lease.test.ts +152 -0
  962. package/src/modules/database/__tests__/advisory-lock.test.ts +147 -0
  963. package/src/modules/database/advisory-lock.ts +346 -0
  964. package/src/modules/database/connection.ts +9 -1
  965. package/src/modules/database/core-schema.ts +177 -0
  966. package/src/modules/database/migrate.ts +27 -6
  967. package/src/modules/declared-variables/declared-variables.routes.ts +6 -3
  968. package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +3 -0
  969. package/src/modules/diff/__tests__/diff.service.test.ts +3 -0
  970. package/src/modules/diff/diff.routes.ts +2 -4
  971. package/src/modules/diff/diff.service.ts +75 -79
  972. package/src/modules/kb-fs/__tests__/locking-filesystem.test.ts +472 -9
  973. package/src/modules/kb-fs/__tests__/node-fs.test.ts +409 -0
  974. package/src/modules/kb-fs/__tests__/repo-path.test.ts +210 -1
  975. package/src/modules/{workspace → kb-fs}/bevel-ignore.ts +22 -15
  976. package/src/modules/kb-fs/file-change-notifier.ts +4 -1
  977. package/src/modules/kb-fs/git-guarded-filesystem.ts +123 -0
  978. package/src/modules/kb-fs/locking-filesystem.ts +399 -109
  979. package/src/modules/kb-fs/node-fs.ts +165 -0
  980. package/src/modules/kb-fs/read-only-filesystem.ts +18 -9
  981. package/src/modules/kb-fs/repo-path.ts +213 -3
  982. package/src/modules/kb-sync/__tests__/kb-sync.routes.test.ts +297 -0
  983. package/src/modules/kb-sync/__tests__/kb-sync.service.test.ts +295 -0
  984. package/src/modules/kb-sync/__tests__/sync-auth.test.ts +118 -0
  985. package/src/modules/kb-sync/__tests__/sync-payload.test.ts +148 -0
  986. package/src/modules/kb-sync/index.ts +19 -0
  987. package/src/modules/kb-sync/kb-sync.interface.ts +79 -0
  988. package/src/modules/kb-sync/kb-sync.routes.ts +200 -0
  989. package/src/modules/kb-sync/kb-sync.service.ts +204 -0
  990. package/src/modules/kb-sync/sync-auth.ts +118 -0
  991. package/src/modules/kb-sync/sync-payload.ts +143 -0
  992. package/src/modules/marketplace/__tests__/github-facade.test.ts +575 -0
  993. package/src/modules/marketplace/__tests__/marketplace-git.test.ts +180 -0
  994. package/src/modules/marketplace/__tests__/marketplace-repo.head.test.ts +47 -0
  995. package/src/modules/marketplace/git-http.routes.ts +196 -0
  996. package/src/modules/marketplace/github-facade/github-facade-admin.routes.ts +110 -0
  997. package/src/modules/marketplace/github-facade/github-facade-codes.store.ts +145 -0
  998. package/src/modules/marketplace/github-facade/github-facade-credentials.service.ts +263 -0
  999. package/src/modules/marketplace/github-facade/github-facade.routes.ts +294 -0
  1000. package/src/modules/marketplace/github-facade/github-facade.service.ts +282 -0
  1001. package/src/modules/marketplace/github-facade/index.ts +26 -0
  1002. package/src/modules/marketplace/index.ts +3 -0
  1003. package/src/modules/marketplace/marketplace-repo.service.ts +352 -0
  1004. package/src/modules/mcp/__tests__/downstream-pool.test.ts +278 -0
  1005. package/src/modules/mcp/__tests__/downstream-token-refresh.test.ts +178 -0
  1006. package/src/modules/mcp/__tests__/fake-downstream-mcp-server.ts +156 -0
  1007. package/src/modules/mcp/__tests__/first-call-probe.cli-args.test.ts +178 -0
  1008. package/src/modules/mcp/__tests__/first-call-probe.test.ts +414 -0
  1009. package/src/modules/mcp/__tests__/manual-failure-memo.test.ts +98 -6
  1010. package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +8 -5
  1011. package/src/modules/mcp/__tests__/mcp-routes-harness.ts +1 -3
  1012. package/src/modules/mcp/__tests__/mcp.e2e.test.ts +1055 -59
  1013. package/src/modules/mcp/__tests__/mcp.routes.stateless.test.ts +182 -0
  1014. package/src/modules/mcp/__tests__/mcp.service.test.ts +274 -6
  1015. package/src/modules/mcp/__tests__/surface-log-throttle.test.ts +169 -0
  1016. package/src/modules/mcp/downstream-pool.ts +256 -0
  1017. package/src/modules/mcp/downstream-token-refresh.ts +170 -0
  1018. package/src/modules/mcp/first-call-probe.cli-args.ts +159 -0
  1019. package/src/modules/mcp/first-call-probe.cli.ts +60 -0
  1020. package/src/modules/mcp/first-call-probe.ts +418 -0
  1021. package/src/modules/mcp/manual-failure-memo.ts +81 -23
  1022. package/src/modules/mcp/mcp-auth.middleware.ts +25 -16
  1023. package/src/modules/mcp/mcp.routes.ts +376 -482
  1024. package/src/modules/mcp/mcp.service.ts +846 -176
  1025. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +8 -2
  1026. package/src/modules/mcp/oauth/oauth-consent.routes.ts +28 -6
  1027. package/src/modules/mcp/oauth/oauth-state.ts +15 -3
  1028. package/src/modules/mcp/surface-log-throttle.ts +120 -0
  1029. package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +166 -0
  1030. package/src/modules/plugins/__tests__/bundle-dialect.test.ts +165 -0
  1031. package/src/modules/plugins/__tests__/compile-marketplace.test.ts +423 -0
  1032. package/src/modules/plugins/__tests__/fake-join-request-store.ts +189 -0
  1033. package/src/modules/plugins/__tests__/join-request-jobs.service.test.ts +608 -0
  1034. package/src/modules/plugins/__tests__/plugin-creation-display-name.test.ts +241 -0
  1035. package/src/modules/plugins/__tests__/plugin-index.service.test.ts +201 -16
  1036. package/src/modules/plugins/__tests__/plugin-links.service.test.ts +284 -0
  1037. package/src/modules/plugins/__tests__/plugin-names.test.ts +77 -0
  1038. package/src/modules/plugins/__tests__/plugin-provision.service.test.ts +330 -20
  1039. package/src/modules/plugins/__tests__/plugin-rename.service.test.ts +456 -0
  1040. package/src/modules/plugins/__tests__/plugins.routes.test.ts +441 -43
  1041. package/src/modules/plugins/__tests__/plugins.tools.test.ts +131 -0
  1042. package/src/modules/plugins/__tests__/teams.routes.test.ts +248 -0
  1043. package/src/modules/plugins/compile/compile-marketplace.ts +500 -0
  1044. package/src/modules/plugins/compile/marketplace-compiler.service.ts +151 -0
  1045. package/src/modules/plugins/discovery/__tests__/kb-plugin-source.test.ts +365 -0
  1046. package/src/modules/plugins/discovery/bundle-dialect/bundle.source.ts +161 -0
  1047. package/src/modules/plugins/discovery/bundle-dialect/registry.ts +250 -0
  1048. package/src/modules/plugins/discovery/kb-plugin-source.ts +117 -0
  1049. package/src/modules/plugins/discovery/native.source.ts +140 -0
  1050. package/src/modules/plugins/discovery/plugin-source.ts +113 -0
  1051. package/src/modules/plugins/index.ts +25 -2
  1052. package/src/modules/plugins/join-request-jobs.service.ts +675 -0
  1053. package/src/modules/plugins/join-request-records.store.ts +353 -0
  1054. package/src/modules/plugins/join-requests.service.ts +7 -4
  1055. package/src/modules/plugins/plugin-links.service.ts +350 -0
  1056. package/src/modules/plugins/plugin-links.ts +187 -0
  1057. package/src/modules/plugins/plugin-provision.service.ts +356 -78
  1058. package/src/modules/plugins/plugin-rename.service.ts +310 -0
  1059. package/src/modules/plugins/plugins.contract.ts +79 -4
  1060. package/src/modules/plugins/plugins.routes.ts +320 -123
  1061. package/src/modules/plugins/plugins.service.ts +184 -57
  1062. package/src/modules/plugins/plugins.tools.ts +88 -0
  1063. package/src/modules/plugins/teams.routes.ts +129 -0
  1064. package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +359 -15
  1065. package/src/modules/secrets-vault/__tests__/db-secrets-vault.oauth.test.ts +248 -0
  1066. package/src/modules/secrets-vault/__tests__/namespace-secrets.test.ts +202 -0
  1067. package/src/modules/secrets-vault/db-secrets-vault.service.ts +217 -35
  1068. package/src/modules/secrets-vault/index.ts +1 -0
  1069. package/src/modules/secrets-vault/mcp-oauth-discovery.service.ts +6 -3
  1070. package/src/modules/secrets-vault/secrets-variable-loader.ts +4 -4
  1071. package/src/modules/secrets-vault/secrets-vault.contract.ts +93 -0
  1072. package/src/modules/secrets-vault/secrets-vault.routes.ts +99 -38
  1073. package/src/modules/settings/__tests__/connection-check.test.ts +233 -0
  1074. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +240 -1
  1075. package/src/modules/settings/__tests__/git-root-folders.test.ts +247 -0
  1076. package/src/modules/settings/__tests__/oidc-check.test.ts +185 -0
  1077. package/src/modules/settings/__tests__/setup.routes.boot-failure.test.ts +119 -0
  1078. package/src/modules/settings/__tests__/setup.routes.layout-phase.test.ts +170 -0
  1079. package/src/modules/settings/__tests__/setup.routes.oidc.test.ts +555 -0
  1080. package/src/modules/settings/__tests__/setup.routes.sync-status.test.ts +77 -0
  1081. package/src/modules/settings/__tests__/setup.routes.test.ts +667 -16
  1082. package/src/modules/settings/connection-check.ts +351 -0
  1083. package/src/modules/settings/deployment-settings.service.ts +478 -39
  1084. package/src/modules/settings/git-root-folders.ts +171 -0
  1085. package/src/modules/settings/oidc-check.ts +229 -0
  1086. package/src/modules/settings/setup.routes.ts +480 -110
  1087. package/src/modules/skills/__tests__/allowed-tools-check.test.ts +224 -0
  1088. package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +210 -0
  1089. package/src/modules/skills/__tests__/pending-skills.service.test.ts +3 -3
  1090. package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +128 -0
  1091. package/src/modules/skills/__tests__/skills.routes.warnings.test.ts +91 -0
  1092. package/src/modules/skills/__tests__/skills.service.test.ts +308 -2
  1093. package/src/modules/skills/allowed-tools-check.ts +352 -0
  1094. package/src/modules/skills/index.ts +5 -0
  1095. package/src/modules/skills/pending-skills.service.ts +26 -85
  1096. package/src/modules/skills/skill-access-requests.routes.ts +203 -0
  1097. package/src/modules/skills/skills.contract.ts +67 -3
  1098. package/src/modules/skills/skills.routes.ts +75 -4
  1099. package/src/modules/skills/skills.service.ts +258 -66
  1100. package/src/modules/skills/skills.tools.ts +43 -5
  1101. package/src/modules/tool-auth/__tests__/connection-key-rejection.test.ts +192 -0
  1102. package/src/modules/tool-auth/__tests__/connection-keys-admin.routes.test.ts +116 -0
  1103. package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +124 -0
  1104. package/src/modules/tool-auth/connection-key-rejection.ts +25 -0
  1105. package/src/modules/tool-auth/connection-keys-admin.routes.ts +76 -0
  1106. package/src/modules/tool-auth/external-api-key.interface.ts +73 -1
  1107. package/src/modules/tool-auth/external-api-key.service.ts +95 -29
  1108. package/src/modules/tool-auth/internal-token.service.ts +5 -2
  1109. package/src/modules/tool-auth/key-or-session.middleware.ts +45 -0
  1110. package/src/modules/tool-auth/tool-auth.middleware.ts +16 -7
  1111. package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +228 -0
  1112. package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +33 -4
  1113. package/src/modules/tool-helpers/tool-context.ts +46 -7
  1114. package/src/modules/tool-helpers/tool-handler.ts +23 -5
  1115. package/src/modules/tool-helpers/tool.contract.ts +5 -0
  1116. package/src/modules/tool-manuals/__tests__/mcp-json-discovery.test.ts +24 -1
  1117. package/src/modules/tool-manuals/__tests__/mcp-server-edit.service.test.ts +2 -1
  1118. package/src/modules/tool-manuals/__tests__/pending-tools.service.test.ts +411 -0
  1119. package/src/modules/tool-manuals/__tests__/tool-delete.route.test.ts +133 -0
  1120. package/src/modules/tool-manuals/__tests__/tool-delete.service.test.ts +469 -0
  1121. package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +21 -2
  1122. package/src/modules/tool-manuals/__tests__/tool-manuals.cli.test.ts +11 -4
  1123. package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +6 -1
  1124. package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.routes.test.ts +254 -0
  1125. package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.test.ts +577 -0
  1126. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +6 -1
  1127. package/src/modules/tool-manuals/__tests__/tool-manuals.pending.route.test.ts +102 -0
  1128. package/src/modules/tool-manuals/__tests__/tool-manuals.restart.test.ts +285 -0
  1129. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +178 -2
  1130. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +114 -2
  1131. package/src/modules/tool-manuals/index.ts +3 -0
  1132. package/src/modules/tool-manuals/mcp-json-discovery.ts +164 -95
  1133. package/src/modules/tool-manuals/mcp-server-edit.service.ts +11 -14
  1134. package/src/modules/tool-manuals/pending-tools.service.ts +179 -0
  1135. package/src/modules/tool-manuals/tool-delete.service.ts +401 -0
  1136. package/src/modules/tool-manuals/tool-manuals.contract.ts +165 -0
  1137. package/src/modules/tool-manuals/tool-manuals.routes.ts +138 -54
  1138. package/src/modules/tool-manuals/tool-manuals.service.ts +440 -104
  1139. package/src/modules/tool-manuals/tool-manuals.tools.ts +81 -6
  1140. package/src/modules/workflow/__tests__/apply-failure.test.ts +1038 -0
  1141. package/src/modules/workflow/__tests__/event-bus.test.ts +61 -9
  1142. package/src/modules/workflow/__tests__/fake-file-lock-db.ts +199 -0
  1143. package/src/modules/workflow/__tests__/file-lock.service.path-identity.test.ts +237 -0
  1144. package/src/modules/workflow/__tests__/format-affected-owners.test.ts +18 -0
  1145. package/src/modules/workflow/__tests__/merge-announces-tree.test.ts +220 -0
  1146. package/src/modules/workflow/__tests__/pending-commits.worker.concurrency.test.ts +187 -0
  1147. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +3 -1
  1148. package/src/modules/workflow/__tests__/sanitize-error.test.ts +10 -0
  1149. package/src/modules/workflow/__tests__/workflow.routes.folder-proposals.test.ts +128 -0
  1150. package/src/modules/workflow/__tests__/workflow.routes.fork-point-file.test.ts +149 -0
  1151. package/src/modules/workflow/__tests__/workflow.routes.lock-path.test.ts +305 -0
  1152. package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +2 -0
  1153. package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +3 -0
  1154. package/src/modules/workflow/__tests__/workflow.service.deleted-branch-sweep.test.ts +2 -0
  1155. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +296 -27
  1156. package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +564 -0
  1157. package/src/modules/workflow/__tests__/workflow.service.platform-restore.test.ts +135 -0
  1158. package/src/modules/workflow/__tests__/workflow.service.read-gate.test.ts +172 -0
  1159. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +133 -2
  1160. package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +442 -0
  1161. package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +281 -0
  1162. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +158 -7
  1163. package/src/modules/workflow/agent-tools/workflow.tools.ts +93 -64
  1164. package/src/modules/workflow/event-bus.ts +26 -28
  1165. package/src/modules/workflow/events.routes.ts +56 -21
  1166. package/src/modules/workflow/file-lock.service.ts +27 -4
  1167. package/src/modules/workflow/git/__tests__/change-request-link.test.ts +43 -0
  1168. package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +1 -0
  1169. package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +238 -1
  1170. package/src/modules/workflow/git/__tests__/git.service.forkPoint.test.ts +245 -0
  1171. package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +35 -0
  1172. package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +149 -0
  1173. package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +3 -3
  1174. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +47 -4
  1175. package/src/modules/workflow/git/__tests__/git.service.revertPathsAndPush.test.ts +177 -0
  1176. package/src/modules/workflow/git/__tests__/git.service.syncFromRemote.test.ts +253 -0
  1177. package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +114 -0
  1178. package/src/modules/workflow/git/__tests__/pull-request.service.getPrDetail.test.ts +69 -2
  1179. package/src/modules/workflow/git/__tests__/pull-request.service.list-fetch.test.ts +121 -0
  1180. package/src/modules/workflow/git/__tests__/pull-request.service.placeholder.test.ts +79 -0
  1181. package/src/modules/workflow/git/__tests__/pull-request.service.test.ts +1 -1
  1182. package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-cancel.test.ts +1 -1
  1183. package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-update.test.ts +111 -0
  1184. package/src/modules/workflow/git/change-request-link.ts +35 -0
  1185. package/src/modules/workflow/git/git-version.ts +5 -2
  1186. package/src/modules/workflow/git/git.service.ts +922 -199
  1187. package/src/modules/workflow/git/node-git-runner.ts +315 -0
  1188. package/src/modules/workflow/git/pull-request.service.ts +188 -27
  1189. package/src/modules/workflow/pending-commits.service.ts +26 -7
  1190. package/src/modules/workflow/pending-commits.worker.ts +114 -69
  1191. package/src/modules/workflow/recovery-bot.ts +4 -1
  1192. package/src/modules/workflow/review-workflow/__tests__/approval-states.test.ts +180 -1
  1193. package/src/modules/workflow/review-workflow/__tests__/cancel-pr.test.ts +1 -1
  1194. package/src/modules/workflow/review-workflow/__tests__/carry-approvals-forward.test.ts +520 -0
  1195. package/src/modules/workflow/review-workflow/__tests__/erase-approver.test.ts +84 -0
  1196. package/src/modules/workflow/review-workflow/__tests__/merge-gate.test.ts +89 -77
  1197. package/src/modules/workflow/review-workflow/approval-lock.ts +122 -0
  1198. package/src/modules/workflow/review-workflow/review-workflow.interface.ts +59 -7
  1199. package/src/modules/workflow/review-workflow/review-workflow.service.ts +309 -105
  1200. package/src/modules/workflow/sanitize-error.ts +9 -4
  1201. package/src/modules/workflow/workflow.routes.ts +273 -29
  1202. package/src/modules/workflow/workflow.service.ts +1341 -174
  1203. package/src/modules/workspace/__tests__/empty-dirs.test.ts +44 -0
  1204. package/src/modules/workspace/__tests__/file-stat-access.test.ts +301 -0
  1205. package/src/modules/workspace/__tests__/git-internals.security.test.ts +792 -0
  1206. package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +464 -0
  1207. package/src/modules/workspace/__tests__/workspace.routes.branch-errors.test.ts +139 -0
  1208. package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +189 -37
  1209. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +51 -11
  1210. package/src/modules/workspace/__tests__/workspace.routes.download-implies-read.test.ts +161 -0
  1211. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +109 -10
  1212. package/src/modules/workspace/__tests__/workspace.routes.file-writes.test.ts +624 -0
  1213. package/src/modules/workspace/__tests__/workspace.routes.folders.test.ts +409 -0
  1214. package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +327 -0
  1215. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +31 -13
  1216. package/src/modules/workspace/__tests__/workspace.service.ensure-remotes-fetched.test.ts +109 -0
  1217. package/src/modules/workspace/__tests__/workspace.service.list-cloned.test.ts +94 -0
  1218. package/src/modules/workspace/__tests__/workspace.service.missing-branch.test.ts +28 -0
  1219. package/src/modules/workspace/__tests__/workspace.service.move-never-overwrites.test.ts +218 -0
  1220. package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +98 -13
  1221. package/src/modules/workspace/__tests__/workspace.service.test.ts +811 -42
  1222. package/src/modules/workspace/__tests__/workspace.service.unknown-branch.test.ts +197 -0
  1223. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +128 -0
  1224. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +212 -0
  1225. package/src/modules/workspace/__tests__/workspace.tools.test.ts +2632 -110
  1226. package/src/modules/workspace/__tests__/write-denial.test.ts +75 -0
  1227. package/src/modules/workspace/empty-dirs.ts +79 -0
  1228. package/src/modules/workspace/file-readers/README.md +32 -0
  1229. package/src/modules/workspace/file-readers/__tests__/doc-extract.test.ts +59 -2
  1230. package/src/modules/workspace/file-readers/__tests__/file-reader.registry.test.ts +133 -4
  1231. package/src/modules/workspace/file-readers/__tests__/fixtures/soft-break.docx +0 -0
  1232. package/src/modules/workspace/file-readers/__tests__/fixtures/tab.docx +0 -0
  1233. package/src/modules/workspace/file-readers/content-mode.ts +87 -0
  1234. package/src/modules/workspace/file-readers/doc-extract.service.ts +4 -1
  1235. package/src/modules/workspace/file-readers/doc-extract.types.ts +8 -4
  1236. package/src/modules/workspace/file-readers/document-reader.ts +6 -0
  1237. package/src/modules/workspace/file-readers/extract-docx.ts +6 -0
  1238. package/src/modules/workspace/file-readers/file-reader.registry.ts +9 -1
  1239. package/src/modules/workspace/file-readers/file-reader.ts +27 -6
  1240. package/src/modules/workspace/file-readers/image-reader.ts +10 -5
  1241. package/src/modules/workspace/file-readers/ooxml-text.ts +38 -2
  1242. package/src/modules/workspace/file-readers/text-reader.ts +61 -4
  1243. package/src/modules/workspace/git-internals.middleware.ts +86 -0
  1244. package/src/modules/workspace/not-found.ts +119 -0
  1245. package/src/modules/workspace/session-ontology.gate.ts +1 -1
  1246. package/src/modules/workspace/startup/__tests__/beside-checkout.test.ts +181 -0
  1247. package/src/modules/workspace/startup/__tests__/kb-startup-runner.degraded.test.ts +361 -0
  1248. package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +53 -16
  1249. package/src/modules/workspace/startup/beside-checkout.ts +112 -0
  1250. package/src/modules/workspace/startup/kb-git.ts +43 -36
  1251. package/src/modules/workspace/startup/kb-startup-runner.ts +303 -63
  1252. package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +1405 -48
  1253. package/src/modules/workspace/startup/steps/groups-to-plugins.step.ts +460 -417
  1254. package/src/modules/workspace/startup/steps/personal-spaces.step.ts +191 -0
  1255. package/src/modules/workspace/startup/steps/plugin-display-names.step.ts +169 -0
  1256. package/src/modules/workspace/startup/steps/plugin-layout.ts +110 -0
  1257. package/src/modules/workspace/startup/steps/plugin-manifests.step.ts +90 -0
  1258. package/src/modules/workspace/startup/steps/roles-yaml.step.ts +6 -12
  1259. package/src/modules/workspace/startup/steps/seed-tree.ts +177 -54
  1260. package/src/modules/workspace/startup/steps/template-files.step.ts +581 -126
  1261. package/src/modules/workspace/startup/steps/template-source.ts +168 -0
  1262. package/src/modules/workspace/workspace.routes.ts +691 -269
  1263. package/src/modules/workspace/workspace.service.ts +1071 -292
  1264. package/src/modules/workspace/workspace.tools.ts +1787 -180
  1265. package/src/modules/workspace/write-denial.ts +189 -0
  1266. package/src/shared/__tests__/canonical-file-identity.test.ts +154 -0
  1267. package/src/shared/__tests__/email-identity.test.ts +35 -0
  1268. package/src/shared/__tests__/filename.test.ts +0 -0
  1269. package/src/shared/__tests__/frontmatter-id.test.ts +5 -0
  1270. package/src/shared/__tests__/git-failure.test.ts +198 -0
  1271. package/src/shared/__tests__/git-internals.test.ts +115 -0
  1272. package/src/shared/__tests__/http-errors.test.ts +42 -0
  1273. package/src/shared/__tests__/logging.test.ts +185 -0
  1274. package/src/shared/__tests__/path-containment.test.ts +60 -0
  1275. package/src/shared/__tests__/path-order.test.ts +24 -0
  1276. package/src/shared/__tests__/pending-proposals.readAt.test.ts +102 -0
  1277. package/src/shared/__tests__/printable.test.ts +64 -0
  1278. package/src/shared/__tests__/redact-secret.test.ts +122 -0
  1279. package/src/shared/__tests__/rename-no-replace.test.ts +466 -0
  1280. package/src/shared/__tests__/ssrf.test.ts +20 -0
  1281. package/src/shared/__tests__/ttl-cache.test.ts +55 -0
  1282. package/src/shared/canonical-file-identity.ts +92 -0
  1283. package/src/shared/domain-errors.ts +178 -0
  1284. package/src/shared/email-identity.ts +38 -0
  1285. package/src/shared/fs.contract.ts +225 -0
  1286. package/src/shared/git-failure.ts +196 -0
  1287. package/src/shared/git-internals.ts +124 -0
  1288. package/src/shared/git.contract.ts +170 -0
  1289. package/src/shared/http-errors.ts +36 -0
  1290. package/src/shared/logger.contract.ts +141 -0
  1291. package/src/shared/logging.ts +96 -0
  1292. package/src/shared/path-containment.ts +34 -0
  1293. package/src/shared/path-order.ts +33 -0
  1294. package/src/shared/pending-proposals.ts +161 -0
  1295. package/src/shared/printable.ts +68 -0
  1296. package/src/shared/redact-secret.ts +118 -0
  1297. package/src/shared/rename-no-replace.ts +386 -0
  1298. package/src/shared/ssrf.ts +44 -16
  1299. package/src/shared/ttl-cache.ts +33 -1
  1300. package/src/version.ts +10 -6
  1301. package/src/modules/diff/diff-paths.ts +0 -9
  1302. package/src/modules/mcp/__tests__/mcp-session-store.test.ts +0 -151
  1303. package/src/modules/mcp/__tests__/mcp.routes.session.test.ts +0 -226
  1304. package/src/modules/mcp/mcp-session-store.ts +0 -162
  1305. package/src/shared/__tests__/fs-walk.test.ts +0 -42
  1306. package/src/shared/fs-walk.ts +0 -30
  1307. package/src/shared/hash-email.ts +0 -14
@@ -1,5 +1,6 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
+ import { logger } from '../../../../shared/logging.js';
3
4
  import {
4
5
  HEXIS_EXTENSION_NS,
5
6
  HEXIS_TOOLS_DIR,
@@ -15,81 +16,18 @@ import type { ToolManualDescriptor } from '../../../tool-manuals/tool-manuals.co
15
16
  import { normalizeToolManual } from '../../../tool-manuals/tool-manuals.service.js';
16
17
  import { parseOwnAccessEntries } from '../../../access-model/access-grammar.js';
17
18
  import { containsVariableReference } from '../../../../shared/variable-refs.js';
18
- import { IGNORE_FILENAME } from '../../bevel-ignore.js';
19
+ import { IGNORE_FILENAME, isAbsence, isSkippedEntry, type IFsProbe, type ITreeWalker } from '../../../../shared/fs.contract.js';
19
20
  import type { KbBranch, OnServerStart, ServerStartContext, StepResult } from '../on-server-start.js';
21
+ import { withoutIgnoreLine } from './template-files.step.js';
22
+ import { PluginLayout, hasManifestEntry } from './plugin-layout.js';
20
23
 
21
- /**
22
- * One-way migration of a knowledge base from `Groups/` to the Agent Plugins
23
- * layout under `Plugins/` (https://agent-plugins.org, v1.0.0), as an
24
- * {@link OnServerStart} step. (It began life as an in-place module run from
25
- * the lazy top-up; that path is gone, and this is the only form.) Steps
26
- * never write: every change is DECLARED on the branch handle
27
- * (`move`/`write`/`remove`) and the runner applies it, while every read goes
28
- * against the real, pre-step tree via `repoDir()`.
29
- *
30
- * Idempotent: a KB already on the new layout is untouched, and a half-finished
31
- * run is completed by the next one.
32
- *
33
- * What moves — and what CONVERTS:
34
- *
35
- * Groups/GTM/access.md → Plugins/GTM/access.md (stays put)
36
- * Groups/GTM/deploy/SKILL.md → Plugins/GTM/skills/deploy/SKILL.md
37
- * Groups/GTM/web-search.tool → Plugins/GTM/software.bevel.hexis/tools/web-search.tool
38
- * Groups/GTM/notion.tool (mcp) → an entry in Plugins/GTM/mcp.json, and the
39
- * `.tool` file is DELETED — mcp.json is
40
- * authoritative for MCP servers now.
41
- * Plugins/GTM/plugin.json (written)
42
- *
43
- * The mcp.json entry is keyed by the `.tool`'s manual id: that id is the
44
- * namespace vault secrets bind to (`<id>_<VAR>`), so keeping it is what keeps
45
- * every configured secret and completed OAuth grant bound. What mcp.json
46
- * cannot carry — auth headers with `${VAR}` references, variable declarations,
47
- * the local-only flag — moves into `plugin.json`'s
48
- * `extensions["software.bevel.hexis"].mcpServers[<id>]` block, the reverse-DNS
49
- * namespace the spec reserves for client-specific data. `http`/`inline`
50
- * manuals still MOVE as `.tool` files: nothing but this platform can run them.
51
- *
52
- * Scope: EVERY branch, drafts included and writable (`ctx.allBranches()`) —
53
- * maintenance applied uniformly at the quiet moment is what keeps a draft's
54
- * change-request diff down to the user's own changes; a stale draft against a
55
- * migrated target would diff by the whole rename.
56
- *
57
- * Outcomes: a per-manual NOT-converted refusal makes the step `partial` with
58
- * the reasons (the declared ops for everything else still apply); a branch
59
- * carrying BOTH roots contributes nothing but a note; everything else is `ok`.
60
- */
61
- export class GroupsToPluginsStep implements OnServerStart {
62
- readonly name = 'groups-to-plugins';
24
+ const log = logger('groups-to-plugins');
63
25
 
64
- async run(ctx: ServerStartContext): Promise<StepResult> {
65
- const refusals: string[] = [];
66
- for (const branch of await ctx.allBranches()) {
67
- await migrateBranch(branch, refusals);
68
- }
69
- return refusals.length > 0 ? { outcome: 'partial', reason: refusals.join('; ') } : { outcome: 'ok' };
70
- }
71
- }
72
-
73
- // lstat, both helpers: SYMLINKS ARE NOT SUPPORTED IN PLUGINS, anywhere, so a
74
- // link never counts as the thing it points at — following one here would let
75
- // a symlinked directory pull files from outside the plugin into the sweep
76
- // (and delete them from wherever they really live).
77
- async function exists(p: string): Promise<boolean> {
78
- try {
79
- await fs.lstat(p);
80
- return true;
81
- } catch {
82
- return false;
83
- }
84
- }
85
-
86
- async function isDir(p: string): Promise<boolean> {
87
- try {
88
- return (await fs.lstat(p)).isDirectory();
89
- } catch {
90
- return false;
91
- }
92
- }
26
+ // The probes here are `lstat`-based (`exists`, `isDirectory`): SYMLINKS ARE
27
+ // NOT SUPPORTED IN PLUGINS, anywhere, so a link never counts as the thing it
28
+ // points at — following one here would let a symlinked directory pull files
29
+ // from outside the plugin into the sweep (and delete them from wherever they
30
+ // really live).
93
31
 
94
32
  /**
95
33
  * A header value referencing a vault variable rather than carrying a literal.
@@ -115,18 +53,6 @@ function splitHeaders(headers: Record<string, string> | undefined): {
115
53
  return { literal, credential };
116
54
  }
117
55
 
118
- /** Read+parse a JSON file, or `null` when absent or unparsable. */
119
- async function readJson(p: string): Promise<Record<string, unknown> | null> {
120
- try {
121
- const parsed: unknown = JSON.parse(await fs.readFile(p, 'utf-8'));
122
- return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)
123
- ? (parsed as Record<string, unknown>)
124
- : null;
125
- } catch {
126
- return null;
127
- }
128
- }
129
-
130
56
  /**
131
57
  * Parse a `.tool`; a convertible MCP manual (has a url) parses to a
132
58
  * descriptor. A non-candidate (other types, a file that will not parse)
@@ -134,6 +60,10 @@ async function readJson(p: string): Promise<Record<string, unknown> | null> {
134
60
  * comes back as the reason string, so the migration log distinguishes a
135
61
  * deliberately-retained integration from one that silently failed — the
136
62
  * same courtesy the manifest-missing refusal already extends.
63
+ *
64
+ * A free function, not a method: it reads ONE file it is handed the path of
65
+ * and decides from the bytes. Nothing about it varies with the step's
66
+ * collaborators.
137
67
  */
138
68
  async function asMcpManual(abs: string, repoRel: string): Promise<ToolManualDescriptor | string | null> {
139
69
  try {
@@ -188,374 +118,487 @@ interface ConvertedManual {
188
118
  }
189
119
 
190
120
  /**
191
- * Migrate one branch. Declares ops only; a branch whose migration declares
192
- * nothing stays clean, so a notes-only pass (advisory refusals) commits
193
- * nothing — the same contract the in-place migration's `migrated` flag
194
- * carried.
121
+ * One-way migration of a knowledge base from `Groups/` to the Agent Plugins
122
+ * layout under `Plugins/` (https://agent-plugins.org, v1.0.0), as an
123
+ * {@link OnServerStart} step. (It began life as an in-place module run from
124
+ * the lazy top-up; that path is gone, and this is the only form.) Steps
125
+ * never write: every change is DECLARED on the branch handle
126
+ * (`move`/`write`/`remove`) and the runner applies it, while every read goes
127
+ * against the real, pre-step tree via `repoDir()`.
128
+ *
129
+ * Idempotent: a KB already on the new layout is untouched, and a half-finished
130
+ * run is completed by the next one.
131
+ *
132
+ * What moves — and what CONVERTS:
133
+ *
134
+ * Groups/GTM/access.md → Plugins/GTM/access.md (stays put)
135
+ * Groups/GTM/deploy/SKILL.md → Plugins/GTM/skills/deploy/SKILL.md
136
+ * Groups/GTM/web-search.tool → Plugins/GTM/software.bevel.hexis/tools/web-search.tool
137
+ * Groups/GTM/notion.tool (mcp) → an entry in Plugins/GTM/mcp.json, and the
138
+ * `.tool` file is DELETED — mcp.json is
139
+ * authoritative for MCP servers now.
140
+ * Plugins/GTM/plugin.json (written)
141
+ *
142
+ * The mcp.json entry is keyed by the `.tool`'s manual id: that id is the
143
+ * namespace vault secrets bind to (`<id>_<VAR>`), so keeping it is what keeps
144
+ * every configured secret and completed OAuth grant bound. What mcp.json
145
+ * cannot carry — auth headers with `${VAR}` references, variable declarations,
146
+ * the local-only flag — moves into `plugin.json`'s
147
+ * `extensions["software.bevel.hexis"].mcpServers[<id>]` block, the reverse-DNS
148
+ * namespace the spec reserves for client-specific data. `http`/`inline`
149
+ * manuals still MOVE as `.tool` files: nothing but this platform can run them.
150
+ *
151
+ * Scope: EVERY branch, drafts included and writable (`ctx.allBranches()`) —
152
+ * maintenance applied uniformly at the quiet moment is what keeps a draft's
153
+ * change-request diff down to the user's own changes; a stale draft against a
154
+ * migrated target would diff by the whole rename.
155
+ *
156
+ * Outcomes: a per-manual NOT-converted refusal makes the step `partial` with
157
+ * the reasons (the declared ops for everything else still apply); a branch
158
+ * carrying BOTH roots contributes nothing but a note; everything else is `ok`.
195
159
  */
196
- async function migrateBranch(branch: KbBranch, refusals: string[]): Promise<void> {
197
- const repoDir = await branch.repoDir();
198
- const legacyDir = path.join(repoDir, LEGACY_GROUPS_DIR);
199
- const pluginsDir = path.join(repoDir, PLUGINS_DIR);
200
-
201
- const hasLegacy = await isDir(legacyDir);
202
- const hasPlugins = await isDir(pluginsDir);
203
-
204
- // `hasPlugins` is false for a FILE or SYMLINK squatting the `Plugins` name.
205
- // Checked BEFORE the nothing-to-do early return below: a branch with a
206
- // squatter and NO Groups/ would otherwise be silently skipped (and on a
207
- // draft nothing later ever reports it), while a branch mid-migration would
208
- // die in the applier with a bare ENOTDIR. Throw the actionable version
209
- // either way: under the phase's fail-closed contract this stops the boot,
210
- // which a squatted reserved root deserves (same stance as
211
- // template-files.step.ts's reserved-dir check).
212
- if (!hasPlugins && (await exists(pluginsDir))) {
213
- throw new Error(
214
- `Branch "${branch.name}": "${PLUGINS_DIR}" exists but is not a directory` +
215
- (hasLegacy ? `, so ${LEGACY_GROUPS_DIR}/ cannot be renamed to ${PLUGINS_DIR}/` : '') +
216
- `. Remove or rename the "${PLUGINS_DIR}" entry — the platform requires this name to be a folder.`,
217
- );
218
- }
160
+ export class GroupsToPluginsStep implements OnServerStart {
161
+ readonly name = 'groups-to-plugins';
219
162
 
220
- if (hasLegacy && hasPlugins) {
221
- // Both present: somebody is mid-migration by hand, or two branches merged
222
- // badly. Merging them here would guess at which copy of a same-named
223
- // plugin wins, so we refuse and say so — loudly, because the KB is in a
224
- // state a human needs to look at. The branch contributes no ops, only a
225
- // note (which surfaces in a commit only if a later step dirties it).
226
- console.warn(
227
- `[groups-to-plugins] ${branch.name}: both ${LEGACY_GROUPS_DIR}/ and ${PLUGINS_DIR}/ exist — leaving both alone. ` +
228
- `Merge ${LEGACY_GROUPS_DIR}/ into ${PLUGINS_DIR}/ by hand; nothing is being migrated automatically.`,
229
- );
230
- branch.note(
231
- `${LEGACY_GROUPS_DIR}/ and ${PLUGINS_DIR}/ both exist — merge by hand; nothing was migrated automatically`,
232
- );
233
- return;
234
- }
235
- if (!hasLegacy && !hasPlugins) return;
236
-
237
- // Every read below goes against the PRE-STEP tree: when the root rename is
238
- // declared this run it is NOT yet on disk, so the plugin folders are still
239
- // read under their legacy root while every declared op speaks post-rename
240
- // `Plugins/…` paths — the root move is declared FIRST, so by the time the
241
- // per-folder ops apply, the tree is already under `Plugins/`.
242
- const rootOnDisk = hasLegacy ? legacyDir : pluginsDir;
243
- // Detail notes are held back until we know ops were declared: the subject
244
- // line must describe a commit that will actually exist.
245
- const details: string[] = [];
246
- let changed = false;
247
-
248
- if (hasLegacy) {
249
- // The Groups→Plugins root rename is ONE declared op, directory and all.
250
- branch.move(LEGACY_GROUPS_DIR, PLUGINS_DIR);
251
- details.push(`${LEGACY_GROUPS_DIR}/ → ${PLUGINS_DIR}/`);
252
- changed = true;
253
- // Rides WITH the rename, not on every run: the rename is what turned the
254
- // ignore rule stale, so the run that renames is the run that heals it.
255
- changed = (await rewriteIgnoreRootRule(repoDir, branch, details)) || changed;
256
- }
163
+ /** The plugin-shaped questions, answered the same way the manifests step answers them. */
164
+ private readonly layout: PluginLayout;
257
165
 
258
- // Runs whether or not the rename just happened, so a KB already on
259
- // `Plugins/` still gets missing manifests and any half-done reorganisation
260
- // finished. That is what makes this idempotent rather than once-only.
261
- for (const entry of await fs.readdir(rootOnDisk, { withFileTypes: true })) {
262
- if (!entry.isDirectory() || entry.name.startsWith('.')) continue;
263
- const folderChanged = await migratePluginFolder(
264
- branch,
265
- path.join(rootOnDisk, entry.name),
266
- entry.name,
267
- details,
268
- refusals,
269
- );
270
- changed = changed || folderChanged;
166
+ constructor(private readonly disk: IFsProbe & ITreeWalker) {
167
+ this.layout = new PluginLayout(disk);
271
168
  }
272
169
 
273
- if (!changed) return;
274
- // First note becomes the commit subject — the same messages the lazy
275
- // top-up committed under; the detail notes become its body.
276
- branch.note(
277
- hasLegacy
278
- ? `Move ${LEGACY_GROUPS_DIR}/ to ${PLUGINS_DIR}/ (Agent Plugins layout)`
279
- : `Reorganise ${PLUGINS_DIR}/ to the Agent Plugins layout`,
280
- );
281
- for (const line of details) branch.note(line);
282
- }
283
-
284
- /**
285
- * Rewrite the KB's `.bevelignore` rule for the renamed root: the exact line
286
- * `Groups/` becomes `Plugins/`. Without this a migrated KB is left with a
287
- * stale rule for a folder that no longer exists and NO rule for the new one,
288
- * so plugin internals start showing up in the file tree and agent view.
289
- *
290
- * The file is the operator's — this touches ONE line, the one the platform's
291
- * own rename invalidated, and only when `Plugins/` is not already listed
292
- * (in which case the stale line is harmlessly dead and left alone).
293
- */
294
- async function rewriteIgnoreRootRule(repoDir: string, branch: KbBranch, details: string[]): Promise<boolean> {
295
- let current: string;
296
- try {
297
- current = await fs.readFile(path.join(repoDir, IGNORE_FILENAME), 'utf-8');
298
- } catch {
299
- return false; // no ignore file — nothing went stale
170
+ async run(ctx: ServerStartContext): Promise<StepResult> {
171
+ const refusals: string[] = [];
172
+ for (const branch of await ctx.allBranches()) {
173
+ await this.migrateBranch(branch, refusals);
174
+ }
175
+ return refusals.length > 0 ? { outcome: 'partial', reason: refusals.join('; ') } : { outcome: 'ok' };
300
176
  }
301
- const legacyRule = `${LEGACY_GROUPS_DIR}/`;
302
- const newRule = `${PLUGINS_DIR}/`;
303
- const lines = current.split('\n');
304
- if (lines.some((l) => l.trim() === newRule)) return false;
305
- const idx = lines.findIndex((l) => l.trim() === legacyRule);
306
- if (idx === -1) return false;
307
- // EVERY exact-match line follows the rename: the first becomes the new
308
- // rule, any further duplicates are dropped — rewriting only the first would
309
- // leave stale `Groups/` lines behind, and the already-has-Plugins guard
310
- // above means a second pass would never touch them.
311
- lines[idx] = newRule;
312
- const rewritten = lines.filter((l, i) => i <= idx || l.trim() !== legacyRule);
313
- branch.write(IGNORE_FILENAME, rewritten.join('\n'));
314
- details.push(`${IGNORE_FILENAME}: ${legacyRule} → ${newRule}`);
315
- return true;
316
- }
317
177
 
318
- /**
319
- * Reorganise ONE plugin folder. `folderDir` is where the folder sits ON DISK
320
- * (under the legacy root when the rename is buffered this run); declared op
321
- * paths always speak `Plugins/<folder>/…`. Returns whether ops were declared.
322
- */
323
- async function migratePluginFolder(
324
- branch: KbBranch,
325
- folderDir: string,
326
- folderName: string,
327
- details: string[],
328
- refusals: string[],
329
- ): Promise<boolean> {
330
- const relPlugin = `${PLUGINS_DIR}/${folderName}`;
331
- let changed = false;
332
-
333
- // When the manifest is written this run its content is remembered: the
334
- // buffered write is not on disk yet, and the fold below must see it.
335
- let renderedManifest: string | null = null;
336
- if (!(await exists(path.join(folderDir, PLUGIN_MANIFEST_FILE)))) {
337
- renderedManifest = renderPluginManifest(folderName);
338
- branch.write(`${relPlugin}/${PLUGIN_MANIFEST_FILE}`, renderedManifest);
339
- details.push(`${folderName}: wrote ${PLUGIN_MANIFEST_FILE}`);
340
- changed = true;
341
- }
178
+ /**
179
+ * Migrate one branch. Declares ops only; a branch whose migration declares
180
+ * nothing stays clean, so a notes-only pass (advisory refusals) commits
181
+ * nothing — the same contract the in-place migration's `migrated` flag
182
+ * carried.
183
+ */
184
+ private async migrateBranch(branch: KbBranch, refusals: string[]): Promise<void> {
185
+ const repoDir = await branch.repoDir();
186
+ const legacyDir = path.join(repoDir, LEGACY_GROUPS_DIR);
187
+ const pluginsDir = path.join(repoDir, PLUGINS_DIR);
188
+
189
+ const hasLegacy = await this.disk.isDirectory(legacyDir);
190
+ const hasPlugins = await this.disk.isDirectory(pluginsDir);
191
+
192
+ // `hasPlugins` is false for a FILE or SYMLINK squatting the `Plugins` name.
193
+ // Checked BEFORE the nothing-to-do early return below: a branch with a
194
+ // squatter and NO Groups/ would otherwise be silently skipped (and on a
195
+ // draft nothing later ever reports it), while a branch mid-migration would
196
+ // die in the applier with a bare ENOTDIR. Throw the actionable version
197
+ // either way: under the phase's fail-closed contract this stops the boot,
198
+ // which a squatted reserved root deserves (same stance as
199
+ // template-files.step.ts's reserved-dir check).
200
+ if (!hasPlugins && (await this.disk.exists(pluginsDir))) {
201
+ throw new Error(
202
+ `Branch "${branch.name}": "${PLUGINS_DIR}" exists but is not a directory` +
203
+ (hasLegacy ? `, so ${LEGACY_GROUPS_DIR}/ cannot be renamed to ${PLUGINS_DIR}/` : '') +
204
+ `. Remove or rename the "${PLUGINS_DIR}" entry — the platform requires this name to be a folder.`,
205
+ );
206
+ }
342
207
 
343
- const entries = await fs.readdir(folderDir, { withFileTypes: true });
344
- const converted: ConvertedManual[] = [];
345
-
346
- const convertOrMove = async (abs: string, rel: string, note: string): Promise<void> => {
347
- const manual = await asMcpManual(abs, rel);
348
- if (manual !== null && typeof manual !== 'string') {
349
- // QUEUED for conversion — the `.tool`'s removal is declared only AFTER
350
- // its entry's writes (see foldIntoPluginFiles). Buffering makes the
351
- // apply all-or-nothing anyway, but the declaration order keeps the old
352
- // recovery reasoning legible: the file IS the recovery path until the
353
- // fold has landed.
354
- converted.push({ manual, rel, note });
208
+ // Detail notes are held back until we know ops were declared: the subject
209
+ // line must describe a commit that will actually exist.
210
+ const details: string[] = [];
211
+ // On EVERY run and every branch, whatever roots it has: the two root
212
+ // rules are stale for one reason (the plugins root is drawn by the sidebar
213
+ // now), and a draft migrated by an earlier release carries the `Plugins/`
214
+ // line that release wrote — the template step, which retires it on the
215
+ // protected branches, never visits a draft. BEFORE the early returns: a
216
+ // branch with both roots (refused below) or neither (nothing to migrate)
217
+ // is no less stale. Idempotent: nothing to drop, nothing declared.
218
+ const changed = await this.retireIgnoreRootRules(repoDir, branch, details);
219
+ const retiredSubject = `Retire the stale ${LEGACY_GROUPS_DIR}/ and ${PLUGINS_DIR}/ ignore rules`;
220
+
221
+ if (hasLegacy && hasPlugins) {
222
+ // Both present: somebody is mid-migration by hand, or two branches merged
223
+ // badly. Merging them here would guess at which copy of a same-named
224
+ // plugin wins, so we refuse and say so — loudly, because the KB is in a
225
+ // state a human needs to look at. The branch contributes no migration
226
+ // ops, only a note (which surfaces in a commit only if the ignore
227
+ // retirement above, or a later step, dirties it).
228
+ log.warn(
229
+ `${branch.name}: both ${LEGACY_GROUPS_DIR}/ and ${PLUGINS_DIR}/ exist — leaving both alone. ` +
230
+ `Merge ${LEGACY_GROUPS_DIR}/ into ${PLUGINS_DIR}/ by hand; nothing is being migrated automatically.`,
231
+ );
232
+ if (changed) branch.note(retiredSubject);
233
+ branch.note(
234
+ `${LEGACY_GROUPS_DIR}/ and ${PLUGINS_DIR}/ both exist — merge by hand; nothing was migrated automatically`,
235
+ );
236
+ for (const line of details) branch.note(line);
237
+ return;
238
+ }
239
+ if (!hasLegacy && !hasPlugins) {
240
+ if (!changed) return;
241
+ branch.note(retiredSubject);
242
+ for (const line of details) branch.note(line);
355
243
  return;
356
244
  }
357
- if (typeof manual === 'string') {
358
- // The operator's answer to "why is this integration not in mcp.json":
359
- // a refused conversion must read as the deliberate retention it is —
360
- // surfaced through the step's `partial` reason rather than a note, so
361
- // it names what did NOT change instead of decorating a commit.
362
- refusals.push(`${branch.name}: ${folderName}: ${note} NOT converted — ${manual}; kept as a .tool`);
245
+
246
+ // Every read below goes against the PRE-STEP tree: when the root rename is
247
+ // declared this run it is NOT yet on disk, so the plugin folders are still
248
+ // read under their legacy root while every declared op speaks post-rename
249
+ // `Plugins/…` paths — the root move is declared FIRST, so by the time the
250
+ // per-folder ops apply, the tree is already under `Plugins/`.
251
+ const rootOnDisk = hasLegacy ? legacyDir : pluginsDir;
252
+
253
+ // Whether any MIGRATION op was declared — apart from the ignore retirement
254
+ // above, which is its own subject when it is all that happened.
255
+ let migrated = false;
256
+ if (hasLegacy) {
257
+ // The Groups→Plugins root rename is ONE declared op, directory and all.
258
+ branch.move(LEGACY_GROUPS_DIR, PLUGINS_DIR);
259
+ details.push(`${LEGACY_GROUPS_DIR}/ → ${PLUGINS_DIR}/`);
260
+ migrated = true;
363
261
  }
364
- const destDisk = path.join(folderDir, ...HEXIS_TOOLS_DIR.split('/'), path.basename(abs));
365
- // Never overwrite: a destination that already exists means a previous run
366
- // got there first (or a human did), and clobbering it would destroy the
367
- // newer copy. The check is against the pre-step tree — the only tree that
368
- // exists while this step runs.
369
- if (abs !== destDisk && !(await exists(destDisk))) {
370
- branch.move(rel, `${relPlugin}/${HEXIS_TOOLS_DIR}/${path.basename(abs)}`);
371
- details.push(`${folderName}: ${note} → ${HEXIS_TOOLS_DIR}/${path.basename(abs)}`);
372
- changed = true;
262
+
263
+ // Runs whether or not the rename just happened, so a KB already on
264
+ // `Plugins/` still gets missing manifests and any half-done reorganisation
265
+ // finished. That is what makes this idempotent rather than once-only.
266
+ // The catalog walk's own skip list: a vendored `node_modules` under the
267
+ // root is nobody's plugin, and this step must not reorganise it.
268
+ for (const entry of (await this.disk.listDir(rootOnDisk)) ?? []) {
269
+ if (!entry.isDirectory() || isSkippedEntry(entry.name)) continue;
270
+ const folderChanged = await this.migratePluginFolder(
271
+ branch,
272
+ path.join(rootOnDisk, entry.name),
273
+ entry.name,
274
+ details,
275
+ refusals,
276
+ );
277
+ migrated = migrated || folderChanged;
373
278
  }
374
- };
375
279
 
376
- for (const entry of entries) {
377
- if (entry.name.startsWith('.')) continue;
378
- if (entry.name === PLUGIN_SKILLS_DIR || entry.name === PLUGIN_MANIFEST_FILE) continue;
379
- if (entry.name === PLUGIN_MCP_FILE || entry.name === 'access.md') continue;
380
- if (entry.name === HEXIS_TOOLS_DIR.split('/')[0]) continue;
280
+ if (!changed && !migrated) return;
281
+ // First note becomes the commit subject — the same messages the lazy
282
+ // top-up committed under; the detail notes become its body. The subject
283
+ // names what happened: a branch that only lost its stale ignore rules
284
+ // was not reorganised.
285
+ branch.note(
286
+ hasLegacy
287
+ ? `Move ${LEGACY_GROUPS_DIR}/ to ${PLUGINS_DIR}/ (Agent Plugins layout)`
288
+ : migrated
289
+ ? `Reorganise ${PLUGINS_DIR}/ to the Agent Plugins layout`
290
+ : retiredSubject,
291
+ );
292
+ for (const line of details) branch.note(line);
293
+ }
381
294
 
382
- const abs = path.join(folderDir, entry.name);
295
+ /**
296
+ * Retire the KB's `.bevelignore` rules for the plugins root, old name and
297
+ * new: every exact `Groups/` and `Plugins/` line goes. `Groups/` used to
298
+ * become `Plugins/` — the rename's companion edit, so plugin internals
299
+ * stayed out of the file tree and the agent view. The plugins root is no
300
+ * longer hidden at all (the Skills & Tools sidebar draws it as a file tree
301
+ * read from the workspace tree), so the old rule has nothing to become and
302
+ * the new one is as stale as it: a KB this step migrated under an earlier
303
+ * release carries the `Plugins/` line that release wrote, on every branch
304
+ * it visited — drafts included, which the template step never reaches.
305
+ *
306
+ * The file is the operator's — this touches only the lines the platform's
307
+ * own root rules put there. Every exact match goes, not just the first: a
308
+ * duplicate left behind would be found again on every boot and never
309
+ * touched, since the first pass is what makes the run a no-op. A `!…`
310
+ * negation is not the rule and stays.
311
+ */
312
+ private async retireIgnoreRootRules(repoDir: string, branch: KbBranch, details: string[]): Promise<boolean> {
313
+ let current: string;
314
+ try {
315
+ current = await fs.readFile(path.join(repoDir, IGNORE_FILENAME), 'utf-8');
316
+ } catch (err) {
317
+ // No ignore file — nothing went stale. Anything else (a directory in
318
+ // its place, a permission hole) is NOT "no file": a rule that may still
319
+ // be there would hide the tree while the run reports success, so the
320
+ // hole surfaces as the step's failure instead.
321
+ if (isAbsence(err)) return false;
322
+ throw err;
323
+ }
324
+ const stale = [`${LEGACY_GROUPS_DIR}/`, `${PLUGINS_DIR}/`];
325
+ const present = stale.filter((rule) => current.split('\n').some((l) => l.trim() === rule));
326
+ if (present.length === 0) return false;
327
+ // The same drop the template step makes, so a platform comment above a
328
+ // rule, and the blank line that opened an appended block, go with it.
329
+ const merged = present.reduce((text, rule) => withoutIgnoreLine(text, rule), current);
330
+ branch.write(IGNORE_FILENAME, merged);
331
+ details.push(`${IGNORE_FILENAME}: ${present.join(', ')} dropped`);
332
+ return true;
333
+ }
383
334
 
384
- // A skill is a folder carrying SKILL.md — the same rule the catalog uses.
385
- if (entry.isDirectory() && (await exists(path.join(abs, 'SKILL.md')))) {
386
- if (!(await exists(path.join(folderDir, PLUGIN_SKILLS_DIR, entry.name)))) {
387
- branch.move(`${relPlugin}/${entry.name}`, `${relPlugin}/${PLUGIN_SKILLS_DIR}/${entry.name}`);
388
- details.push(`${folderName}: ${entry.name}/ → ${PLUGIN_SKILLS_DIR}/${entry.name}/`);
389
- changed = true;
335
+ /**
336
+ * Reorganise ONE plugin folder. `folderDir` is where the folder sits ON DISK
337
+ * (under the legacy root when the rename is buffered this run); declared op
338
+ * paths always speak `Plugins/<folder>/…`. Returns whether ops were declared.
339
+ */
340
+ private async migratePluginFolder(
341
+ branch: KbBranch,
342
+ folderDir: string,
343
+ folderName: string,
344
+ details: string[],
345
+ refusals: string[],
346
+ ): Promise<boolean> {
347
+ const relPlugin = `${PLUGINS_DIR}/${folderName}`;
348
+ let changed = false;
349
+
350
+ const entries = await this.disk.listDir(folderDir);
351
+ if (entries === null) return false; // vanished since the root was listed: nothing to reorganise
352
+
353
+ // When the manifest is written this run its content is remembered: the
354
+ // buffered write is not on disk yet, and the fold below must see it.
355
+ // "Has a manifest" is the manifests step's own judgement — a REGULAR file
356
+ // entry, bundle dialect included — so a folder squatted by a link or a
357
+ // directory named `plugin.json` is not mistaken for a plugin that has one.
358
+ let renderedManifest: string | null = null;
359
+ if (!hasManifestEntry(entries)) {
360
+ // A folder is made a plugin only when it IS one — by the same rule the
361
+ // manifests step applies: legacy plugin content inside it, and no
362
+ // plugin beneath it. A plain folder somebody made under the root (a
363
+ // `.gitkeep`), or a grouping folder holding plugins, is neither, and a
364
+ // manifest written there would turn a grouping folder into a plugin
365
+ // that hides everything beneath it.
366
+ if (
367
+ !(await this.layout.looksLikeLegacyPlugin(folderDir, entries)) ||
368
+ (await this.layout.hasPluginBeneath(folderDir))
369
+ ) {
370
+ return false;
390
371
  }
391
- continue;
372
+ renderedManifest = renderPluginManifest(folderName);
373
+ branch.write(`${relPlugin}/${PLUGIN_MANIFEST_FILE}`, renderedManifest);
374
+ details.push(`${folderName}: wrote ${PLUGIN_MANIFEST_FILE}`);
375
+ changed = true;
392
376
  }
393
377
 
394
- if (entry.isFile() && entry.name.toLowerCase().endsWith('.tool')) {
395
- await convertOrMove(abs, `${relPlugin}/${entry.name}`, entry.name);
396
- }
397
- }
378
+ const converted: ConvertedManual[] = [];
398
379
 
399
- // Second sweep: mcp `.tool`s an EARLIER run moved into the extension dir
400
- // (when mcp.json was a projection, not the authority). Converting them here
401
- // is what makes the migration complete itself rather than strand a twin.
402
- // `isDir` is lstat-based, so a SYMLINK planted at this path is not swept:
403
- // this sweep DELETES what it converts, and following a link would delete
404
- // `.tool` files from wherever the link really points.
405
- //
406
- // Under buffered ops this sweep reads the PRE-STEP tree, so a `.tool` the
407
- // first sweep just declared moved here is not visible — and does not need
408
- // to be: same-run movables were already converted or refused by the same
409
- // `asMcpManual` logic above. The sweep exists for files parked by EARLIER
410
- // runs, which are on disk. (The old in-place code happened to re-see
411
- // same-run moves and no-op on them; the buffered read makes that a
412
- // non-event by construction.)
413
- const extToolsDir = path.join(folderDir, ...HEXIS_TOOLS_DIR.split('/'));
414
- if (await isDir(extToolsDir)) {
415
- for (const entry of await fs.readdir(extToolsDir, { withFileTypes: true })) {
416
- if (!entry.isFile() || !entry.name.toLowerCase().endsWith('.tool')) continue;
417
- const abs = path.join(extToolsDir, entry.name);
418
- const rel = `${relPlugin}/${HEXIS_TOOLS_DIR}/${entry.name}`;
380
+ const convertOrMove = async (abs: string, rel: string, note: string): Promise<void> => {
419
381
  const manual = await asMcpManual(abs, rel);
420
- // A refusal reason here is a SETTLED resident of the tools dir — it
421
- // was named the run it moved in, and this sweep repeats every boot,
422
- // so re-raising it would be log spam. Only a convertible manual queues.
423
382
  if (manual !== null && typeof manual !== 'string') {
424
- converted.push({ manual, rel, note: `${HEXIS_TOOLS_DIR}/${entry.name}` });
383
+ // QUEUED for conversion — the `.tool`'s removal is declared only AFTER
384
+ // its entry's writes (see foldIntoPluginFiles). Buffering makes the
385
+ // apply all-or-nothing anyway, but the declaration order keeps the old
386
+ // recovery reasoning legible: the file IS the recovery path until the
387
+ // fold has landed.
388
+ converted.push({ manual, rel, note });
389
+ return;
390
+ }
391
+ if (typeof manual === 'string') {
392
+ // The operator's answer to "why is this integration not in mcp.json":
393
+ // a refused conversion must read as the deliberate retention it is —
394
+ // surfaced through the step's `partial` reason rather than a note, so
395
+ // it names what did NOT change instead of decorating a commit.
396
+ refusals.push(`${branch.name}: ${folderName}: ${note} NOT converted — ${manual}; kept as a .tool`);
397
+ }
398
+ const destDisk = path.join(folderDir, ...HEXIS_TOOLS_DIR.split('/'), path.basename(abs));
399
+ // Never overwrite: a destination that already exists means a previous run
400
+ // got there first (or a human did), and clobbering it would destroy the
401
+ // newer copy. The check is against the pre-step tree — the only tree that
402
+ // exists while this step runs.
403
+ if (abs !== destDisk && !(await this.disk.exists(destDisk))) {
404
+ branch.move(rel, `${relPlugin}/${HEXIS_TOOLS_DIR}/${path.basename(abs)}`);
405
+ details.push(`${folderName}: ${note} → ${HEXIS_TOOLS_DIR}/${path.basename(abs)}`);
406
+ changed = true;
407
+ }
408
+ };
409
+
410
+ for (const entry of entries) {
411
+ if (entry.name.startsWith('.')) continue;
412
+ if (entry.name === PLUGIN_SKILLS_DIR || entry.name === PLUGIN_MANIFEST_FILE) continue;
413
+ if (entry.name === PLUGIN_MCP_FILE || entry.name === 'access.md') continue;
414
+ if (entry.name === HEXIS_TOOLS_DIR.split('/')[0]) continue;
415
+
416
+ const abs = path.join(folderDir, entry.name);
417
+
418
+ // A skill is a folder carrying SKILL.md — the same rule the catalog uses.
419
+ if (entry.isDirectory() && (await this.disk.exists(path.join(abs, 'SKILL.md')))) {
420
+ if (!(await this.disk.exists(path.join(folderDir, PLUGIN_SKILLS_DIR, entry.name)))) {
421
+ branch.move(`${relPlugin}/${entry.name}`, `${relPlugin}/${PLUGIN_SKILLS_DIR}/${entry.name}`);
422
+ details.push(`${folderName}: ${entry.name}/ → ${PLUGIN_SKILLS_DIR}/${entry.name}/`);
423
+ changed = true;
424
+ }
425
+ continue;
426
+ }
427
+
428
+ if (entry.isFile() && entry.name.toLowerCase().endsWith('.tool')) {
429
+ await convertOrMove(abs, `${relPlugin}/${entry.name}`, entry.name);
425
430
  }
426
431
  }
427
- }
428
432
 
429
- changed =
430
- (await foldIntoPluginFiles(branch, folderDir, relPlugin, folderName, renderedManifest, converted, details, refusals)) ||
431
- changed;
432
- return changed;
433
- }
433
+ // Second sweep: mcp `.tool`s an EARLIER run moved into the extension dir
434
+ // (when mcp.json was a projection, not the authority). Converting them here
435
+ // is what makes the migration complete itself rather than strand a twin.
436
+ // `isDirectory` is lstat-based, so a SYMLINK planted at this path is not swept:
437
+ // this sweep DELETES what it converts, and following a link would delete
438
+ // `.tool` files from wherever the link really points.
439
+ //
440
+ // Under buffered ops this sweep reads the PRE-STEP tree, so a `.tool` the
441
+ // first sweep just declared moved here is not visible — and does not need
442
+ // to be: same-run movables were already converted or refused by the same
443
+ // `asMcpManual` logic above. The sweep exists for files parked by EARLIER
444
+ // runs, which are on disk. (The old in-place code happened to re-see
445
+ // same-run moves and no-op on them; the buffered read makes that a
446
+ // non-event by construction.)
447
+ const extToolsDir = path.join(folderDir, ...HEXIS_TOOLS_DIR.split('/'));
448
+ if (await this.disk.isDirectory(extToolsDir)) {
449
+ for (const entry of (await this.disk.listDir(extToolsDir)) ?? []) {
450
+ if (!entry.isFile() || !entry.name.toLowerCase().endsWith('.tool')) continue;
451
+ const abs = path.join(extToolsDir, entry.name);
452
+ const rel = `${relPlugin}/${HEXIS_TOOLS_DIR}/${entry.name}`;
453
+ const manual = await asMcpManual(abs, rel);
454
+ // A refusal reason here is a SETTLED resident of the tools dir — it
455
+ // was named the run it moved in, and this sweep repeats every boot,
456
+ // so re-raising it would be log spam. Only a convertible manual queues.
457
+ if (manual !== null && typeof manual !== 'string') {
458
+ converted.push({ manual, rel, note: `${HEXIS_TOOLS_DIR}/${entry.name}` });
459
+ }
460
+ }
461
+ }
434
462
 
435
- /**
436
- * Fold converted mcp manuals into the plugin's mcp.json and plugin.json.
437
- *
438
- * MERGE, never clobber: an entry already present under a manual's key — hand
439
- * written or from a previous run — wins, because overwriting it would discard
440
- * the newer intent. The extension block merges the same way. A plugin.json
441
- * that does not parse costs the extension write (logged), not the migration.
442
- */
443
- async function foldIntoPluginFiles(
444
- branch: KbBranch,
445
- folderDir: string,
446
- relPlugin: string,
447
- folderName: string,
448
- renderedManifest: string | null,
449
- manuals: ConvertedManual[],
450
- details: string[],
451
- refusals: string[],
452
- ): Promise<boolean> {
453
- if (manuals.length === 0) return false;
454
-
455
- const mcp = (await readJson(path.join(folderDir, PLUGIN_MCP_FILE))) ?? {
456
- $schema: PLUGIN_MCP_SCHEMA,
457
- mcpServers: {},
458
- };
459
- // An array (or any non-object) here would take property assignments and then
460
- // drop them at stringify — normalize to an object before merging into it.
461
- if (typeof mcp.mcpServers !== 'object' || mcp.mcpServers === null || Array.isArray(mcp.mcpServers)) {
462
- mcp.mcpServers = {};
463
- }
464
- const servers = mcp.mcpServers as Record<string, unknown>;
465
-
466
- // The manifest may have been DECLARED this very run — a buffered write not
467
- // yet on disk. Reading the disk then would see "missing" and refuse
468
- // conversions the write-then-read in-place code performed, so the step's
469
- // own rendered content stands in for the tree it is about to produce.
470
- const manifest =
471
- renderedManifest !== null
472
- ? (JSON.parse(renderedManifest) as Record<string, unknown>)
473
- : await readJson(path.join(folderDir, PLUGIN_MANIFEST_FILE));
474
- if (manifest === null) {
475
- console.warn(
476
- `[groups-to-plugins] ${branch.name}: ${folderName}/${PLUGIN_MANIFEST_FILE} is missing or unparsable — ` +
477
- 'mcp manuals convert only when they carry NOTHING for the extensions block; any ' +
478
- 'non-portable half (auth headers, variables, a description, or the local-only flag) ' +
479
- 'keeps the manual a `.tool` until the manifest is fixed.',
480
- );
463
+ changed =
464
+ (await this.foldIntoPluginFiles(
465
+ branch,
466
+ folderDir,
467
+ relPlugin,
468
+ folderName,
469
+ renderedManifest,
470
+ converted,
471
+ details,
472
+ refusals,
473
+ )) || changed;
474
+ return changed;
481
475
  }
482
476
 
483
- let wroteMcp = false;
484
- let wroteManifest = false;
485
- const folded: ConvertedManual[] = [];
486
- for (const item of manuals.sort((a, b) => a.manual.name.localeCompare(b.manual.name))) {
487
- const m = item.manual;
488
- const { literal, credential } = splitHeaders(m.headers);
489
- // A manual whose non-portable half (auth headers, variables, local flag)
490
- // has nowhere to go — the manifest is missing or unparsable — is NOT
491
- // converted at all: writing only its portable half and deleting the
492
- // source would silently discard the credential wiring. It stays a
493
- // `.tool` until the manifest is fixed.
494
- const extEntry = {
495
- ...(Object.keys(credential).length > 0 ? { headers: credential } : {}),
496
- ...(m.variables && m.variables.length > 0 ? { variables: m.variables } : {}),
497
- ...(typeof m.description === 'string' ? { description: m.description } : {}),
498
- ...(m.remote === false ? { local: true } : {}),
477
+ /**
478
+ * Fold converted mcp manuals into the plugin's mcp.json and plugin.json.
479
+ *
480
+ * MERGE, never clobber: an entry already present under a manual's key — hand
481
+ * written or from a previous run — wins, because overwriting it would discard
482
+ * the newer intent. The extension block merges the same way. A plugin.json
483
+ * that does not parse costs the extension write (logged), not the migration.
484
+ */
485
+ private async foldIntoPluginFiles(
486
+ branch: KbBranch,
487
+ folderDir: string,
488
+ relPlugin: string,
489
+ folderName: string,
490
+ renderedManifest: string | null,
491
+ manuals: ConvertedManual[],
492
+ details: string[],
493
+ refusals: string[],
494
+ ): Promise<boolean> {
495
+ if (manuals.length === 0) return false;
496
+
497
+ const mcp = (await this.disk.readJsonObject(path.join(folderDir, PLUGIN_MCP_FILE))) ?? {
498
+ $schema: PLUGIN_MCP_SCHEMA,
499
+ mcpServers: {},
499
500
  };
500
- if (manifest === null && Object.keys(extEntry).length > 0) {
501
- refusals.push(
502
- `${branch.name}: ${folderName}: ${item.note} NOT converted — ${PLUGIN_MANIFEST_FILE} is missing/unparsable ` +
503
- 'and the manual carries declarations (auth headers, variables, a description, or the ' +
504
- 'local-only flag) that would be lost; fix the manifest first',
505
- );
506
- continue;
501
+ // An array (or any non-object) here would take property assignments and then
502
+ // drop them at stringify — normalize to an object before merging into it.
503
+ if (typeof mcp.mcpServers !== 'object' || mcp.mcpServers === null || Array.isArray(mcp.mcpServers)) {
504
+ mcp.mcpServers = {};
507
505
  }
508
- folded.push(item);
509
- // Own-property check: `in` sees `constructor` and friends on the prototype,
510
- // which would silently skip a legitimately named server.
511
- if (!Object.prototype.hasOwnProperty.call(servers, m.name)) {
512
- servers[m.name] = {
513
- type: 'streamable-http',
514
- url: m.url,
515
- ...(Object.keys(literal).length > 0 ? { headers: literal } : {}),
516
- };
517
- wroteMcp = true;
518
- details.push(`${folderName}: ${m.name} → ${PLUGIN_MCP_FILE}`);
506
+ const servers = mcp.mcpServers as Record<string, unknown>;
507
+
508
+ // The manifest may have been DECLARED this very run — a buffered write not
509
+ // yet on disk. Reading the disk then would see "missing" and refuse
510
+ // conversions the write-then-read in-place code performed, so the step's
511
+ // own rendered content stands in for the tree it is about to produce.
512
+ const manifest =
513
+ renderedManifest !== null
514
+ ? (JSON.parse(renderedManifest) as Record<string, unknown>)
515
+ : await this.disk.readJsonObject(path.join(folderDir, PLUGIN_MANIFEST_FILE));
516
+ if (manifest === null) {
517
+ log.warn(
518
+ `${branch.name}: ${folderName}/${PLUGIN_MANIFEST_FILE} is missing or unparsable — ` +
519
+ 'mcp manuals convert only when they carry NOTHING for the extensions block; any ' +
520
+ 'non-portable half (auth headers, variables, a description, or the local-only flag) ' +
521
+ 'keeps the manual a `.tool` until the manifest is fixed.',
522
+ );
519
523
  }
520
524
 
521
- // The non-portable half: auth headers, variable declarations, local-only.
522
- if (manifest !== null && Object.keys(extEntry).length > 0) {
523
- // Normalize each level: a parseable manifest can still carry a string or
524
- // array where an object belongs, and mutating that would throw mid-run.
525
- if (typeof manifest.extensions !== 'object' || manifest.extensions === null || Array.isArray(manifest.extensions)) {
526
- manifest.extensions = {};
527
- }
528
- const ext = manifest.extensions as Record<string, unknown>;
529
- if (typeof ext[HEXIS_EXTENSION_NS] !== 'object' || ext[HEXIS_EXTENSION_NS] === null || Array.isArray(ext[HEXIS_EXTENSION_NS])) {
530
- ext[HEXIS_EXTENSION_NS] = {};
525
+ let wroteMcp = false;
526
+ let wroteManifest = false;
527
+ const folded: ConvertedManual[] = [];
528
+ for (const item of manuals.sort((a, b) => a.manual.name.localeCompare(b.manual.name))) {
529
+ const m = item.manual;
530
+ const { literal, credential } = splitHeaders(m.headers);
531
+ // A manual whose non-portable half (auth headers, variables, local flag)
532
+ // has nowhere to go — the manifest is missing or unparsable — is NOT
533
+ // converted at all: writing only its portable half and deleting the
534
+ // source would silently discard the credential wiring. It stays a
535
+ // `.tool` until the manifest is fixed.
536
+ const extEntry = {
537
+ ...(Object.keys(credential).length > 0 ? { headers: credential } : {}),
538
+ ...(m.variables && m.variables.length > 0 ? { variables: m.variables } : {}),
539
+ ...(typeof m.description === 'string' ? { description: m.description } : {}),
540
+ ...(m.remote === false ? { local: true } : {}),
541
+ };
542
+ if (manifest === null && Object.keys(extEntry).length > 0) {
543
+ refusals.push(
544
+ `${branch.name}: ${folderName}: ${item.note} NOT converted — ${PLUGIN_MANIFEST_FILE} is missing/unparsable ` +
545
+ 'and the manual carries declarations (auth headers, variables, a description, or the ' +
546
+ 'local-only flag) that would be lost; fix the manifest first',
547
+ );
548
+ continue;
531
549
  }
532
- const ns = ext[HEXIS_EXTENSION_NS] as Record<string, unknown>;
533
- if (typeof ns.mcpServers !== 'object' || ns.mcpServers === null || Array.isArray(ns.mcpServers)) {
534
- ns.mcpServers = {};
550
+ folded.push(item);
551
+ // Own-property check: `in` sees `constructor` and friends on the prototype,
552
+ // which would silently skip a legitimately named server.
553
+ if (!Object.prototype.hasOwnProperty.call(servers, m.name)) {
554
+ servers[m.name] = {
555
+ type: 'streamable-http',
556
+ url: m.url,
557
+ ...(Object.keys(literal).length > 0 ? { headers: literal } : {}),
558
+ };
559
+ wroteMcp = true;
560
+ details.push(`${folderName}: ${m.name} → ${PLUGIN_MCP_FILE}`);
535
561
  }
536
- const extServers = ns.mcpServers as Record<string, unknown>;
537
- if (!Object.prototype.hasOwnProperty.call(extServers, m.name)) {
538
- extServers[m.name] = extEntry;
539
- wroteManifest = true;
562
+
563
+ // The non-portable half: auth headers, variable declarations, local-only.
564
+ if (manifest !== null && Object.keys(extEntry).length > 0) {
565
+ // Normalize each level: a parseable manifest can still carry a string or
566
+ // array where an object belongs, and mutating that would throw mid-run.
567
+ if (typeof manifest.extensions !== 'object' || manifest.extensions === null || Array.isArray(manifest.extensions)) {
568
+ manifest.extensions = {};
569
+ }
570
+ const ext = manifest.extensions as Record<string, unknown>;
571
+ if (typeof ext[HEXIS_EXTENSION_NS] !== 'object' || ext[HEXIS_EXTENSION_NS] === null || Array.isArray(ext[HEXIS_EXTENSION_NS])) {
572
+ ext[HEXIS_EXTENSION_NS] = {};
573
+ }
574
+ const ns = ext[HEXIS_EXTENSION_NS] as Record<string, unknown>;
575
+ if (typeof ns.mcpServers !== 'object' || ns.mcpServers === null || Array.isArray(ns.mcpServers)) {
576
+ ns.mcpServers = {};
577
+ }
578
+ const extServers = ns.mcpServers as Record<string, unknown>;
579
+ if (!Object.prototype.hasOwnProperty.call(extServers, m.name)) {
580
+ extServers[m.name] = extEntry;
581
+ wroteManifest = true;
582
+ }
540
583
  }
541
584
  }
542
- }
543
585
 
544
- if (wroteMcp) {
545
- branch.write(`${relPlugin}/${PLUGIN_MCP_FILE}`, `${JSON.stringify(mcp, null, 2)}\n`);
546
- }
547
- if (wroteManifest) {
548
- // May supersede the bare manifest declared above — ops apply in order, so
549
- // the extended content is what lands.
550
- branch.write(`${relPlugin}/${PLUGIN_MANIFEST_FILE}`, `${JSON.stringify(manifest, null, 2)}\n`);
551
- details.push(`${folderName}: wrote mcp-server declarations into ${PLUGIN_MANIFEST_FILE}`);
552
- }
553
- // Sources go LAST in declaration order, once everything they carried has
554
- // been declared elsewhere — the same shape the in-place code used so a
555
- // failure never stranded the non-portable half with no source to retry from.
556
- for (const item of folded) {
557
- branch.remove(item.rel);
558
- details.push(`${folderName}: ${item.note} converted to an ${PLUGIN_MCP_FILE} entry`);
586
+ if (wroteMcp) {
587
+ branch.write(`${relPlugin}/${PLUGIN_MCP_FILE}`, `${JSON.stringify(mcp, null, 2)}\n`);
588
+ }
589
+ if (wroteManifest) {
590
+ // May supersede the bare manifest declared above — ops apply in order, so
591
+ // the extended content is what lands.
592
+ branch.write(`${relPlugin}/${PLUGIN_MANIFEST_FILE}`, `${JSON.stringify(manifest, null, 2)}\n`);
593
+ details.push(`${folderName}: wrote mcp-server declarations into ${PLUGIN_MANIFEST_FILE}`);
594
+ }
595
+ // Sources go LAST in declaration order, once everything they carried has
596
+ // been declared elsewhere — the same shape the in-place code used so a
597
+ // failure never stranded the non-portable half with no source to retry from.
598
+ for (const item of folded) {
599
+ branch.remove(item.rel);
600
+ details.push(`${folderName}: ${item.note} converted to an ${PLUGIN_MCP_FILE} entry`);
601
+ }
602
+ return wroteMcp || wroteManifest || folded.length > 0;
559
603
  }
560
- return wroteMcp || wroteManifest || folded.length > 0;
561
604
  }