@bevel-software/platform-core-backend 0.13.6 → 0.15.1

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 (456) hide show
  1. package/THIRD-PARTY-NOTICES.md +6 -6
  2. package/dist/core/catalog-cache-invalidation.d.ts +29 -0
  3. package/dist/core/catalog-cache-invalidation.d.ts.map +1 -0
  4. package/dist/core/catalog-cache-invalidation.js +71 -0
  5. package/dist/core/catalog-cache-invalidation.js.map +1 -0
  6. package/dist/core/create-core-server.d.ts.map +1 -1
  7. package/dist/core/create-core-server.js +101 -9
  8. package/dist/core/create-core-server.js.map +1 -1
  9. package/dist/core/create-core-services.d.ts +20 -1
  10. package/dist/core/create-core-services.d.ts.map +1 -1
  11. package/dist/core/create-core-services.js +105 -43
  12. package/dist/core/create-core-services.js.map +1 -1
  13. package/dist/core-config.d.ts.map +1 -1
  14. package/dist/core-config.js +12 -5
  15. package/dist/core-config.js.map +1 -1
  16. package/dist/modules/access/access-control.interface.d.ts +18 -6
  17. package/dist/modules/access/access-control.interface.d.ts.map +1 -1
  18. package/dist/modules/access/access-control.service.d.ts +26 -1
  19. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  20. package/dist/modules/access/access-control.service.js +213 -71
  21. package/dist/modules/access/access-control.service.js.map +1 -1
  22. package/dist/modules/access/access.routes.d.ts.map +1 -1
  23. package/dist/modules/access/access.routes.js +59 -7
  24. package/dist/modules/access/access.routes.js.map +1 -1
  25. package/dist/modules/access-model/access-grammar.d.ts +51 -1
  26. package/dist/modules/access-model/access-grammar.d.ts.map +1 -1
  27. package/dist/modules/access-model/access-grammar.js +95 -1
  28. package/dist/modules/access-model/access-grammar.js.map +1 -1
  29. package/dist/modules/access-model/group-files.d.ts.map +1 -1
  30. package/dist/modules/access-model/group-files.js +4 -1
  31. package/dist/modules/access-model/group-files.js.map +1 -1
  32. package/dist/modules/access-model/kb-read-filter.d.ts +12 -0
  33. package/dist/modules/access-model/kb-read-filter.d.ts.map +1 -1
  34. package/dist/modules/access-model/kb-read-filter.js +15 -0
  35. package/dist/modules/access-model/kb-read-filter.js.map +1 -1
  36. package/dist/modules/access-model/plugin-principals.d.ts +49 -0
  37. package/dist/modules/access-model/plugin-principals.d.ts.map +1 -0
  38. package/dist/modules/access-model/plugin-principals.js +125 -0
  39. package/dist/modules/access-model/plugin-principals.js.map +1 -0
  40. package/dist/modules/connection-probe/connection-probe.contract.d.ts +43 -0
  41. package/dist/modules/connection-probe/connection-probe.contract.d.ts.map +1 -0
  42. package/dist/modules/connection-probe/connection-probe.contract.js +2 -0
  43. package/dist/modules/connection-probe/connection-probe.contract.js.map +1 -0
  44. package/dist/modules/connection-probe/connection-probe.service.d.ts +94 -0
  45. package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -0
  46. package/dist/modules/connection-probe/connection-probe.service.js +684 -0
  47. package/dist/modules/connection-probe/connection-probe.service.js.map +1 -0
  48. package/dist/modules/connection-probe/index.d.ts +3 -0
  49. package/dist/modules/connection-probe/index.d.ts.map +1 -0
  50. package/dist/modules/connection-probe/index.js +3 -0
  51. package/dist/modules/connection-probe/index.js.map +1 -0
  52. package/dist/modules/database/core-schema.d.ts +326 -0
  53. package/dist/modules/database/core-schema.d.ts.map +1 -1
  54. package/dist/modules/database/core-schema.js +52 -0
  55. package/dist/modules/database/core-schema.js.map +1 -1
  56. package/dist/modules/diff/diff.routes.d.ts.map +1 -1
  57. package/dist/modules/diff/diff.routes.js +3 -5
  58. package/dist/modules/diff/diff.routes.js.map +1 -1
  59. package/dist/modules/kb-fs/mutex.d.ts +37 -0
  60. package/dist/modules/kb-fs/mutex.d.ts.map +1 -1
  61. package/dist/modules/kb-fs/mutex.js +48 -5
  62. package/dist/modules/kb-fs/mutex.js.map +1 -1
  63. package/dist/modules/kb-sync/index.d.ts +6 -0
  64. package/dist/modules/kb-sync/index.d.ts.map +1 -0
  65. package/dist/modules/kb-sync/index.js +5 -0
  66. package/dist/modules/kb-sync/index.js.map +1 -0
  67. package/dist/modules/kb-sync/kb-sync.interface.d.ts +77 -0
  68. package/dist/modules/kb-sync/kb-sync.interface.d.ts.map +1 -0
  69. package/dist/modules/kb-sync/kb-sync.interface.js +2 -0
  70. package/dist/modules/kb-sync/kb-sync.interface.js.map +1 -0
  71. package/dist/modules/kb-sync/kb-sync.routes.d.ts +70 -0
  72. package/dist/modules/kb-sync/kb-sync.routes.d.ts.map +1 -0
  73. package/dist/modules/kb-sync/kb-sync.routes.js +135 -0
  74. package/dist/modules/kb-sync/kb-sync.routes.js.map +1 -0
  75. package/dist/modules/kb-sync/kb-sync.service.d.ts +45 -0
  76. package/dist/modules/kb-sync/kb-sync.service.d.ts.map +1 -0
  77. package/dist/modules/kb-sync/kb-sync.service.js +183 -0
  78. package/dist/modules/kb-sync/kb-sync.service.js.map +1 -0
  79. package/dist/modules/kb-sync/sync-auth.d.ts +59 -0
  80. package/dist/modules/kb-sync/sync-auth.d.ts.map +1 -0
  81. package/dist/modules/kb-sync/sync-auth.js +62 -0
  82. package/dist/modules/kb-sync/sync-auth.js.map +1 -0
  83. package/dist/modules/kb-sync/sync-payload.d.ts +32 -0
  84. package/dist/modules/kb-sync/sync-payload.d.ts.map +1 -0
  85. package/dist/modules/kb-sync/sync-payload.js +105 -0
  86. package/dist/modules/kb-sync/sync-payload.js.map +1 -0
  87. package/dist/modules/marketplace/git-http.routes.d.ts +42 -0
  88. package/dist/modules/marketplace/git-http.routes.d.ts.map +1 -0
  89. package/dist/modules/marketplace/git-http.routes.js +190 -0
  90. package/dist/modules/marketplace/git-http.routes.js.map +1 -0
  91. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.d.ts +23 -0
  92. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.d.ts.map +1 -0
  93. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.js +59 -0
  94. package/dist/modules/marketplace/github-facade/github-facade-admin.routes.js.map +1 -0
  95. package/dist/modules/marketplace/github-facade/github-facade-codes.store.d.ts +59 -0
  96. package/dist/modules/marketplace/github-facade/github-facade-codes.store.d.ts.map +1 -0
  97. package/dist/modules/marketplace/github-facade/github-facade-codes.store.js +96 -0
  98. package/dist/modules/marketplace/github-facade/github-facade-codes.store.js.map +1 -0
  99. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.d.ts +99 -0
  100. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.d.ts.map +1 -0
  101. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.js +147 -0
  102. package/dist/modules/marketplace/github-facade/github-facade-credentials.service.js.map +1 -0
  103. package/dist/modules/marketplace/github-facade/github-facade.routes.d.ts +47 -0
  104. package/dist/modules/marketplace/github-facade/github-facade.routes.d.ts.map +1 -0
  105. package/dist/modules/marketplace/github-facade/github-facade.routes.js +228 -0
  106. package/dist/modules/marketplace/github-facade/github-facade.routes.js.map +1 -0
  107. package/dist/modules/marketplace/github-facade/github-facade.service.d.ts +109 -0
  108. package/dist/modules/marketplace/github-facade/github-facade.service.d.ts.map +1 -0
  109. package/dist/modules/marketplace/github-facade/github-facade.service.js +172 -0
  110. package/dist/modules/marketplace/github-facade/github-facade.service.js.map +1 -0
  111. package/dist/modules/marketplace/github-facade/index.d.ts +6 -0
  112. package/dist/modules/marketplace/github-facade/index.d.ts.map +1 -0
  113. package/dist/modules/marketplace/github-facade/index.js +6 -0
  114. package/dist/modules/marketplace/github-facade/index.js.map +1 -0
  115. package/dist/modules/marketplace/index.d.ts +4 -0
  116. package/dist/modules/marketplace/index.d.ts.map +1 -0
  117. package/dist/modules/marketplace/index.js +4 -0
  118. package/dist/modules/marketplace/index.js.map +1 -0
  119. package/dist/modules/marketplace/marketplace-repo.service.d.ts +122 -0
  120. package/dist/modules/marketplace/marketplace-repo.service.d.ts.map +1 -0
  121. package/dist/modules/marketplace/marketplace-repo.service.js +300 -0
  122. package/dist/modules/marketplace/marketplace-repo.service.js.map +1 -0
  123. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  124. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +4 -0
  125. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  126. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +14 -8
  127. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -1
  128. package/dist/modules/mcp/oauth/oauth-consent.routes.js +13 -1
  129. package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -1
  130. package/dist/modules/mcp/oauth/oauth-state.d.ts +13 -2
  131. package/dist/modules/mcp/oauth/oauth-state.d.ts.map +1 -1
  132. package/dist/modules/mcp/oauth/oauth-state.js +3 -1
  133. package/dist/modules/mcp/oauth/oauth-state.js.map +1 -1
  134. package/dist/modules/plugins/compile/compile-marketplace.d.ts +97 -0
  135. package/dist/modules/plugins/compile/compile-marketplace.d.ts.map +1 -0
  136. package/dist/modules/plugins/compile/compile-marketplace.js +240 -0
  137. package/dist/modules/plugins/compile/compile-marketplace.js.map +1 -0
  138. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts +66 -0
  139. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts.map +1 -0
  140. package/dist/modules/plugins/compile/marketplace-compiler.service.js +132 -0
  141. package/dist/modules/plugins/compile/marketplace-compiler.service.js.map +1 -0
  142. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts +37 -0
  143. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts.map +1 -0
  144. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js +135 -0
  145. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js.map +1 -0
  146. package/dist/modules/plugins/discovery/bundle-dialect/registry.d.ts +45 -0
  147. package/dist/modules/plugins/discovery/bundle-dialect/registry.d.ts.map +1 -0
  148. package/dist/modules/plugins/discovery/bundle-dialect/registry.js +147 -0
  149. package/dist/modules/plugins/discovery/bundle-dialect/registry.js.map +1 -0
  150. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts +37 -0
  151. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts.map +1 -0
  152. package/dist/modules/plugins/discovery/kb-plugin-source.js +107 -0
  153. package/dist/modules/plugins/discovery/kb-plugin-source.js.map +1 -0
  154. package/dist/modules/plugins/discovery/native.source.d.ts +15 -0
  155. package/dist/modules/plugins/discovery/native.source.d.ts.map +1 -0
  156. package/dist/modules/plugins/discovery/native.source.js +102 -0
  157. package/dist/modules/plugins/discovery/native.source.js.map +1 -0
  158. package/dist/modules/plugins/discovery/plugin-source.d.ts +96 -0
  159. package/dist/modules/plugins/discovery/plugin-source.d.ts.map +1 -0
  160. package/dist/modules/plugins/discovery/plugin-source.js +2 -0
  161. package/dist/modules/plugins/discovery/plugin-source.js.map +1 -0
  162. package/dist/modules/plugins/index.d.ts +10 -1
  163. package/dist/modules/plugins/index.d.ts.map +1 -1
  164. package/dist/modules/plugins/index.js +8 -0
  165. package/dist/modules/plugins/index.js.map +1 -1
  166. package/dist/modules/plugins/plugin-links.d.ts +66 -0
  167. package/dist/modules/plugins/plugin-links.d.ts.map +1 -0
  168. package/dist/modules/plugins/plugin-links.js +160 -0
  169. package/dist/modules/plugins/plugin-links.js.map +1 -0
  170. package/dist/modules/plugins/plugin-links.service.d.ts +114 -0
  171. package/dist/modules/plugins/plugin-links.service.d.ts.map +1 -0
  172. package/dist/modules/plugins/plugin-links.service.js +304 -0
  173. package/dist/modules/plugins/plugin-links.service.js.map +1 -0
  174. package/dist/modules/plugins/plugin-provision.service.d.ts +39 -3
  175. package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
  176. package/dist/modules/plugins/plugin-provision.service.js +152 -52
  177. package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
  178. package/dist/modules/plugins/plugin-rename.service.d.ts +69 -0
  179. package/dist/modules/plugins/plugin-rename.service.d.ts.map +1 -0
  180. package/dist/modules/plugins/plugin-rename.service.js +245 -0
  181. package/dist/modules/plugins/plugin-rename.service.js.map +1 -0
  182. package/dist/modules/plugins/plugins.contract.d.ts +27 -1
  183. package/dist/modules/plugins/plugins.contract.d.ts.map +1 -1
  184. package/dist/modules/plugins/plugins.routes.d.ts +7 -1
  185. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  186. package/dist/modules/plugins/plugins.routes.js +120 -12
  187. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  188. package/dist/modules/plugins/plugins.service.d.ts +50 -3
  189. package/dist/modules/plugins/plugins.service.d.ts.map +1 -1
  190. package/dist/modules/plugins/plugins.service.js +108 -47
  191. package/dist/modules/plugins/plugins.service.js.map +1 -1
  192. package/dist/modules/secrets-vault/db-secrets-vault.service.js +1 -1
  193. package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -1
  194. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +6 -0
  195. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  196. package/dist/modules/secrets-vault/secrets-vault.routes.js +31 -1
  197. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  198. package/dist/modules/settings/deployment-settings.service.d.ts +9 -0
  199. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  200. package/dist/modules/settings/deployment-settings.service.js +82 -2
  201. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  202. package/dist/modules/settings/setup.routes.d.ts +26 -0
  203. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  204. package/dist/modules/settings/setup.routes.js +9 -1
  205. package/dist/modules/settings/setup.routes.js.map +1 -1
  206. package/dist/modules/skills/index.d.ts +1 -0
  207. package/dist/modules/skills/index.d.ts.map +1 -1
  208. package/dist/modules/skills/index.js +1 -0
  209. package/dist/modules/skills/index.js.map +1 -1
  210. package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
  211. package/dist/modules/skills/pending-skills.service.js +9 -4
  212. package/dist/modules/skills/pending-skills.service.js.map +1 -1
  213. package/dist/modules/skills/skill-access-requests.routes.d.ts +38 -0
  214. package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -0
  215. package/dist/modules/skills/skill-access-requests.routes.js +168 -0
  216. package/dist/modules/skills/skill-access-requests.routes.js.map +1 -0
  217. package/dist/modules/skills/skills.contract.d.ts +31 -0
  218. package/dist/modules/skills/skills.contract.d.ts.map +1 -1
  219. package/dist/modules/skills/skills.routes.d.ts +28 -3
  220. package/dist/modules/skills/skills.routes.d.ts.map +1 -1
  221. package/dist/modules/skills/skills.routes.js +42 -3
  222. package/dist/modules/skills/skills.routes.js.map +1 -1
  223. package/dist/modules/skills/skills.service.d.ts +4 -0
  224. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  225. package/dist/modules/skills/skills.service.js +83 -22
  226. package/dist/modules/skills/skills.service.js.map +1 -1
  227. package/dist/modules/tool-auth/external-api-key.interface.d.ts +18 -1
  228. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
  229. package/dist/modules/tool-auth/external-api-key.interface.js +2 -1
  230. package/dist/modules/tool-auth/external-api-key.interface.js.map +1 -1
  231. package/dist/modules/tool-auth/external-api-key.service.d.ts +13 -4
  232. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  233. package/dist/modules/tool-auth/external-api-key.service.js +26 -9
  234. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  235. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +36 -0
  236. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
  237. package/dist/modules/tool-manuals/mcp-json-discovery.js +130 -83
  238. package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
  239. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -1
  240. package/dist/modules/tool-manuals/mcp-server-edit.service.js +10 -4
  241. package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -1
  242. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +83 -0
  243. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
  244. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +15 -2
  245. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  246. package/dist/modules/tool-manuals/tool-manuals.service.js +199 -38
  247. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  248. package/dist/modules/workflow/git/git.service.d.ts +58 -3
  249. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  250. package/dist/modules/workflow/git/git.service.js +325 -60
  251. package/dist/modules/workflow/git/git.service.js.map +1 -1
  252. package/dist/modules/workflow/git/pull-request.service.d.ts +6 -0
  253. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
  254. package/dist/modules/workflow/git/pull-request.service.js +8 -0
  255. package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
  256. package/dist/modules/workflow/workflow.routes.d.ts +2 -1
  257. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
  258. package/dist/modules/workflow/workflow.routes.js +98 -9
  259. package/dist/modules/workflow/workflow.routes.js.map +1 -1
  260. package/dist/modules/workflow/workflow.service.d.ts +133 -9
  261. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  262. package/dist/modules/workflow/workflow.service.js +462 -52
  263. package/dist/modules/workflow/workflow.service.js.map +1 -1
  264. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts +35 -0
  265. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts.map +1 -0
  266. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js +121 -0
  267. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js.map +1 -0
  268. package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
  269. package/dist/modules/workspace/startup/steps/seed-tree.js +46 -2
  270. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  271. package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
  272. package/dist/modules/workspace/startup/steps/template-files.step.js +112 -25
  273. package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
  274. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  275. package/dist/modules/workspace/workspace.routes.js +11 -14
  276. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  277. package/dist/modules/workspace/workspace.service.d.ts +38 -1
  278. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  279. package/dist/modules/workspace/workspace.service.js +131 -20
  280. package/dist/modules/workspace/workspace.service.js.map +1 -1
  281. package/dist/shared/domain-errors.d.ts +20 -0
  282. package/dist/shared/domain-errors.d.ts.map +1 -1
  283. package/dist/shared/domain-errors.js +29 -0
  284. package/dist/shared/domain-errors.js.map +1 -1
  285. package/dist/shared/fs-errors.d.ts +8 -0
  286. package/dist/shared/fs-errors.d.ts.map +1 -0
  287. package/dist/shared/fs-errors.js +11 -0
  288. package/dist/shared/fs-errors.js.map +1 -0
  289. package/dist/shared/fs-walk.d.ts +20 -6
  290. package/dist/shared/fs-walk.d.ts.map +1 -1
  291. package/dist/shared/fs-walk.js +35 -27
  292. package/dist/shared/fs-walk.js.map +1 -1
  293. package/dist/shared/kb-walk.d.ts +52 -0
  294. package/dist/shared/kb-walk.d.ts.map +1 -0
  295. package/dist/shared/kb-walk.js +76 -0
  296. package/dist/shared/kb-walk.js.map +1 -0
  297. package/dist/shared/path-order.d.ts +18 -0
  298. package/dist/shared/path-order.d.ts.map +1 -0
  299. package/dist/shared/path-order.js +35 -0
  300. package/dist/shared/path-order.js.map +1 -0
  301. package/dist/shared/token-crypto.d.ts +17 -2
  302. package/dist/shared/token-crypto.d.ts.map +1 -1
  303. package/dist/shared/token-crypto.js +25 -8
  304. package/dist/shared/token-crypto.js.map +1 -1
  305. package/dist/shared/ttl-cache.d.ts +28 -1
  306. package/dist/shared/ttl-cache.d.ts.map +1 -1
  307. package/dist/shared/ttl-cache.js +33 -1
  308. package/dist/shared/ttl-cache.js.map +1 -1
  309. package/kb-template/.bevelignore +1 -1
  310. package/kb-template/AGENTS.md +95 -30
  311. package/kb-template/Skills/.gitkeep +0 -0
  312. package/migrations/0005_github_facade.sql +25 -0
  313. package/migrations/meta/0005_snapshot.json +1717 -0
  314. package/migrations/meta/_journal.json +7 -0
  315. package/package.json +6 -6
  316. package/src/__tests__/core-config.admin.test.ts +21 -0
  317. package/src/__tests__/kb-layout-config.test.ts +110 -0
  318. package/src/core/__tests__/catalog-cache-invalidation.test.ts +146 -0
  319. package/src/core/catalog-cache-invalidation.ts +92 -0
  320. package/src/core/create-core-server.ts +126 -7
  321. package/src/core/create-core-services.ts +173 -41
  322. package/src/core-config.ts +14 -7
  323. package/src/modules/access/__tests__/access-control.invalidate-race.test.ts +86 -0
  324. package/src/modules/access/__tests__/access-control.service.test.ts +19 -3
  325. package/src/modules/access/__tests__/access-plugin-principals.test.ts +368 -0
  326. package/src/modules/access/__tests__/groups-admin.service.test.ts +8 -0
  327. package/src/modules/access/access-control.interface.ts +20 -9
  328. package/src/modules/access/access-control.service.ts +240 -78
  329. package/src/modules/access/access.routes.ts +96 -14
  330. package/src/modules/access-model/__tests__/access-grammar.test.ts +18 -0
  331. package/src/modules/access-model/__tests__/plugin-token-canonical.test.ts +40 -0
  332. package/src/modules/access-model/access-grammar.ts +114 -2
  333. package/src/modules/access-model/group-files.ts +4 -0
  334. package/src/modules/access-model/kb-read-filter.ts +22 -0
  335. package/src/modules/access-model/plugin-principals.ts +137 -0
  336. package/src/modules/connection-probe/__tests__/connection-probe.service.test.ts +685 -0
  337. package/src/modules/connection-probe/connection-probe.contract.ts +44 -0
  338. package/src/modules/connection-probe/connection-probe.service.ts +734 -0
  339. package/src/modules/connection-probe/index.ts +2 -0
  340. package/src/modules/database/core-schema.ts +54 -0
  341. package/src/modules/diff/diff.routes.ts +9 -5
  342. package/src/modules/kb-fs/__tests__/mutex.test.ts +107 -0
  343. package/src/modules/kb-fs/mutex.ts +50 -5
  344. package/src/modules/kb-sync/__tests__/kb-sync.routes.test.ts +297 -0
  345. package/src/modules/kb-sync/__tests__/kb-sync.service.test.ts +295 -0
  346. package/src/modules/kb-sync/__tests__/sync-auth.test.ts +118 -0
  347. package/src/modules/kb-sync/__tests__/sync-payload.test.ts +148 -0
  348. package/src/modules/kb-sync/index.ts +19 -0
  349. package/src/modules/kb-sync/kb-sync.interface.ts +79 -0
  350. package/src/modules/kb-sync/kb-sync.routes.ts +197 -0
  351. package/src/modules/kb-sync/kb-sync.service.ts +201 -0
  352. package/src/modules/kb-sync/sync-auth.ts +118 -0
  353. package/src/modules/kb-sync/sync-payload.ts +143 -0
  354. package/src/modules/marketplace/__tests__/github-facade.test.ts +443 -0
  355. package/src/modules/marketplace/__tests__/marketplace-git.test.ts +179 -0
  356. package/src/modules/marketplace/git-http.routes.ts +193 -0
  357. package/src/modules/marketplace/github-facade/github-facade-admin.routes.ts +78 -0
  358. package/src/modules/marketplace/github-facade/github-facade-codes.store.ts +145 -0
  359. package/src/modules/marketplace/github-facade/github-facade-credentials.service.ts +208 -0
  360. package/src/modules/marketplace/github-facade/github-facade.routes.ts +268 -0
  361. package/src/modules/marketplace/github-facade/github-facade.service.ts +221 -0
  362. package/src/modules/marketplace/github-facade/index.ts +25 -0
  363. package/src/modules/marketplace/index.ts +3 -0
  364. package/src/modules/marketplace/marketplace-repo.service.ts +337 -0
  365. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +3 -0
  366. package/src/modules/mcp/oauth/oauth-consent.routes.ts +24 -2
  367. package/src/modules/mcp/oauth/oauth-state.ts +15 -3
  368. package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +163 -0
  369. package/src/modules/plugins/__tests__/compile-marketplace.test.ts +294 -0
  370. package/src/modules/plugins/__tests__/plugin-index.service.test.ts +56 -12
  371. package/src/modules/plugins/__tests__/plugin-links.service.test.ts +287 -0
  372. package/src/modules/plugins/__tests__/plugin-provision.service.test.ts +205 -5
  373. package/src/modules/plugins/__tests__/plugin-rename.service.test.ts +394 -0
  374. package/src/modules/plugins/__tests__/plugins.routes.test.ts +80 -33
  375. package/src/modules/plugins/compile/compile-marketplace.ts +403 -0
  376. package/src/modules/plugins/compile/marketplace-compiler.service.ts +150 -0
  377. package/src/modules/plugins/discovery/__tests__/kb-plugin-source.test.ts +329 -0
  378. package/src/modules/plugins/discovery/bundle-dialect/bundle.source.ts +140 -0
  379. package/src/modules/plugins/discovery/bundle-dialect/registry.ts +175 -0
  380. package/src/modules/plugins/discovery/kb-plugin-source.ts +114 -0
  381. package/src/modules/plugins/discovery/native.source.ts +122 -0
  382. package/src/modules/plugins/discovery/plugin-source.ts +99 -0
  383. package/src/modules/plugins/index.ts +10 -0
  384. package/src/modules/plugins/plugin-links.service.ts +363 -0
  385. package/src/modules/plugins/plugin-links.ts +184 -0
  386. package/src/modules/plugins/plugin-provision.service.ts +160 -54
  387. package/src/modules/plugins/plugin-rename.service.ts +298 -0
  388. package/src/modules/plugins/plugins.contract.ts +28 -1
  389. package/src/modules/plugins/plugins.routes.ts +128 -11
  390. package/src/modules/plugins/plugins.service.ts +106 -53
  391. package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +12 -0
  392. package/src/modules/secrets-vault/__tests__/oauth-return-to.route.test.ts +10 -3
  393. package/src/modules/secrets-vault/__tests__/tool-owner-gate.route.test.ts +26 -0
  394. package/src/modules/secrets-vault/db-secrets-vault.service.ts +1 -1
  395. package/src/modules/secrets-vault/secrets-vault.routes.ts +35 -1
  396. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +57 -0
  397. package/src/modules/settings/__tests__/setup.routes.sync-status.test.ts +77 -0
  398. package/src/modules/settings/deployment-settings.service.ts +95 -2
  399. package/src/modules/settings/setup.routes.ts +24 -0
  400. package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +128 -0
  401. package/src/modules/skills/__tests__/skills.service.test.ts +85 -0
  402. package/src/modules/skills/index.ts +1 -0
  403. package/src/modules/skills/pending-skills.service.ts +7 -5
  404. package/src/modules/skills/skill-access-requests.routes.ts +199 -0
  405. package/src/modules/skills/skills.contract.ts +32 -0
  406. package/src/modules/skills/skills.routes.ts +59 -3
  407. package/src/modules/skills/skills.service.ts +84 -22
  408. package/src/modules/tool-auth/external-api-key.interface.ts +20 -1
  409. package/src/modules/tool-auth/external-api-key.service.ts +31 -13
  410. package/src/modules/tool-manuals/__tests__/mcp-json-discovery.test.ts +35 -1
  411. package/src/modules/tool-manuals/__tests__/tool-manuals.cli.test.ts +2 -0
  412. package/src/modules/tool-manuals/__tests__/tool-manuals.health-check.test.ts +104 -0
  413. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +56 -0
  414. package/src/modules/tool-manuals/mcp-json-discovery.ts +154 -76
  415. package/src/modules/tool-manuals/mcp-server-edit.service.ts +13 -4
  416. package/src/modules/tool-manuals/tool-manuals.contract.ts +89 -0
  417. package/src/modules/tool-manuals/tool-manuals.service.ts +210 -37
  418. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +1 -1
  419. package/src/modules/workflow/__tests__/workflow.routes.history-read-gate.test.ts +139 -0
  420. package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +337 -0
  421. package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +1 -0
  422. package/src/modules/workflow/__tests__/workflow.service.deleted-branch-sweep.test.ts +7 -1
  423. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +97 -10
  424. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +119 -2
  425. package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +437 -0
  426. package/src/modules/workflow/git/__tests__/git.service.history-guards.test.ts +86 -0
  427. package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +3 -3
  428. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +47 -4
  429. package/src/modules/workflow/git/__tests__/git.service.syncFromRemote.test.ts +253 -0
  430. package/src/modules/workflow/git/git.service.ts +354 -63
  431. package/src/modules/workflow/git/pull-request.service.ts +9 -0
  432. package/src/modules/workflow/workflow.routes.ts +104 -4
  433. package/src/modules/workflow/workflow.service.ts +505 -64
  434. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +6 -7
  435. package/src/modules/workspace/__tests__/workspace.service.list-cloned.test.ts +93 -0
  436. package/src/modules/workspace/__tests__/workspace.service.missing-branch.test.ts +28 -0
  437. package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +42 -12
  438. package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +219 -4
  439. package/src/modules/workspace/startup/steps/plugin-manifests.step.ts +129 -0
  440. package/src/modules/workspace/startup/steps/seed-tree.ts +44 -2
  441. package/src/modules/workspace/startup/steps/template-files.step.ts +131 -27
  442. package/src/modules/workspace/workspace.routes.ts +17 -21
  443. package/src/modules/workspace/workspace.service.ts +128 -19
  444. package/src/shared/__tests__/filename.test.ts +0 -0
  445. package/src/shared/__tests__/fs-walk.test.ts +22 -1
  446. package/src/shared/__tests__/kb-walk.test.ts +107 -0
  447. package/src/shared/__tests__/path-order.test.ts +24 -0
  448. package/src/shared/__tests__/token-crypto.test.ts +34 -0
  449. package/src/shared/__tests__/ttl-cache.test.ts +55 -0
  450. package/src/shared/domain-errors.ts +29 -0
  451. package/src/shared/fs-errors.ts +10 -0
  452. package/src/shared/fs-walk.ts +38 -23
  453. package/src/shared/kb-walk.ts +95 -0
  454. package/src/shared/path-order.ts +33 -0
  455. package/src/shared/token-crypto.ts +28 -10
  456. package/src/shared/ttl-cache.ts +33 -1
@@ -1,34 +1,42 @@
1
- import path from 'node:path';
2
- import fs from 'node:fs/promises';
1
+ import { walkKb, isSkippedEntry } from './kb-walk.js';
2
+ export { isSkippedEntry };
3
3
  /**
4
- * The ONE recursive file walk for catalog scanners: relative (`/`-separated,
5
- * sorted) paths of files under `root` whose basename matches. A missing root
6
- * yields `[]`; dot-entries (incl. `.git`) are skipped. Scanners with different
7
- * semantics (the skills scanner's stop-at-skill-folder walk, the access
8
- * resolver's dir chains) deliberately keep their own walks.
4
+ * The file listing catalog scanners want, on top of {@link walkKb}: relative
5
+ * (`/`-separated, sorted) paths of files under `root` whose basename matches.
6
+ * A missing root yields `[]`; skipped entries are never entered.
7
+ *
8
+ * A directory that cannot be listed is SKIPPED by default — right for a
9
+ * catalog, which shows what it can. A caller that must see EVERYTHING or
10
+ * nothing passes `strict`, and the listing throws a {@link WalkError} naming
11
+ * the directory instead: a list with a hole in it is not a list of every
12
+ * file, and the caller can say WHICH hole rather than pass a raw errno up.
9
13
  */
10
- export async function walkFiles(root, match) {
14
+ export async function walkFiles(root, match, opts = {}) {
11
15
  const out = [];
12
- const walk = async (dir, rel) => {
13
- let entries;
14
- try {
15
- entries = await fs.readdir(dir, { withFileTypes: true });
16
- }
17
- catch {
18
- return;
19
- }
20
- for (const entry of entries) {
21
- if (entry.name.startsWith('.'))
22
- continue;
23
- const childRel = rel ? `${rel}/${entry.name}` : entry.name;
24
- if (entry.isDirectory())
25
- await walk(path.join(dir, entry.name), childRel);
26
- else if (entry.isFile() && match(entry.name))
27
- out.push(childRel);
28
- }
29
- };
30
- await walk(root, '');
16
+ await walkKb(root, [
17
+ {
18
+ onFile(dir, name) {
19
+ if (match(name))
20
+ out.push(dir ? `${dir}/${name}` : name);
21
+ },
22
+ onHole(rel, err) {
23
+ if (opts.strict)
24
+ throw new WalkError(rel, err);
25
+ },
26
+ },
27
+ ]);
31
28
  out.sort();
32
29
  return out;
33
30
  }
31
+ /** A strict listing's refusal: the directory (relative to the root, `''` for the root itself) it could not list. */
32
+ export class WalkError extends Error {
33
+ relDir;
34
+ cause;
35
+ constructor(relDir, cause) {
36
+ super(`${relDir || '.'} could not be listed — ${cause instanceof Error ? cause.message : String(cause)}`);
37
+ this.relDir = relDir;
38
+ this.cause = cause;
39
+ this.name = 'WalkError';
40
+ }
41
+ }
34
42
  //# sourceMappingURL=fs-walk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fs-walk.js","sourceRoot":"","sources":["../../src/shared/fs-walk.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,KAAoC;IAChF,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,IAAI,GAAG,KAAK,EAAE,GAAW,EAAE,GAAW,EAAiB,EAAE;QAC7D,IAAI,OAAmC,CAAC;QACxC,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACzC,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;YAC3D,IAAI,KAAK,CAAC,WAAW,EAAE;gBAAE,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;iBACrE,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnE,CAAC;IACH,CAAC,CAAC;IACF,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACrB,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"fs-walk.js","sourceRoot":"","sources":["../../src/shared/fs-walk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAY,EACZ,KAAoC,EACpC,OAA6B,EAAE;IAE/B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,MAAM,CAAC,IAAI,EAAE;QACjB;YACE,MAAM,CAAC,GAAG,EAAE,IAAI;gBACd,IAAI,KAAK,CAAC,IAAI,CAAC;oBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC3D,CAAC;YACD,MAAM,CAAC,GAAG,EAAE,GAAG;gBACb,IAAI,IAAI,CAAC,MAAM;oBAAE,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACjD,CAAC;SACF;KACF,CAAC,CAAC;IACH,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,OAAO,GAAG,CAAC;AACb,CAAC;AAED,oHAAoH;AACpH,MAAM,OAAO,SAAU,SAAQ,KAAK;IAEvB;IACA;IAFX,YACW,MAAc,EACd,KAAc;QAEvB,KAAK,CAAC,GAAG,MAAM,IAAI,GAAG,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAHjG,WAAM,GAAN,MAAM,CAAQ;QACd,UAAK,GAAL,KAAK,CAAS;QAGvB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * THE walk of a knowledge-base checkout.
3
+ *
4
+ * Every reader of the tree — the access resolver looking for rules, plugin
5
+ * discovery looking for manifests, a rename looking for grants, the catalog
6
+ * scanners — used to carry a recursive `readdir` loop of its own, each with
7
+ * its own skip list, its own idea of what an unreadable folder means and its
8
+ * own visiting order. Two loops that disagree on one of those are two
9
+ * answers to "what is in the tree", and every such disagreement was a bug.
10
+ *
11
+ * So there is one loop, and it decides three things once:
12
+ *
13
+ * - WHAT IS SKIPPED: {@link isSkippedEntry} — dot-entries (`.git`, a parked
14
+ * delete) and vendored dependencies. Nothing else is pruned; a listener
15
+ * that stops at a leaf of its own (a skill folder, a plugin folder)
16
+ * simply ignores what lies beneath it.
17
+ * - IN WHAT ORDER: each folder's entries in {@link comparePathComponents}
18
+ * order, so "first by path" means the same thing to every listener.
19
+ * - WHAT A HOLE IS: a folder that exists but could not be listed is
20
+ * reported as an event and in the result — never thrown, never silently
21
+ * skipped — so a reader can show what it saw and a writer can refuse.
22
+ * A folder that vanished between listing and visiting is not a hole.
23
+ *
24
+ * Listeners see the same events in the same order; what each makes of them
25
+ * is its own business (`.bevelignore` included — the explorer honours it,
26
+ * the resolver must not, so it is a listener's decision, not the walk's).
27
+ */
28
+ export declare function isSkippedEntry(name: string): boolean;
29
+ /** A directory entry as the walk presents it: a name and what it is. */
30
+ export interface WalkedEntry {
31
+ name: string;
32
+ isDirectory(): boolean;
33
+ isFile(): boolean;
34
+ }
35
+ export interface KbWalkListener {
36
+ /** A folder was listed. `rel` is repo-relative (`''` for the root); `entries` are its children, skipped ones removed, in walk order. */
37
+ onDir?(rel: string, entries: readonly WalkedEntry[]): void | Promise<void>;
38
+ /** A file was seen. `dir` is its folder (`''` for the root), `name` its basename. */
39
+ onFile?(dir: string, name: string): void | Promise<void>;
40
+ /** A folder that exists but could not be listed. */
41
+ onHole?(rel: string, err: unknown): void | Promise<void>;
42
+ }
43
+ export interface KbWalkResult {
44
+ /** Every folder that could not be listed, repo-relative (`''` for the root). */
45
+ holes: string[];
46
+ }
47
+ /**
48
+ * Walk the checkout at `root`, driving every listener from one traversal.
49
+ * A missing root is an empty tree. Listener errors propagate untouched.
50
+ */
51
+ export declare function walkKb(root: string, listeners: readonly KbWalkListener[]): Promise<KbWalkResult>;
52
+ //# sourceMappingURL=kb-walk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kb-walk.d.ts","sourceRoot":"","sources":["../../src/shared/kb-walk.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,IAAI,OAAO,CAAC;IACvB,MAAM,IAAI,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,wIAAwI;IACxI,KAAK,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,qFAAqF;IACrF,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,oDAAoD;IACpD,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,YAAY;IAC3B,gFAAgF;IAChF,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,cAAc,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAiCtG"}
@@ -0,0 +1,76 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs/promises';
3
+ import { isAbsence } from './fs-errors.js';
4
+ import { comparePathComponents } from './path-order.js';
5
+ /**
6
+ * THE walk of a knowledge-base checkout.
7
+ *
8
+ * Every reader of the tree — the access resolver looking for rules, plugin
9
+ * discovery looking for manifests, a rename looking for grants, the catalog
10
+ * scanners — used to carry a recursive `readdir` loop of its own, each with
11
+ * its own skip list, its own idea of what an unreadable folder means and its
12
+ * own visiting order. Two loops that disagree on one of those are two
13
+ * answers to "what is in the tree", and every such disagreement was a bug.
14
+ *
15
+ * So there is one loop, and it decides three things once:
16
+ *
17
+ * - WHAT IS SKIPPED: {@link isSkippedEntry} — dot-entries (`.git`, a parked
18
+ * delete) and vendored dependencies. Nothing else is pruned; a listener
19
+ * that stops at a leaf of its own (a skill folder, a plugin folder)
20
+ * simply ignores what lies beneath it.
21
+ * - IN WHAT ORDER: each folder's entries in {@link comparePathComponents}
22
+ * order, so "first by path" means the same thing to every listener.
23
+ * - WHAT A HOLE IS: a folder that exists but could not be listed is
24
+ * reported as an event and in the result — never thrown, never silently
25
+ * skipped — so a reader can show what it saw and a writer can refuse.
26
+ * A folder that vanished between listing and visiting is not a hole.
27
+ *
28
+ * Listeners see the same events in the same order; what each makes of them
29
+ * is its own business (`.bevelignore` included — the explorer honours it,
30
+ * the resolver must not, so it is a listener's decision, not the walk's).
31
+ */
32
+ export function isSkippedEntry(name) {
33
+ return name.startsWith('.') || name === 'node_modules';
34
+ }
35
+ /**
36
+ * Walk the checkout at `root`, driving every listener from one traversal.
37
+ * A missing root is an empty tree. Listener errors propagate untouched.
38
+ */
39
+ export async function walkKb(root, listeners) {
40
+ const holes = [];
41
+ const visit = async (abs, rel) => {
42
+ let listed;
43
+ try {
44
+ listed = await fs.readdir(abs, { withFileTypes: true });
45
+ }
46
+ catch (err) {
47
+ if (isAbsence(err)) {
48
+ // The root: a checkout without this tree, an empty walk. Deeper: a
49
+ // folder that vanished between listing and visiting — not a hole.
50
+ return;
51
+ }
52
+ holes.push(rel);
53
+ for (const l of listeners)
54
+ await l.onHole?.(rel, err);
55
+ return;
56
+ }
57
+ const entries = listed
58
+ .filter((e) => !isSkippedEntry(e.name) && (e.isDirectory() || e.isFile()))
59
+ .sort((a, b) => comparePathComponents(a.name, b.name));
60
+ for (const l of listeners)
61
+ await l.onDir?.(rel, entries);
62
+ for (const entry of entries) {
63
+ const childRel = rel ? `${rel}/${entry.name}` : entry.name;
64
+ if (entry.isDirectory()) {
65
+ await visit(path.join(abs, entry.name), childRel);
66
+ }
67
+ else {
68
+ for (const l of listeners)
69
+ await l.onFile?.(rel, entry.name);
70
+ }
71
+ }
72
+ };
73
+ await visit(root, '');
74
+ return { holes };
75
+ }
76
+ //# sourceMappingURL=kb-walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kb-walk.js","sourceRoot":"","sources":["../../src/shared/kb-walk.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,cAAc,CAAC;AACzD,CAAC;AAuBD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAY,EAAE,SAAoC;IAC7E,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,MAAM,KAAK,GAAG,KAAK,EAAE,GAAW,EAAE,GAAW,EAAiB,EAAE;QAC9D,IAAI,MAAkC,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnB,mEAAmE;gBACnE,kEAAkE;gBAClE,OAAO;YACT,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,KAAK,MAAM,CAAC,IAAI,SAAS;gBAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAkB,MAAM;aAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;aACzE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,KAAK,MAAM,CAAC,IAAI,SAAS;YAAE,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACzD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;YAC3D,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,KAAK,MAAM,CAAC,IAAI,SAAS;oBAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACtB,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The ONE ordering of repository paths: component by component, each
3
+ * component by `localeCompare`, a shorter path before its extensions. It is
4
+ * exactly the order a directory walk that sorts each level's entries visits
5
+ * them in — so a consumer that must agree with the walk on "first by path"
6
+ * (plugin discovery keeps the first of two folders sharing a slug; principal
7
+ * synthesis must pick the same one) sorts with this and nothing else. A
8
+ * whole-string `localeCompare` does not agree: it weighs the separator
9
+ * against the next character (`a-b/x` before `a/b/x`), the walk never does.
10
+ *
11
+ * TOTAL over distinct paths: two components the collation cannot tell apart
12
+ * (a precomposed `é` and its decomposed spelling) fall through to code-unit
13
+ * order, so no pair of distinct paths ever compares equal — an equal pair
14
+ * would leave "first" to whichever enumeration happened to run, and the two
15
+ * consumers could then pick different folders for one slug.
16
+ */
17
+ export declare function comparePathComponents(a: string, b: string): number;
18
+ //# sourceMappingURL=path-order.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-order.d.ts","sourceRoot":"","sources":["../../src/shared/path-order.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CASlE"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The ONE ordering of repository paths: component by component, each
3
+ * component by `localeCompare`, a shorter path before its extensions. It is
4
+ * exactly the order a directory walk that sorts each level's entries visits
5
+ * them in — so a consumer that must agree with the walk on "first by path"
6
+ * (plugin discovery keeps the first of two folders sharing a slug; principal
7
+ * synthesis must pick the same one) sorts with this and nothing else. A
8
+ * whole-string `localeCompare` does not agree: it weighs the separator
9
+ * against the next character (`a-b/x` before `a/b/x`), the walk never does.
10
+ *
11
+ * TOTAL over distinct paths: two components the collation cannot tell apart
12
+ * (a precomposed `é` and its decomposed spelling) fall through to code-unit
13
+ * order, so no pair of distinct paths ever compares equal — an equal pair
14
+ * would leave "first" to whichever enumeration happened to run, and the two
15
+ * consumers could then pick different folders for one slug.
16
+ */
17
+ export function comparePathComponents(a, b) {
18
+ const as = a.split('/');
19
+ const bs = b.split('/');
20
+ const n = Math.min(as.length, bs.length);
21
+ for (let i = 0; i < n; i++) {
22
+ const order = compareComponent(as[i], bs[i]);
23
+ if (order !== 0)
24
+ return order;
25
+ }
26
+ return as.length - bs.length;
27
+ }
28
+ /** One component against another: collation first, code units to break a tie. */
29
+ function compareComponent(a, b) {
30
+ const order = a.localeCompare(b);
31
+ if (order !== 0)
32
+ return order;
33
+ return a < b ? -1 : a > b ? 1 : 0;
34
+ }
35
+ //# sourceMappingURL=path-order.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-order.js","sourceRoot":"","sources":["../../src/shared/path-order.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB,CAAC,CAAS,EAAE,CAAS;IACxD,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC;QAC/C,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IAChC,CAAC;IACD,OAAO,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC;AAC/B,CAAC;AAED,iFAAiF;AACjF,SAAS,gBAAgB,CAAC,CAAS,EAAE,CAAS;IAC5C,MAAM,KAAK,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC"}
@@ -8,9 +8,24 @@
8
8
  */
9
9
  export declare class TokenCrypto {
10
10
  private readonly key;
11
- /** @param rawKey 32-byte key as hex (64 chars) or base64. */
12
- constructor(rawKey: string);
11
+ /**
12
+ * @param rawKey 32-byte key as hex (64 chars) or base64.
13
+ * @param envVarName the environment variable the caller read `rawKey` from,
14
+ * so a bad key is reported against the variable the operator actually has
15
+ * to fix. Defaults to core's own `SECRETS_ENC_KEY` — every core consumer
16
+ * reads that; an overlay bringing its own key (the SharePoint token
17
+ * cache, connector configs) passes its own name.
18
+ */
19
+ constructor(rawKey: string, envVarName?: string);
13
20
  encrypt(plaintext: string): string;
14
21
  decrypt(blob: string): string;
15
22
  }
23
+ /**
24
+ * Decode a key and refuse anything that is not exactly 32 bytes, blaming
25
+ * `envVarName`. Exported so boot-time config can validate the key THE MOMENT
26
+ * it knows which environment variable supplied it (`SECRETS_ENC_KEY` or a
27
+ * legacy fallback) — every later `new TokenCrypto(key)` with the default name
28
+ * is then safe, because a bad key never gets that far.
29
+ */
30
+ export declare function assertKeyDecodesTo32Bytes(rawKey: string, envVarName: string): Buffer;
16
31
  //# sourceMappingURL=token-crypto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-crypto.d.ts","sourceRoot":"","sources":["../../src/shared/token-crypto.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,6DAA6D;gBACjD,MAAM,EAAE,MAAM;IAW1B,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAQlC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAa9B"}
1
+ {"version":3,"file":"token-crypto.d.ts","sourceRoot":"","sources":["../../src/shared/token-crypto.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B;;;;;;;OAOG;gBACS,MAAM,EAAE,MAAM,EAAE,UAAU,SAAoB;IAI1D,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAQlC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAa9B;AASD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CASpF"}
@@ -9,14 +9,16 @@ import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
9
9
  */
10
10
  export class TokenCrypto {
11
11
  key;
12
- /** @param rawKey 32-byte key as hex (64 chars) or base64. */
13
- constructor(rawKey) {
14
- const key = decodeKey(rawKey);
15
- if (key.length !== 32) {
16
- throw new Error(`SHAREPOINT_TOKEN_ENC_KEY must decode to 32 bytes (got ${key.length}). ` +
17
- 'Generate one with: `node -e "console.log(require(\'crypto\').randomBytes(32).toString(\'base64\'))"`.');
18
- }
19
- this.key = key;
12
+ /**
13
+ * @param rawKey 32-byte key as hex (64 chars) or base64.
14
+ * @param envVarName the environment variable the caller read `rawKey` from,
15
+ * so a bad key is reported against the variable the operator actually has
16
+ * to fix. Defaults to core's own `SECRETS_ENC_KEY` — every core consumer
17
+ * reads that; an overlay bringing its own key (the SharePoint token
18
+ * cache, connector configs) passes its own name.
19
+ */
20
+ constructor(rawKey, envVarName = 'SECRETS_ENC_KEY') {
21
+ this.key = assertKeyDecodesTo32Bytes(rawKey, envVarName);
20
22
  }
21
23
  encrypt(plaintext) {
22
24
  const iv = randomBytes(12);
@@ -46,4 +48,19 @@ function decodeKey(raw) {
46
48
  return Buffer.from(raw, 'hex');
47
49
  return Buffer.from(raw, 'base64');
48
50
  }
51
+ /**
52
+ * Decode a key and refuse anything that is not exactly 32 bytes, blaming
53
+ * `envVarName`. Exported so boot-time config can validate the key THE MOMENT
54
+ * it knows which environment variable supplied it (`SECRETS_ENC_KEY` or a
55
+ * legacy fallback) — every later `new TokenCrypto(key)` with the default name
56
+ * is then safe, because a bad key never gets that far.
57
+ */
58
+ export function assertKeyDecodesTo32Bytes(rawKey, envVarName) {
59
+ const key = decodeKey(rawKey);
60
+ if (key.length !== 32) {
61
+ throw new Error(`${envVarName} must decode to 32 bytes (got ${key.length}). ` +
62
+ 'Generate one with: `node -e "console.log(require(\'crypto\').randomBytes(32).toString(\'base64\'))"`.');
63
+ }
64
+ return key;
65
+ }
49
66
  //# sourceMappingURL=token-crypto.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-crypto.js","sourceRoot":"","sources":["../../src/shared/token-crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE5E;;;;;;;GAOG;AACH,MAAM,OAAO,WAAW;IACL,GAAG,CAAS;IAE7B,6DAA6D;IAC7D,YAAY,MAAc;QACxB,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,yDAAyD,GAAG,CAAC,MAAM,KAAK;gBACtE,uGAAuG,CAC1G,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,OAAO,CAAC,SAAiB;QACvB,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;QAC3B,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC3D,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7E,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAChC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IACvF,CAAC;IAED,OAAO,CAAC,IAAY;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACzF,CAAC;QACD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;QACrC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;QACzF,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3G,CAAC;CACF;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,8EAA8E;IAC9E,sCAAsC;IACtC,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAClE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"token-crypto.js","sourceRoot":"","sources":["../../src/shared/token-crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE5E;;;;;;;GAOG;AACH,MAAM,OAAO,WAAW;IACL,GAAG,CAAS;IAE7B;;;;;;;OAOG;IACH,YAAY,MAAc,EAAE,UAAU,GAAG,iBAAiB;QACxD,IAAI,CAAC,GAAG,GAAG,yBAAyB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,CAAC,SAAiB;QACvB,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;QAC3B,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC3D,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7E,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAChC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IACvF,CAAC;IAED,OAAO,CAAC,IAAY;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACzF,CAAC;QACD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;QACrC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;QACzF,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3G,CAAC;CACF;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,8EAA8E;IAC9E,sCAAsC;IACtC,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAClE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAc,EAAE,UAAkB;IAC1E,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9B,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,GAAG,UAAU,iCAAiC,GAAG,CAAC,MAAM,KAAK;YAC3D,uGAAuG,CAC1G,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -8,9 +8,36 @@ export declare class TtlCache<T> {
8
8
  private readonly ttlMs;
9
9
  private readonly now;
10
10
  private entry;
11
+ /**
12
+ * Bumped by every `invalidate()`. A fetch carries the value this had when it
13
+ * started, and `set` refuses a value whose fetch straddled a drop — see there.
14
+ */
15
+ private generation;
11
16
  constructor(ttlMs: number, now?: () => number);
12
17
  get(): T | null;
13
- set(value: T): void;
18
+ /**
19
+ * Take a token BEFORE starting the fetch whose result you will `set`.
20
+ *
21
+ * Every caller of this cache reads the disk across an `await`, and the whole
22
+ * point of `invalidate()` is that it fires during exactly that window: the
23
+ * merge pulls the new tree in while a catalog read that started on the old
24
+ * one is still in flight. Without a token that late `set` wins, and the cache
25
+ * holds the PRE-invalidation scan for a fresh full TTL — the drop silently
26
+ * undone, and the staleness it existed to prevent restored.
27
+ */
28
+ begin(): number;
29
+ /**
30
+ * Store a value fetched under `token`. Required, not optional: a caller that
31
+ * could forget it is a caller that reintroduces the race above, and there are
32
+ * few enough call sites to make the token cheap.
33
+ *
34
+ * A stale token means an `invalidate()` landed mid-fetch, so this value
35
+ * describes a tree that is already gone: it is DISCARDED rather than stored.
36
+ * The fetcher still returns it to its own caller — that read is merely as old
37
+ * as the moment it started, which is true of any read — but the next caller
38
+ * re-scans instead of inheriting it.
39
+ */
40
+ set(value: T, token: number): void;
14
41
  invalidate(): void;
15
42
  }
16
43
  //# sourceMappingURL=ttl-cache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ttl-cache.d.ts","sourceRoot":"","sources":["../../src/shared/ttl-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,qBAAa,QAAQ,CAAC,CAAC;IAInB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJtB,OAAO,CAAC,KAAK,CAAyC;gBAGnC,KAAK,EAAE,MAAM,EACb,GAAG,GAAE,MAAM,MAAiB;IAG/C,GAAG,IAAI,CAAC,GAAG,IAAI;IAKf,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAInB,UAAU,IAAI,IAAI;CAGnB"}
1
+ {"version":3,"file":"ttl-cache.d.ts","sourceRoot":"","sources":["../../src/shared/ttl-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,qBAAa,QAAQ,CAAC,CAAC;IASnB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IATtB,OAAO,CAAC,KAAK,CAAyC;IACtD;;;OAGG;IACH,OAAO,CAAC,UAAU,CAAK;gBAGJ,KAAK,EAAE,MAAM,EACb,GAAG,GAAE,MAAM,MAAiB;IAG/C,GAAG,IAAI,CAAC,GAAG,IAAI;IAKf;;;;;;;;;OASG;IACH,KAAK,IAAI,MAAM;IAIf;;;;;;;;;;OAUG;IACH,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC,UAAU,IAAI,IAAI;CAInB"}
@@ -8,6 +8,11 @@ export class TtlCache {
8
8
  ttlMs;
9
9
  now;
10
10
  entry = null;
11
+ /**
12
+ * Bumped by every `invalidate()`. A fetch carries the value this had when it
13
+ * started, and `set` refuses a value whose fetch straddled a drop — see there.
14
+ */
15
+ generation = 0;
11
16
  constructor(ttlMs, now = Date.now) {
12
17
  this.ttlMs = ttlMs;
13
18
  this.now = now;
@@ -17,11 +22,38 @@ export class TtlCache {
17
22
  return this.entry.value;
18
23
  return null;
19
24
  }
20
- set(value) {
25
+ /**
26
+ * Take a token BEFORE starting the fetch whose result you will `set`.
27
+ *
28
+ * Every caller of this cache reads the disk across an `await`, and the whole
29
+ * point of `invalidate()` is that it fires during exactly that window: the
30
+ * merge pulls the new tree in while a catalog read that started on the old
31
+ * one is still in flight. Without a token that late `set` wins, and the cache
32
+ * holds the PRE-invalidation scan for a fresh full TTL — the drop silently
33
+ * undone, and the staleness it existed to prevent restored.
34
+ */
35
+ begin() {
36
+ return this.generation;
37
+ }
38
+ /**
39
+ * Store a value fetched under `token`. Required, not optional: a caller that
40
+ * could forget it is a caller that reintroduces the race above, and there are
41
+ * few enough call sites to make the token cheap.
42
+ *
43
+ * A stale token means an `invalidate()` landed mid-fetch, so this value
44
+ * describes a tree that is already gone: it is DISCARDED rather than stored.
45
+ * The fetcher still returns it to its own caller — that read is merely as old
46
+ * as the moment it started, which is true of any read — but the next caller
47
+ * re-scans instead of inheriting it.
48
+ */
49
+ set(value, token) {
50
+ if (token !== this.generation)
51
+ return;
21
52
  this.entry = { at: this.now(), value };
22
53
  }
23
54
  invalidate() {
24
55
  this.entry = null;
56
+ this.generation++;
25
57
  }
26
58
  }
27
59
  //# sourceMappingURL=ttl-cache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ttl-cache.js","sourceRoot":"","sources":["../../src/shared/ttl-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,OAAO,QAAQ;IAIA;IACA;IAJX,KAAK,GAAoC,IAAI,CAAC;IAEtD,YACmB,KAAa,EACb,MAAoB,IAAI,CAAC,GAAG;QAD5B,UAAK,GAAL,KAAK,CAAQ;QACb,QAAG,GAAH,GAAG,CAAyB;IAC5C,CAAC;IAEJ,GAAG;QACD,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QACnF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,GAAG,CAAC,KAAQ;QACV,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC;IACzC,CAAC;IAED,UAAU;QACR,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;CACF"}
1
+ {"version":3,"file":"ttl-cache.js","sourceRoot":"","sources":["../../src/shared/ttl-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,OAAO,QAAQ;IASA;IACA;IATX,KAAK,GAAoC,IAAI,CAAC;IACtD;;;OAGG;IACK,UAAU,GAAG,CAAC,CAAC;IAEvB,YACmB,KAAa,EACb,MAAoB,IAAI,CAAC,GAAG;QAD5B,UAAK,GAAL,KAAK,CAAQ;QACb,QAAG,GAAH,GAAG,CAAyB;IAC5C,CAAC;IAEJ,GAAG;QACD,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QACnF,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;;;;;;;;OAUG;IACH,GAAG,CAAC,KAAQ,EAAE,KAAa;QACzB,IAAI,KAAK,KAAK,IAAI,CAAC,UAAU;YAAE,OAAO;QACtC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC;IACzC,CAAC;IAED,UAAU;QACR,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;CACF"}
@@ -22,4 +22,4 @@ CLAUDE.md
22
22
  **/access.md
23
23
  roles.yaml
24
24
 
25
- Plugins/
25
+ {{pluginsDir}}/